为什么选 jest
Jest是在Facebook开发的测试框架,可以让我的测试更加方便。jest自动集成了断言、JSDom、覆盖率报告等开发者所需要的所有测试工具,是一款几乎零配置的测试框架。
其实我的原因是因为
- 它一套开源的 JavaScript 测试框架
- 我并未用过其他的
- 欢迎各位大佬仗义直言 🙂
安装Nuxt
npm run test先跑起来看看
自己写一个例子
在test目录下新建2个文件
- sum.js
function sum(a, b) {
return a + b;
}
module.exports = sum;
- sum.test.js
const sum = require('./sum');
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
再次
run起来
进入项目,打开文件jest.config.js
- collectCoverage
- 由于要带上覆盖率搜集语句重新访问所有执行过的文件,这可能会让你的测试执行速度被明显减慢
module.exports = {
moduleNameMapper: { //类似 webpack.resolve.alias
'^@/(.*)$': '<rootDir>/$1',
'^~/(.*)$': '<rootDir>/$1',
'^vue$': 'vue/dist/vue.common.js'
},
moduleFileExtensions: ['js', 'vue', 'json'], // 类似 webpack.resolve.extensions
transform: { // 类似 webpack.module.rules
'^.+\\.js$': 'babel-jest',
'.*\\.(vue)$': 'vue-jest'
},
'collectCoverage': false, // 指出是否收集测试时的覆盖率信息
'collectCoverageFrom': [ // 类似 webpack 的 rule.include
'<rootDir>/components/**/*.vue',
'<rootDir>/pages/**/*.vue'
]
}
再次
run起来
collectCoverageFrom的文件没用检测,同样速度也会快些
Vscode 设置
安装 jest
在文件目录配置jest.config路径
可以实时看到
Jest的输出结果了
用Jest编写第一个Vue.js组件单元测试
官方的VueJS测试库vue/test-utils
在components目录下,新增几个文件
MessageList.vue
<template>
<ul>
<li v-for="message in messages">
{{ message }}
</li>
</ul>
</template>
<script>
export default {
name: 'list',
props: ['messages']
}
</script>
修改Pages目录下的index.vue
<template>
<div id="app">
<MessageList :messages="messages" />
</div>
</template>
<script>
import MessageList from "~/components/MessageList";
export default {
name: "app",
data: () => ({ messages: ["Hey John", "Howdy Paco"] }),
components: {
MessageList
}
};
</script>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
开始写我们的测试文件
在test目录编写一个文件index.test.js
import Vue from "vue";
import pageIndex from '@/pages/index.vue'
describe("index.test.js", () => {
let cmp, vm;
beforeEach(() => {
cmp = Vue.extend(pageIndex); // Create a copy of the original component
vm = new cmp({
data: {
// Replace data value with this fake data
messages: ["Cat"]
}
}).$mount(); // Instances and mounts the component
});
it('equals messages to ["Cat"]', () => {
expect(vm.messages).toEqual(["Cat"]);
});
产看输入结果/npm run test,测试应运行并通过 。
Snapshots功能
增加一个it
it("has the expected html structure", () => {
expect(vm.$el).toMatchSnapshot();
});
再次run 生成下面的一个文件
这里有一个大问题:
单元测试必须作为一个独立的单元进行测试,这意味着index.test.js我们要测试APP组件,而不应该影响其他的事情。想象一下,例如,子组件(MessageList在这种情况下)在created挂钩上执行了副作用操作,例如调用fetch,Vuex动作或状态更改?那不就不是我们想要的了嘛?
浅层渲染
浅层渲是一种确保组件在没有子对象的情况下进行渲染的技术
- 仅测试要测试的组件(单元测试)
- 避免子组件可能具有的副作用,例如进行HTTP调用,调用存储操作...
重写index.test.js
import { shallowMount } from "@vue/test-utils";
import pageIndex from '@/pages/index.vue'
describe("index.test.js", () => {
let cmp;
beforeEach(() => {
cmp = shallowMount(pageIndex, {
// Create a shallow instance of the component
data: {
messages: ["Cat"]
}
});
});
it('equals messages to ["Cat"]', () => {
// Within cmp.vm, we can access all Vue instance methods
expect(cmp.vm.messages).toEqual(["Cat"]);
});
it("has the expected html structure", () => {
expect(cmp.element).toMatchSnapshot();
});
});
选择重新生成快照(SnapShots),index被完全隔离,如果子组件中有任何钩子,则它们也不会被调用,比如created。
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`App.test.js has the expected html structure 1`] = `
<div
id="app"
>
<!-- -->
</div>
`;
新增MessageList.test.js
import { mount } from "@vue/test-utils";
import MessageList from "~/components/MessageList";
describe("MessageList.test.js", () => {
let cmp;
beforeEach(() => {
cmp = mount(MessageList, {
// Be aware that props is overridden using `propsData`
propsData: {
messages: ["Cat"]
}
});
});
it('has received ["Cat"] as the message property', () => {
expect(cmp.vm.messages).toEqual(["Cat"]);
});
it("has the expected html structure", () => {
expect(cmp.element).toMatchSnapshot();
});
});
npm run test