单元测试 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 进行测试需要更多的脚手架,但会使您的测试更加真实。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论