Quick start jest unit test, mock test, dom test, snapshot test

Written in the front: This article summarizes the course study with reference to the unit test part of the full-stack architecture growth plan course taught  by Uncle Ran . Those who are interested can go to Station B to search for "Full Stack Ran Uncle", and you can learn more cutting-edge things.

1. Unit testing

JavaScript lacks type checking, and errors cannot be located during compilation. Unit testing can help you test for various abnormal conditions. The test can verify the correctness of the code, so that you can have a bottom line before going online. Although the internal information can be printed out through the console, this is a one-time thing. The next test needs to be done from the beginning, and the efficiency cannot be guaranteed. By writing test cases, you can write once and run many times. The product iteration speed of the Internet industry is very fast, and there must be a process of code refactoring after iteration, so how can we ensure the quality of the refactored code? Backed by test cases, you can boldly refactor.

In simple terms, what a unit test does is the following

  1. Import the function to be tested
  2. give the function an input
  3. define expected output
  4. Check that the function returns the expected output

That is: input - expected output - verification result.

Table of contents

1. Unit testing

1.1 A Jest Demo

1.2 jest assertion function

jest grouping function

jest's hook function

Scope of jest hook function

2. Asynchronous testing

A demo of asynchronous testing

Create a new src/delay.js file

Create a new src/__test__/delay.spec.js test file

test

Improve the efficiency of asynchronous testing

Change delay.spec.js

3. Mock test

A demo of mock test

Add src/fetch.js

Add src/__test__/fetch.spec.js

test

 jest's fn method

 Four, Dom test

dom.js file

dom.spec.js test file

install jsdom

Add jsdom-config.js configuration file

 Modify the dom.spec.js file

5. Snapshot test

Add snapshot.spec.js test file

test


1.1 A Jest Demo

jest is a js testing framework open sourced by facebook. Chinese Documentation: Quick Start · Jest

Brush up on official documents more often, official documents are the best tutorials.

Jest is suitable for but not limited to projects using the following technologies: Babel, TypeScript, Node, React, Angular, Vue, etc. Jest stipulates that there is a set of test directories in each code, and this test directory corresponds to the corresponding test functions. A file (test.spec.js) under the test folder and the file test.js with the same name under the src folder are corresponding mapping relationships. Separate the actual code and test files for easy management and maintenance.

1. Create a new vue project

Initialize the project and generate a package.json file.

Command: npm init -y

2. Install Jest

Global installation is recommended, jest works by default under the npm package in the current workspace

Command: npm i jest -g

vscode installs jest type hints, which can prompt jest syntax

npm i -D @types/jest

3. New addition procedure

src/add.js

Create a new src folder and add add.js file

const add = (a,b) => a+b;

module.exports = add;

4. New test class

Add a new __test__ folder under the src file at the same level, and create a file with the same name add.spec.js

//引入add方法
const add = require('../add')
//describe测试单元,用于分组
describe('',()=>{
    //比如,第一个测试用例,测试1+2是否为3
    //test第一个参数打印一段文本,第二个参数执行回调函数
    test('add(1,2) === 3',()=>{
        //断言 期待执行add(1,2)后返回结果是3,tobe表示期待的结果值
        expect(add(1,2)).toBe(3)
    })

    test('add(2,2)===4',()=>{
        expect(add(2,2).toBe(4))
    })
})
//第一个测试用例

The above test code is as comfortable as speaking in natural language. expect is called an assertion function: it asserts that a real result is the expected result. Many testing frameworks have this method.

5. Execute jest

Execute jest directly in the current directory, and all test cases can be executed once.

Command: test

1.2 jest assertion function

The test is whether the running result is consistent with our expected result. The assertion function is used to verify whether the result is correct.

Commonly used assertion methods

.toBe judgment on value

.toEqual is similar to === equal judgment

