Vue 开发实战生态篇 # 25:单元测试的重要性及其使用

Posted 凯小默

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue 开发实战生态篇 # 25:单元测试的重要性及其使用相关的知识,希望对你有一定的参考价值。

说明

【Vue 开发实战】学习笔记。

重要性

  • 减少 bug
  • 提高项目的稳定性
  • 提高开发速度

使用方式

实战

创建工程

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 的值和抛出的异常(如果有的话)。 有两种类型的间谍:一些是匿名函数,而另一些则封装了被测系统中已经存在的方法。

https://sinonjs.org/releases/

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

以上是关于Vue 开发实战生态篇 # 25:单元测试的重要性及其使用的主要内容,如果未能解决你的问题,请参考以下文章

Vue 开发实战拓展篇 # 48:结课测试和GitHub相关生态应用持续集成单测覆盖率文档发布issue管理(完结)

Vue 开发实战生态篇 # 19:Vue Router的使用场景

Vue 开发实战生态篇 # 16:如何在Vue中使用Vuex

Vue 开发实战生态篇 # 18:Vuex最佳实践

Vue 开发实战生态篇 # 20:选择何种模式的路由及底层原理

Vue 开发实战生态篇 # 21:Nuxt解决了哪些问题?