Vue 测试入门:使用 Jest 来测试你的 Vue Components
Vue单元测试组件一直使我感到恐惧。我依赖于 Laravel Dusk 这样的验收测试工具来满足我所有JavaScript 测试需求,因为它易于使用且可以在 Laravel 生态系统中使用。尽管非常有用,但 Dusk 测试可能会非常缓慢地运行且难以维护。在编写 Vue 组件时更快地接收反馈可以对我的前端工作流程有很大的改进。
这篇文章逐步介绍了在 Laravel 应用中设置基本的 Vue 测试包。由于 JavaScript 测试领域的新发展,入门比以前容易得多。希望您会发现这个过程简单易懂。
设置测试包后,我们还将探索 Jest 提供的强大测试功能:快照测试。快照测试是获得 Vue 组件全面测试覆盖范围的一个简便方法,而无需完成编写自定义断言的繁琐工作。在这篇文章的最后,我们将探索开始使用这种技术来代替您用来编写测试的更典型方式的样子。
工具
过去,我对大多数的JavaScript测试工具感到有些不知所措,并且对于它们在我的实际测试中是如何编写和运行经常感到困惑。像 karma,mocha,chai,sinon 等词似乎混在一起了。这一次,这些困难都被克服了,因为更成熟的生态系统为我们带来了更好的打包工具,比如 Jest 和 Vue Test Utils.
如果您开始对设置感到不知所措,请记住,尽管我们需要安装许多的Node.js软件包,但这两个实用程序才是我们使用的唯一核心工具。
什么是 Jest?
Jest是 Facebook 创建的一种 JavaScript 测试工具,用于运行测试和进行断言。可以将它想像成 JavaScript 的 PHPUnit;就像 PHPUnit 之于 Laravel,Jest 之于 Vue。除了 Jest,还有其他测试工具,但我更喜欢它,因为它易于使用。
安装 Jest
首先,让我们通过npm
获取设置所需的所有依赖关系。从项目的根目录运行以下命令:
npm install -—save-dev jest vue-jest jest-serializer-vue
我们可以通过在项目的package.json
文件中添加“ jest”
和“ babel”
条目来配置Jest以满足我们的需求。此配置将告诉 Jest 在哪里寻找要测试的组件以及如何解释非标准 JavaScript 文件(例如 ES6 语法)和.vue
组件。
...
"jest": {
"moduleFileExtensions": [
"js",
"vue"
],
"moduleNameMapper": {
"^@/(.*)$": "<rootDir>/resources/assets/js/components/$1"
},
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/babel-jest",
".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
},
"snapshotSerializers": [
"<rootDir>/node_modules/jest-serializer-vue"
]
},
"babel": {
"env": {
"test": {
"presets": [
["env", { "targets": { "node": "current" }}]
]
}
}
},
这就是我们的 Jest 设置!让我们继续设置将要使用的第二个也是最后一个测试实用程序:Vue Test Utils。
什么是 Vue Test Utils?
Vue Test Utils 使我们的测试具有“ Vue意识”,让我们能够轻松地在 Jest 测试中与 Vue 组件进行交互。没有它,我们只能单纯对 JavaScript 代码编写测试,而不能针对Vue编写测试。
安装 Vue Test Utils
Vue Test Utils 更加易于安装和配置。运行以下命令以通过npm
进行安装,我们将准备编写第一个测试:npm install --save-dev @vue/test-utils
编写我们的第一个测试
出于演示的目的,让我们创建一个带有“递增”按钮的简单计数器组件,用于以下条件编写测试:
resources/assets/js/components/Counter.vue
<template>
<div>
<h1>Count: {{ counter }}</h1>
<button @click="counter++" jest="increment-button">+1</button>
</div>
</template>
<script>
export default {
data() {
return {
counter: 0,
}
}
}
</script>
*注意:我在按钮元素 “ jest” 中添加了HTML属性。这并不是什么特殊的语法;这只是我个人用于可以清楚地表明这些 CSS 选择器的测试目的的一种方式。有关此技术的更多信息,请参阅本教程。
现在让我们为 Counter.vue
组件编写测试:
tests/javascript/Counter.spec.js
import { mount } from '@vue/test-utils'
import Counter from '@/Counter.vue'
describe('Counter.vue', () => {
it('increments counter', () => {
const wrapper = mount(Counter);
expect(wrapper.vm.counter).toBe(0);
wrapper.find('[jest="increment-button"]').trigger('click')
expect(wrapper.vm.counter).toBe(1);
})
})
请注意,我们正在使用 Vue Test Utils 提供的名为mount
的实用程序包装Counter
组件。mount()
方法是在内部安装 Vue 组件,并为我们提供了与底层组件进行交互并对其进行断言的接口。有关使用 Vue Test Utils 可能实现更多的详细信息,请转到 docs以获取更多参考。
在安装组件并将其存储在wrapper
对象中后,我们:
- 对组件的状态进行初始声明
- 执行一个动作(在这种情况下,单击增量按钮)
- 断言初始数据属性已更改
假设您熟悉基本的单元测试原理,那么学习曲线将主要需要熟悉 Jest 和 Vue Test Utils 所提供的功能。就像我上面提到的一样,我建议浏览一下文档的更多信息以了解有关这些工具以及如何使用它们。
时间到了!
弹出您的终端,然后从项目根目录运行以下命令:
node_modules/.bin/jest
好极了!如果一切顺利,您应该能看到通过单元测试。
在继续之前,我们先整理一下 Jest 命令。
创建一个npm
脚本来运行测试
将以下npm
脚本添加到您的package.json
文件中以获得更清晰的测试运行体验:
"scripts": {
...
"test": "jest",
"test-watch": "npm run test -- --watch"
},
npm run test
将运行所有的Jest测试。
npm run test-watch
将在您更改被测组件时重新运行测试。
*专业提示: Jest 提供了一些方便的功能,您可以在观看模式下运行测试后按 “ w” 键来访问这些功能。 像重新运行失败的测试这样的特性在PHPUnit中是非常缺乏的,而Jest为我们提供了开箱即用的功能。
简介:快照测试
新的测试配置可以做很多事情。但是,如果您想进一步进行 Vue 测试,让我们探索一下 Jest 提供的另一种强大的测试技术:快照测试。
在先前介绍的范例中,当您对测试中的 Vue 组件进行操作时,您要为一个特定的结果编写一个期望。但是,在快照测试范例中,每次对组件执行操作时,Jest 都会对整个渲染 DOM 输出进行“快照”。简单来说,Jest 基本上将您呈现的组件转换为字符串。这些快照以纯文本格式存储,并在下次运行测试组件时用于与将来的结果进行比较。将它们视为自动断言,使它们成为快速测试大型系统的好方法。
如果对您来说没有意义,没关系。对我来说,通过例子可以更好地理解这个概念。
让我们将原始测试修改为使用快照,而不是针对特定的数据属性进行断言。
tests/javascript/Counter.spec.js
import { mount } from '@vue/test-utils'
import Counter from '@/Counter.vue'
describe('Counter.vue', () => {
it('increments counter', () => {
const wrapper = mount(Counter);
expect(wrapper.html()).toMatchSnapshot()
wrapper.find('[jest="increment-button"]').trigger('click')
expect(wrapper.html()).toMatchSnapshot()
})
})
请注意新的.toMatchSnapshot()
语句。
现在,让我们运行具有快照匹配功能的新测试:
npm run test
第一次运行后,Jest 将在与原始测试所在的目录中生成一个__ snapshots __
目录。让我们来看看新生成的快照。
tests/javascript/__snapshots__/Counter.spec.js.snap
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Counter.vue increments counter 1`] = `
<div>
<h1>Count: 0</h1>
<button jest="increment-button">+1</button>
</div>
`;
exports[`Counter.vue increments counter 2`] = `
<div>
<h1>Count: 1</h1>
<button jest="increment-button">+1</button>
</div>
`;
如您所见,Jest 在每个步骤都渲染 Vue 组件,并将其渲染状态保存为纯文本。下次运行测试时,如果渲染的组件的任何部分发生更改,则测试将失败并指出差异。
如果您想要更改组件的行为,则需要重新生成这些快照。为此,请运行:
npm run test -- -u
快照测试是获得全面的组件覆盖范围而无需测试特定结果的好方法。
请记住,这种方法仅在某些情况下有用。快照测试是非常严格;例如,对组件进行小的、非关键性的更改(如更改类名)将导致测试失败。您还必须注意不要让错误进入快照。如果要更新快照,请确保在提交快照之前对其进行彻底检查。
结束
直到最近,Vue 测试对我来说还是一个有点模糊的概念。我希望这篇文章能给这个主题带来一些清晰度,让您可以轻松地开始并运行一些简单的组件测试。有关要测试什么以及如何测试更深层次的信息,请记住查看文档,以了解 Jest 和 Vue测试Utils 的文档。
最后,不要再找借口不测试您的Vue组件了!
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。