expect(运行结果).toBe(期望的结果);
//常见断言方法
expect({a:1}).toBe({a:1})//判断两个对象是否相等
expect(1).not.toBe(2)//判断不等
expect({ a: 1, foo: { b: 2 } }).toEqual({ a: 1, foo: { b: 2 } })
expect(n).toBeNull(); //判断是否为null
expect(n).toBeUndefined(); //判断是否为undefined
expect(n).toBeDefined(); //判断结果与toBeUndefined相反
expect(n).toBeTruthy(); //判断结果为true
expect(n).toBeFalsy(); //判断结果为false
expect(value).toBeGreaterThan(3); //大于3
expect(value).toBeGreaterThanOrEqual(3.5); //大于等于3.5
expect(value).toBeLessThan(5); //小于5
expect(value).toBeLessThanOrEqual(4.5); //小于等于4.5
expect(value).toBeCloseTo(0.3); // 浮点数判断相等
expect('Christoph').toMatch(/stop/); //正则表达式判断
expect(['one','two']).toContain('one'); //不解释

jest grouping function

describe("关于每个功能或某个组件的单元测试",()=>{

  // 不同用例的单元测试

})

jest's hook function

beforeAll:在所有测试用例运行之前,会先调用 beforeAll 钩子函数
beforeEach:每个测试用例执行之前,都会调用,类似 vue-router 的 beforeEach,这样每次测试都是一个全新的实例,各个用例之间互不干扰。
afterEach:与 beforeEach 相反
afterAll:与 beforeAll 相反

Scope of jest hook function

describe: Put the code related to increase into one type of group, and put the subtraction into another type of group. You can use describe grouping. Jest will set a describe in the outermost layer by default. Do not write initialization code in describe to avoid If you step on the pit, you must write it in the hook function

2. Asynchronous testing

If there are asynchronous operations in the test function, and the asynchronous operation needs to be executed before the assertion result is performed, the unit test function needs to set the done parameter and call it in the timing callback function.

A demo of asynchronous testing

Create a new src/delay.js file

The function delay means delay, use delayed execution to test asynchronous

module.exports = fn => {
    //设置1秒钟之后执行该延迟函数
    setTimeout(()=>fn(),1000);
};

Create a new src/__test__/delay.spec.js test file

The done function in the it method indicates the end of the program execution, which is used as a mark for testing

//引入 delay函数
const delay = require('../delay')
//异步测试
//done函数表示程序执行完成
it('异步测试',done => {
    delay(() =>{
        //等待定时器一定时间后调用delay函数执行
        done()
    })
    expect(true).toBe(true)
})

test

Command: jest delay

Improve the efficiency of asynchronous testing

Since the asynchronous test will wait according to the waiting time in the program, the jest.useFakeTimers() method can be used to improve efficiency. Simply put, it is to simulate a time function and let the time function perform a fast-forward process.

Change delay.spec.js

//引入 delay函数
const delay = require('../delay')
//异步测试
//done函数表示程序执行完成
it('异步测试',done => {
    //.useFakeTimers()使用虚拟时钟,在执行过程中进行拨快
    jest.useFakeTimers()
    delay(() =>{
        //等待定时器一定时间后调用delay函数执行
        done()
    })
    //.runAllTimers()在调用完成后,拨快时钟
    jest.runAllTimers()
    expect(true).toBe(true)
})

Command: jest delay

It can be seen that the test time has been significantly prompted

3. Mock test

When calling other library information in vue project development, it is not a unit test.

The mock function is equivalent to creating a virtual function

A demo of mock test

install axios

Command: npm i axios -s

Add src/fetch.js

const axios = require('axios')
//定义一个getData方法,通过axios.get方法获取某个接口数据
exports.getData = () => axios.get('/abc/bcd');

Add src/__test__/fetch.spec.js

const {getData} = require('../fetch')
const axios = require('axios')
//mock方法
jest.mock('axios')
it('测试fetch',async()=>{

    //根据行为模拟mock对象
    //假设已知fetch.js中的axios.get方法返回一个promise对象值为'123'
    axios.get.mockResolvedValueOnce('123')
    axios.get.mockResolvedValueOnce('456')
    const data1 = await getData()
    const data2 = await getData()
    //断言结果'123'
    expect(data1).toBe('123')
    expect(data2).toBe('456')
})

test

there is a fetch

If the returned value is not as expected

jest will prompt, what is the expected value of expect, and what is the value received by receive

 jest's fn method

jest.fn() is the easiest way to create a Mock function. If the internal implementation of the function is not defined, jest.fn() will return undefined as the return value

Add a new test case in the above asynchronous test method to detect whether mockFn is called

