说明
【Vue 开发实战】学习笔记。
重要性
- 减少 bug
- 提高项目的稳定性
- 提高开发速度
使用方式
Jest 内置单元测试 Mocha、断言库 chai、SDOM、 测试报告 istanbul
@vue/test-utils:https://v1.test-utils.vuejs.org/zh/guides/
vue-test
babel-jest
jest-serializer-vue
sinon:https://sinonjs.org/
实战
创建工程
vue create test-demo
jest.config.js 配置
module.exports = { // 指定测试的文件 moduleFileExtensions: ["js", "jsx", "json", "vue"], // 类似webpack的loader transform: { "^.+\\.vue$": "vue-jest", ".+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$": "jest-transform-stub", "^.+\\.jsx?$": "babel-jest" }, // 忽略node_modules文件夹 transformIgnorePatterns: ["/node_modules/"], // 类似webpack的 alias:支持源代码中相同的 `@` -> `src` 别名 moduleNameMapper: { "^@/(.*)$": "<rootDir>/src/$1" }, // 快照的序列化工具 snapshotSerializers: ["jest-serializer-vue"], // 指定哪些文件走单元测试 testMatch: [ "**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)" ], // 给 jsdom 使用 testURL: "http://localhost/", watchPlugins: [ "jest-watch-typeahead/filename", "jest-watch-typeahead/testname" ] };
example.spec.js 例子
import { shallowMount } from "@vue/test-utils"; import HelloWorld from "@/components/HelloWorld.vue"; // 测试 HelloWorld.vue 组件 // describe 定义一个测试集 describe("HelloWorld.vue", () => { // it 单元测试最小集 it("renders props.msg when passed", () => { const msg = "new message"; // Vue Test Utils 允许你通过 shallowMount 方法只挂载一个组件而不渲染其子组件 (即保留它们的存根) const wrapper = shallowMount(HelloWorld, { propsData: { msg } }); // 断言 expect(wrapper.text()).toMatch(msg); }); });
编写一个计数器的测试用例
安装依赖:
npm i sinon -D
什么是测试间谍?
测试间谍是一个函数,它记录所有调用的参数、返回值、this 的值和抛出的异常(如果有的话)。 有两种类型的间谍:一些是匿名函数,而另一些则封装了被测系统中已经存在的方法。
Counter.vue 组件
<template> <div> <span>count: {{ count }}</span> <button @click="handleClick">count++</button> </div> </template> <script> export default { data() { return { count: 0 }; }, methods: { handleClick() { this.count++; this.$emit("change", this.count); } } }; </script> <style></style>
添加单元测试Counter.spec.js
文件
import { mount } from "@vue/test-utils"; import Counter from "@/components/Counter.vue"; import sinon from "sinon"; describe("Counter.vue", () => { // 使用辅助函数库 const change = sinon.spy(); const wrapper = mount(Counter, { listeners: { change } }); it("renders counter html", () => { // 生成快照,可以很方便的比对前后的 html expect(wrapper.html()).toMatchSnapshot(); }); it("count++", () => { // 找到按钮 const button = wrapper.find("button"); // 点击按钮 button.trigger("click"); // 判断值是否为1 expect(wrapper.vm.count).toBe(1); // called:如果至少调用了一次间谍,则为 true expect(change.called).toBe(true); // 再次点击 button.trigger("click"); // callCount:通话录音的数量。 expect(change.callCount).toBe(2); }); });
生成快照如下:
// Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Counter.vue renders counter html 1`] = `<div><span>count: 0</span> <button>count++</button></div>`;
添加监听脚本命令测试:
"test": "vue-cli-service test:unit --watch"
运行测试命令
npm run test