单元测试 Vue 应用程序的两种模式

Mastering JS ,我们尽最大努力测试我们所有教程中的每个示例。
这样我们就可以确信我们的内容在主要版本发生时是最新的,或者当我们决定重写教程时。 这意味着我们还需要自动测试我们所有的 Vue 示例。 通常,我们使用两种模式 单元测试 对代码示例

在 Node.js 中使用服务器端渲染

在进行单元测试时,您首先需要定义您认为的 单元。
在编写 Vue 代码时,关于什么是单元存在一些争论:单个 方法 是否算作单元? 怎么样 计算属性
Mastering JS 的我们倾向于在更接近最终用户如何与之交互的测试代码方面犯错,因此我们将 Vue 组件 一个单元。

Vue 支持 服务器端渲染的
与其他一些框架不同,在 Node.js 中实例化 Vue 组件不需要任何外部库或特殊定制。
调用 new Vue() 你得到一个 Vue 实例

const Vue = require(vue);
const { renderToString } = require(vue-server-renderer).createRenderer();

const app = new Vue({
  data: () => ({ count: 0 }),
  methods: {
    increment: function() { ++this.count; }
  },
  template: `
    <div>
      <div>Clicks: {{count}}</div>
      <button v-on:click=increment()>Increment</button>
    </div>
  `
});

let res = await renderToString(app);
assert.ok(res.includes(Clicks: 0));

// `app` is reactive in Node
app.count = 2;
res = await renderToString(app);
assert.ok(res.includes(Clicks: 2));

// You can also call methods in Node
app.$options.methods.increment.call(app);
res = await renderToString(app);
assert.ok(res.includes(Clicks: 3));

使用 Node.js 进行单元测试的好处是最小的设置和开销。您唯一需要的外部库是像 Mocha vue-server-renderer
你还可以在 Node.js 中使用 Vue 做一些惊人的事情:你可以 $emit 事件、更改数据、调用方法、触发生命周期钩子等。

不能 用 Node.js 做的是与实际的 DOM 元素交互,除非你使用另一个外部库。 在上面的示例中,您可以调用 v-on:click 触发,但您实际上不能触发点击事件。

Puppeteer

使用 Puppeteer 测试 Vue 应用程序 是另一种选择。使用 Puppeteer 是您可以使用一个成熟的浏览器。 您可以使用 vanilla JavaScript API 与您的组件进行交互,例如 click()document.querySelector()

我们如何使用 Puppeteer 测试 Vue 背后的关键思想是 Puppeteer 的 setContent() 功能。 如果您可以捆绑组件所需的所有内容,则可以将该 JavaScript 放入一个最小的 HTML 页面中,然后将其放入 Puppeteer 中。

const puppeteer = require(puppeteer);

// Since your Vue app is running in a real browser, you would need
// webpack or browserify to build a bundle if you use `require()`
const createComponent = function() {
  return new Vue({
    data: () => ({ count: 0 }),
    methods: {
      increment: function() { ++this.count; }
    },
    template: `
      <div>
        <div>Clicks: {{count}}</div>
        <button v-on:click=increment()>Increment</button>
      </div>
    `
  });
};

const js = createComponent.toString();
const htmlScaffold = `
  <html>
    <body>
      <script src=https://unpkg.com/vue/dist/vue.js></script>

      <div></div>

      <script type=text/javascript>
        const app = (${js})();
        app.$mount(#content);
      </script>
    </body>
  </html>
`;

// Launch a new browser and make it render the above HTML.
// You can set `headless: false` to interact with the real browser.
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.setContent(htmlScaffold);

// Interact with the component via `evaluate()`
let content = await page.evaluate(() => {
  return document.querySelector(#clicks).innerHTML.trim()
});
assert.equal(content, Clicks: 0);

await page.evaluate(() => document.querySelector(button).click());

content = await page.evaluate(() => {
  return document.querySelector(#clicks).innerHTML.trim()
});
assert.equal(content, Clicks: 1);

// Clean up
await browser.close();

使用 Puppeteer 进行测试非常棒,因为您是在真实的浏览器中进行测试,这意味着此测试与您无需指向和单击自己即可获得的一样真实。 此外,如果您禁用无头模式,您实际上可以观看测试运行。

使用 Puppeteer 进行测试的缺点是您需要自己处理捆绑。 上面的例子不需要捆绑,因为它没有使用 require(),但 如果 您的代码使用 require(), 即使你使用 ES6 导入,正确搭建脚手架也很棘手。

结论

Vue 使使用 Node.js 或 Puppeteer 隔离测试组件变得容易。 使用 Node.js 进行单元测试更容易,因为它需要的设置更少,但您无法测试真正的浏览器交互。 另一方面,使用 Puppeteer 进行测试需要更多的脚手架,但会使您的测试更加真实。

© 版权声明
THE END
喜欢就支持一下吧
点赞961 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容