vue+jest 单元测试配置+用例

目录

目录 1

Jest 说明文档 2

1、 搭建node环境包 2

这里安装环境是node 18,npm 9.5.0。 2

Test Runner 2

2、 安装jest 3

Jest安装步骤 4

项目的根目录下创建一个.babelrc 配置文件: 4

在项目的根目录下创建 jest.config.js 4

3、 全局设定 5

预处理和后处理 5

方法 6

4、 断言 6

真假断言 6

数字断言 7

字符串断言toMatch 8

数组& 迭代器断言toContain 8

异常断言toThrow 8

快照测试 9

5、 Jest 使用指南 - - Mock 篇 9

Jest Mock 9

jest.fn() 9

jest.spyOn() 9

总结 10

6、 Vue/test-utils API使用说明 10

Jest 说明文档

  1. 搭建node环境包

这里安装环境是node 18,npm 9.5.0。

Node.js 刚刚发布了 18.0.0 版本,内置了 fetch 和 node:test 等标准模块。

Test Runner

单元测试,内置对应的能力,Node.js 在 18.x 里官方支持了 Test 能力

import test from 'node:test';
import assert from 'assert/strict';
 
// 等价于 describe()
test('asynchronous passing test', async () => {
  const res = await fetch('https://nodejs.org/api/documentation.json');
  assert(res.ok);//断言
});
 
test('multi level test', async (t) => {
  // 等价于 it()
  await t.test('subtest 1', (t) => {
    assert.strictEqual(1, 1);
  });
 
  await t.test('subtest 2', (t) => {
    assert.strictEqual(2, 2);
  });
});
 
// 等价于 describe.skip() / it.skip()
test('skip option', { skip: true }, () => {});
 
// 等价于 describe.only() / it.only()
test('only option', { only: true }, () => {});

可以看到:

语法其实差不多,会更简洁一点,就一个 test(),options 除了 skip 和 only 外,还支持 concurrency 并发。

无需启动器,每一个文件都是一个独立可执行的Node.js 代码。

暂未支持 before/after/beforeEach/afterEach 能力,看 issue 描述会后续支持。

暂未支持Reporter,但日志输出为标准 TAP 格式,所以应该很容易能复用现有的社区生态。

类似覆盖率的演进过程,以前我们需要通过nyc 对代码转译打桩,现在变为 Node.js 内置覆盖率输出,nyc 简化为 c8 这样的覆盖率报告生成工具。

后续Mocha 等估计会变为类似的上层封装,提供批量执行 和 Reporter 等能力。

  1. 安装jest

Jest安装步骤

使用node18+版本,vue-cli默认选择安装jest。

npm install --save-dev jest

npm install --save-dev babel-jest @babel/core @babel/preset-env

·@babel/core:babel核心库

· @babel/preset-env:进行 ES 语法转换的库

· babel-jest:和 Jest 通信的库,用来检测是否安装了上面两个依赖

项目的根目录下创建一个.babelrc 配置文件:

{"presets": [["@babel/preset-env", { "targets": { "node": "current" } }]]}

在项目的根目录下创建 jest.config.js

配置项添加了解释说明,可根据实际项目增加删减

Node 18+ npm9.5.0 自配配置

const path = require('path')
 
module.exports = {
    rootDir: path.resolve(__dirname, '../../'),
    //告诉jest 哪些文件拓展名需要测试
    moduleFileExtensions: [
        'js',
        'json',
        'vue'
    ],
    // 是否显示覆盖率报告
    collectCoverage: false,
    // 这将用于配置覆盖结果的最低阈值强制
    coverageThreshold: {
        global: {
            statements: 90, // 保证每个语句都执行了
            functions: 90, // 保证每个函数都调用了
            branches: 90, // 保证每个 if 等分支代码都执行了
        },
    },
    //从正则表达式到允许根资源的模块名称或模块名称数组的映射
    moduleNameMapper: {
        '^@/(.*)$': '<rootDir>/src/$1'
    },
    //通过一个默认地址给浏览器环境
    testURL: 'http://localhost/',
    //转换/翻译测试问题
    transform: {
        '^.+\\.js$': '<rootDir>/node_modules/babel-jest',
        '.*\\.(vue)$': '<rootDir>/node_modules/vue-jest'
    },
    //快照
    snapshotSerializers: ['<rootDir>/node_modules/jest-serializer-vue'],
    //运行一些代码以配置或设置测试框架的模块的路径列表
    setupFiles: ['<rootDir>/test/unit/setup'],
    //Jest应该输出其覆盖范围文件的目录。
    coverageDirectory: '<rootDir>/test/unit/coverage',
    //匹配需要从中收集覆盖信息的文件
    collectCoverageFrom: [
        'src/**/*.{js,vue}',
        '!src/main.js',
        '!src/router/index.js',
        '!**/node_modules/**'
    ]
}

更详细的jest配置说明地址:

https://zhuanlan.zhihu.com/p/535048414

这里注意transform配置项,需要先安装babel-jest,不然报错。

  1. 全局设定

预处理和后处理

