vue 引入jest 单元测试

一、前言

为什么要搞单元测试,好处有什么。

  • 提测需要,代码覆盖率达到95%,分支覆盖率达到100%,不达到要求,不给测。
  • 确保代码正确性。单元测试可以检测和发现代码中的错误,在开发期间及时纠正。
  • 提高代码质量。进行单元测试可以思考更多场景,添加边界测试用例,找到更多潜在的问题。通过反复测试和修改,代码的质量和可维护性得到提高。
  • 方便重构。如果代码有充分的测试覆盖率,重构时就可以更加放心。当修改代码时,运行测试用例可确保没有破坏代码的现有功能)。
  • 加速开发流程。单元测试可以自动执行,因此可以快速发现问题并且节省手动测试的时间,从而加速开发流程。

二、思想 vue 官网-测试

在实际开发中想清楚vue组件的业务代码和逻辑代码的处理,把逻辑代码抽离后编写单元测试用例
再针对业务代码编写组件测试用例。

单元测试

编写单元测试是为了验证小的、独立的代码单元是否按预期工作。一个单元测试通常覆盖一个单个函数、类、组合式函数或模块。单元测试侧重于逻辑上的正确性,只关注应用整体功能的一小部分。

组件测试

主要需要关心组件的公开接口而不是内部实现细节。对于大部分的组件来说,公开接口包括触发的事件、prop 和插槽。当进行测试时,测试这个组件做了什么,而不是测试它是怎么做到的。
对于 视图 的测试:根据输入 prop 和插槽断言渲染输出是否正确。
对于 交互 的测试:断言渲染的更新是否正确或触发的事件是否正确地响应了用户输入事件。

三、引入

  1. 新建vue项目直接用脚手架搭建项目时,勾选上单元测试即可。
  2. 旧项目添加单元测试,使用命令:vue add @vue-cli-plugin-unit-jest。命令执行成功后,根目录下面多了tests文件夹和 jest.config.js 文件,tests文件夹下面有一个unit文件夹,里面包含了example.spec.js文件;如下图所示。
    在这里插入图片描述

四、使用

1. jest.config文件

module.exports = {
  // 预设
  preset: '@vue/cli-plugin-unit-jest',  
  // // 多于一个测试文件运行时展示每个测试用例测试通过情况
  verbose: true,
  // // 参数指定只要有一个测试用例没有通过,就停止执行后面的测试用例
  bail: true,
  // // 测试环境,jsdom 可以在 Node 虚拟浏览器环境运行测试
  testEnvironment: 'jsdom',
  // // 需要检测的文件类型(不需要配置)
  moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
  // // 预处理器配置,匹配的文件要经过转译才能被识别,否则会报错(不需要配置)
  // transform: {
  //   // 用 `vue-jest` 处理 `*.vue` 文件
  //   // ".*\\.(vue)$": "<rootDir>/node_modules/vue-jest",
  //   // 用 `babel-jest` 处理 js
  //   "^.+\\.js$": "babel-jest"
  // },
  // // 转译时忽略 node_modules
  // transformIgnorePatterns: ['/node_modules/'],
  // // 从正则表达式到模块名称的映射,和webpack的alisa类似(不需要配置)
  // moduleNameMapper: {
  //   '^@/(.*)$': '<rootDir>/src/$1'
  // },
  // // Jest用于检测测试的文件,可以用正则去匹配
  testMatch: [
    '**/tests/unit/**/*.spec.[jt]s?(x)',
  ],
  // // 是否显示覆盖率报告,开启后显示代码覆盖率详细信息,将测试用例结果输出到终端
  collectCoverage: true,
  // // // 告诉 jest 哪些文件需要经过单元测试测试
  collectCoverageFrom: ["src/assets/js/*.{js,vue}"],
  // // // 覆盖率报告输出的目录
  coverageDirectory: 'tests/unit/coverage',
  // // // 报告的格式
  // coverageReporters: ["html", "text-summary"],
  // // // 需要跳过覆盖率信息收集的文件目录
  coveragePathIgnorePatterns: ['/node_modules/'],
  // // 设置单元测试覆盖率阈值, 如果未达到阈值,Jest 将返回失败
  coverageThreshold: {
    global: {
      statements: 90, // 保证每个语句都执行了
      functions: 90, // 保证每个函数都调用了
      branches: 90, // 保证每个 if 等分支代码都执行了
      lines: 90
    },
  }
}

