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

发布于 2022-08-29 08:56:44 字数 4839 浏览 89 评论 0

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 进行测试需要更多的脚手架,但会使您的测试更加真实。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

屋檐

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

lorenzathorton8

文章 0 评论 0

Zero

文章 0 评论 0

萧瑟寒风

文章 0 评论 0

mylayout

文章 0 评论 0

tkewei

文章 0 评论 0

17818769742

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文