beforeAll(() => { // 在所有测试用例前执行一次});

afterAll(() => { // 在所有测试用例后执行一次});

beforeEach(() => { // 在每个测试用例前执行一次});

afterEach(() => { // 在每个测试用例后执行一次});

方法

describe 将您的测试套件分解为多个组件,可以嵌套使用 describe 块。

it 是您执行单个测试。

test是执行测试,类似it ,是测试的最小单位。

expect:提供很多的matcher 来判定你的方法返回值是否符合特定条件。

describe.only:如果你只想运行一次模块测试的话,可以使用 describe.only。

describe.skip 可以使用skip 跳过某一个测试。

test.only如果你只想运行一次测试的话。

test.skip 来指定一些要跳过的测试。

test.failing:失败的测试将抛出任何错误,如果不抛出,则它将失败。

test.todo :用 test.todo 来表示你计划要写这些测试。

  1. 断言

每次要测试值时都会使用expect函数,使用expect和“matcher”函数来断言某个值。

假设您有一个方法bestLaCroixFlavor(),它应该返回字符串“葡萄柚”。以下是测试方法:

test('the best flavor is grapefruit', () => {

expect(bestLaCroixFlavor()).toBe('grapefruit');

});

这段代码翻译:期望bestLaCroixFlavor()这个函数返回正确的'grapefruit'

toBe是是否精确匹配器函数。期望的参数应该是代码生成的值,匹配器的任何参数都应该是正确的值。

真假断言

在测试中常用API,有时需要区分undefined、null和false,not取反;

toBeNull仅匹配null

toBeUndefined仅匹配未定义

toBeDefined与toBeUndefined相反

toBeTruthy匹配if语句视为真的任何内容

toBeFalsy匹配if语句视为false的任何内容

例子如下:

test('zero', () => {

const z = 0;

expect(z).not.toBeNull();

expect(z).toBeDefined();

expect(z).not.toBeUndefined();

expect(z).not.toBeTruthy();

expect(z).toBeFalsy();

});

数字断言

expect(value)

.toBeCloseTo(number, numDigits) 比较浮点数以获得近似相等。

.toBeGreaterThan(number) 比较数字或大整数值。

.toBeGreaterThanOrEqual(number) 比较数字或大整数值所需的接收值>=。

.toBeLessThan(number) 比较数字或大整数值的接收<预期值。

.toBeLessThanOrEqual(number) 比较数字或大整数值所需的接收<=。

例子如下:

test('two plus two', () => {

const value = 2 + 2;

expect(value).toBeGreaterThan(3);

expect(value).toBeGreaterThanOrEqual(3.5);

expect(value).toBeLessThan(5);

expect(value).toBeLessThanOrEqual(4.5);

// toBe and toEqual are 等同于数字

expect(value).toBe(4);

expect(value).toEqual(4);

});

字符串断言toMatch

.toMatch检查字符串是否与正则表达式匹配

例子如下:

describe('grapefruits are healthy', () => {

test('grapefruits are a fruit', () => {

expect('grapefruits').toMatch('fruit');

});

});

数组& 迭代器断言toContain

如果要检查数组中是否有项,请使用.toContain。对于测试数组中的项,这使用==,一个严格的相等检查。toContain还可以检查一个字符串是否是另一个字符串的子字符串。

例子如下:

const shoppingList = [

'diapers', 'kleenex', 'trash bags', 'paper towels', 'beer',

];

test('the shoppingList list contains beer', () => {

expect(getAllFlavors()).toContain('beer');

});

异常断言toThrow

toThrow测试函数在调用时抛出异常。

例子如下:

test('throws on octopus', () => {

expect(() => {

drinkFlavor('octopus');

}).toThrow();

});

不规则匹配器

expect.anything匹配除null或undefined以外的任何内容

快照测试

toMatchSnapshot() 会为expect 的结果做一个快照并与前面的快照做匹配。(如果前面没有快照那就保存当前生成的快照即可)

执行单元测试后,测试通过,然后Jest会在test/__snapshots__/文件夹下创建一个快照文件****.spec.js.snap

  1. Jest 使用指南 - - Mock 篇

Jest Mock

Mock函数提供的以下三种特性,在我们写测试代码时十分有用:

擦除函数的实际实现(换句话说:改变函数的内部实现)。

捕获函数调用情况( 包括:这些调用中传递的参数、new 的实例)。

设置函数返回值。

jest.fn()

Jest.fn()是创建Mock函数最简单的方式,如果没有定义函数内部的实现,jest.fn()会返回undefined作为返回值。

Jest.fn()所创建的Mock函数还可以设置返回值,定义内部实现或返回Promise对象。

jest.spyOn()

Jest.spyOn()方法同样创建一个mock函数,但是该mock函数不仅能够捕获函数的调用情况,还可以正常的执行被spy的函数。实际上,jest.spyOn()是jest.fn()的语法糖,它创建了一个和被spy的函数具有相同内部代码的mock函数。 如果没有提供实现,调用模拟函数将返回 undefined。

总结

在实际项目的单元测试中,jest.fn()常被用来进行某些有回调函数的测试;jest.mock()可以mock整个模块中的方法,当某个模块已经被单元测试100%覆盖时,使用jest.mock()去mock该模块,节约测试时间和测试的冗余度是十分必要;当需要测试某些必须被完整执行的方法时,常常需要使用jest.spyOn()。

  1. Vue/test-utils API使用说明

mount: 创建一个包含被挂载和渲染的 Vue 组件的 wrapper,它仅仅挂载当前实例。

shallowMount:和 mount 一样,创建一个包含被挂载和渲染的 Vue 组件的 Wrapper,只挂载一个组件而不渲染其子组件 (即保留它们的存根),这个方法可以保证你关心的组件在渲染时没有同时将其子组件渲染,避免了子组件可能带来的副作用(比如Http请求等)

shallowMount和mount的区别:在文档中描述为"不同的是被存根的子组件",大白话就是shallowMount不会加载子组件,不会被子组件的行为属性影响该组件。

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:用来触发事件。

执行单元测试后,测试通过,然后Jest会在test/__snapshots__/文件夹下创建一个快照文件*****.spec.js.snap

注意:

  1. shallow 1.0.0版本已删除,请改用shallowMount 安装

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值