//引入 delay函数
const delay = require('../delay')
//异步测试
//done函数表示程序执行完成
it('异步测试',done => {
    //.useFakeTimers()使用虚拟时钟,在执行过程中进行拨快
    jest.useFakeTimers()
    delay(() =>{
        //等待定时器一定时间后调用delay函数执行
        done()
    })
    //.runAllTimers()在调用完成后,拨快时钟
    jest.runAllTimers()
    expect(true).toBe(true)
})

it('异步测试 fn',done => {
    //定义一个mockFn函数,该函数本身可以被断言
    let mockFn = jest.fn()
    jest.useFakeTimers()
    delay(() =>{
        mockFn()
        done()
    })
    jest.runAllTimers()
    expect(true).toBe(true)
    //断言mockFn是否被断言
    expect(mockFn).toBeCalled()
})

Success after executing jest delay

 If the mockFn() call is commented out, the execution will report an error

 Four, Dom test

The so-called Dom test is to verify whether the operation of the front-end program on the Dom is correct. For the convenience of testing, if you don't want to do it in the browser environment, you can do it in the Node environment, but there is no Dom model in Node. The solution is to use jsdom for Dom simulation.

dom.js file

//创建一个div的元素
exports.generateDiv = () => {
    const div = document.createElement('div')
    //修改div的属性
    div.className = 'c1'
    //添加到文档对象模型中
    document.body.appendChild(div)
}

dom.spec.js test file

const {generateDiv} = require('../dom')
it('Dom测试',()=>{
    generateDiv()
})

Command: jest dom

jest dom test results

Running the dom test case directly will report an error

install jsdom

Use the jsdom tool to test the Dom element according to the error message

Command: npm i jsdom -s

Add jsdom-config.js configuration file

//引入jsdom
const jsdom = require('jsdom') // eslint-disable-line
const { JSDOM } = jsdom
//jsdom实现对真实dom方针
const dom = new JSDOM('<!DOCTYPE html><head/><body></body>', {
  url: 'http://localhost/',
  referrer: 'https://example.com/',
  contentType: 'text/html',
  userAgent: 'Mellblomenator/9000',
  includeNodeLocations: true,
  storageQuota: 10000000,
})
//浏览器包括window对象和document对象
//将dom绑定到全局 dom对象的window属性绑定到全局的window属性
global.window = dom.window
global.document = window.document
global.navigator = window.navigator

 Modify the dom.spec.js file

Introduce the jsdom-config.js file and re-execute the test

Command: jest dom

It can be found that the test passes normally

5. Snapshot test

The snapshot test uses jest's toMatchSnapshot matcher, and a __snapshots__ folder will be generated in the root directory after running.

After modifying the content, compare it with the snapshot generated last time, execute jest --updateSnapshot or jest -u to update the snapshot

Executing toMatchInlineSnapshot will generate a snapshot into the line

Snapshot testing actually serializes object instances and converts them into files for persistent storage. Wait until the next test to compare with it. Snapshot testing is widely used in UI testing. For example, in the front-end test, you can make a snapshot of the Dom object. Snapshot testing is a very useful tool whenever you want to make sure that your UI doesn't change unexpectedly. The typical approach is to save a snapshot file after rendering the UI components, and check whether it matches the snapshot file saved next to the unit test. The test will fail if the two snapshots do not match: either an unexpected change has been made, or the UI component has been updated to a newer version.

Next we test the Dom element using the snapshot test

Add snapshot.spec.js test file

//引入dom
const {generateDiv} = require('../dom')
//引入jsdom-config
require('../jsdom-config')
//快照测试
test('Dom的快照测试',()=>{
    generateDiv()
    //toMatchSnapshot 和上次的快照进行比对
    expect(document.getElementsByClassName('c1')).toMatchSnapshot()
})

test

Command: test snapshot

After execution, you can see that a new snapshots file has been added to the __test__ directory. Here is the snapshot file stored

Snapshot files are not updated when testing again

Command: test snapshot

Assuming that the div class name in the dom.js file is modified, and the test is executed again, the snapshot test result has changed.

 Quick start, have you started yet?

Guess you like

Origin blog.csdn.net/qq_36384657/article/details/127002200