注意事项:
(1)collectCoverageFrom 告诉Jest 哪些文件需要经过单元测试测试;
(2)testMatch Jest用于检测测试的文件,可以用正则去匹配;
(3)coverageThreshold 设置单元测试覆盖率阈值, 如果未达到阈值,影响报告颜色(虽然你可以自己改)。

2. 测试用例

export default class Demo {
  static TimeoutFn (cb) {
    setTimeout(() => {
      cb && cb("hello Timeout");
    }, 1000)
  }
  static promiseFn () {
    return new Promise(r => {
      setTimeout(() => {
        r("hello Promise");
      }, 1000)
    })
  }
  static TimeoutAsnycFn () {
    return new Promise(r => {
      setTimeout(() => {
        r("hello asnyc");
      }, 1000)
    })
  }
}

demo

import Demo from "@/assets/js/demo.js";
describe("Demo File", () => {
  it("TimeoutFn", done => {
    let cb = t => {
      expect(t).toBe("hello Timeout");
      done();
    }
    Demo.TimeoutFn(cb);
  })
  
  it("promiseFn", () => {
    return Demo.promiseFn().then(res => {
      expect(res).toBe("hello Promise")
    })
  })
  it("TimeoutAsnycFn", async () => {
    let res = await Demo.TimeoutAsnycFn();
    expect(res).toBe("hello asnyc");
  })
})

3. 报告输出

  1. jest.config,js 文件中添加配置项 collectCoverage: true;
  2. package.json 命令行添加 “test:unit”: “vue-cli-service test:unit --coverage”,
  3. jest.config,js 文件删除配置项 coverageReporters;(添加了终端不会显示分支,代码覆盖统计情况)
    在这里插入图片描述
  4. 报告路径 /tests/unit/coverage/lcov-report/index.html;Statements-代码,Branches-分支,Function-函数,Lines-代码行数
    在这里插入图片描述

4. jest语法 jest官网

4.1 匹配器(常用,剩下的可以看官网)

4.1.1 String,Number 类型用 toBe

test("add 1 + 2 to equal 3", () => {
	expect(1 + 2).toBe(3)
})
test("add a + b to equal ab", () => {
	expect("a" + "b").toBe("ab")
})

4.1.2 Array,Object 类型用 toEqual

test('Array', () => {
  expect(["a", "b"]).toEqual(["a", "b"]);
})

test('Object', () => {
  expect({ name: 'xiaoming', age: 18 }).toEqual({ age: 18, name: 'xiaoming' });
})

4.1.3 Boolean,Null, undefined

  • toBeNull:判断是否为null
  • toBeUndefined:判断是否为undefined
  • toBeDefined:判断是否不为undefined
  • toBeNaN:判断是否为NaN
  • toBeTruthy:判断是否为true
  • toBeFalsy:判断是否为false

4.1.4 其他

  • toContain:数组用,检测是否包含
  • toHaveLength:数组用,检测数组长度
4.2 Wrapper

Wrapper:Wrapper 是一个包括了一个挂载组件或 vnode,以及测试该组件或 vnode 的方法
Wrapper.vm:这是该 Vue 实例。你可以通过 wrapper.vm 访问一个实例所有的方法和属性
Wrapper.classes:返回是否拥有该class的dom或者类名数组
Wrapper.find:返回第一个满足条件的dom
Wrapper.findAll:返回所有满足条件的dom
Wrapper.html:返回html字符串
Wrapper.text:返回内容字符串
Wrapper.setData:设置该组件的初始data数据
Wrapper.setProps:设置该组件的初始props数据
Wrapper.trigger:用来触发事件

4.3 钩子函数
  • beforeAll 所有测试用例执行之前执行
  • beforeEach 每个测试用例执行之前执行
  • afterEach 每个测试用例执行完之后执行
  • afterAll 所有测试用例执行完之后执行

使用场景,在测试接口api时,可以在beforeAll 先调登录接口,获取登录信息
执行顺序,如下图所示。
在这里插入图片描述

五、问题

Q: 执行 vue add @vue-cli-plugin-unit-jest 命令报错,如下:
在这里插入图片描述
在这里插入图片描述
A: 把node版切到16以上即可。

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值