Why write unit tests
- Reduce bugs and avoid low-level errors
- Improve project code quality
- Quick Problem Location
- Reduce debugging time and deliver development efficiency
- Easy to reconstruct
What is a Jest
Jest Chinese: Jest is a delightful JavaScript testing framework that focuses on simplicity. These projects use Jest: Babel, TypeScript, Node, React, Angular, Vue, etc.
Jest advantages
Jest
Simple installation and configuration, very easy to use, almost zero configuration, through the NPM command installation can run directlyJest
Assertion libraries are automatically integrated, eliminating the need to introduce third-party assertion librariesJest
Built-in code coverage reporting allows you to collect code coverage information across the project, including untested files.Jest
The test cases are executed in parallel. It automatically identifies some test files and only executes the tests corresponding to the changed files, improving the test speedJest
providesnapshot
Function, by comparing the UI code generated snapshot file, to achievevue
Automatic testing of the frameworkjest
Can generate sonarQube required test coverage reports, data can be uploaded to sonarvue
Officially recommended unit testing framework, yesvue
Frame friendly, andvue
Scaffolding optional custom integrated unit test framework.
Jest installation and configuration
Installing a plug-in
First we need to install some plugins that jest requires:
jest
: Jest@vue/test-utils
Vue Test Utils is the official Vue. Js unit Test utility librarybabel-jest
: Automatically compile JavaScript code using Babelvue-jest
: Use vue-jest to compile. Vue filesjest-serializer-vue
: the module that generates the serializer for vue snapshots, which will be required for Snapshot Testsjest-transform-stub
: deal with CSS preprocessor | | picture fontjest-sonar-reporter
(Optional) : Custom result handler for Jest. The processor converts Jest’s output into a common test data format with Sonar.
Configuration jest. Config. Js
module.exports = {
verbose: true.bail: 1.moduleFileExtensions: [
'vue'.'js'.'json'].moduleNameMapper: {
'^ @ / (. *) $': '<rootDir>/src/$1',},transform: {
'.+\\.(css|less|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub'.'^.+\\.js$': 'babel-jest'.'.*\\.vue$': 'vue-jest'.'^.+\\.svg$': 'jest-svg-sprite-loader'
},
snapshotSerializers: [ 'jest-serializer-vue'].testResultsProcessor: 'jest-sonar-reporter'.collectCoverage: true.collectCoverageFrom: [
'src/**/*.{js,vue}',].coverageReporters: ['html'.'lcov'.'text-summary'].coverageDirectory: './test/coverage'.coveragePathIgnorePatterns: [ '/node_modules/'].coverageThreshold: {
global: {
branches: 20.functions: 20.lines: 20.statements: 20}},testMatch: [
'**/*.spec.js']};Copy the code
verbose
: More than one test file runtime shows the test passes of each test casebail
The: parameter specifies to stop the execution of subsequent test cases if one of them failsmoduleFileExtensions
:jest
Type of file to be testedmoduleNameMapper
: Mapping from regular expressions to module names, similar to Alisa for Webpacktransform
: Preprocessor configurationsnapshotSerializers
:Jest
A list of paths to the snapshot serializer modules used in the snapshot testtestResultsProcessor
: Custom result handler, usedjest-sonar-reporter
The outputsonar
Common test data formats requiredcollectCoverage
: Indicates whether to perform coverage collectioncollectCoverageFrom
: Files that need to be collected for coverage are executed in sequencecoverageReporters
:Jest
In the configuration of writing coverage reports, add”text
“Or”text-summary
“View the coverage summary in the console outputcoverageDirectory
:Jest
The directory that outputs the overwrite information filecoveragePathIgnorePatterns
: Indicates the directory where the coverage information needs to be skippedcoverageThreshold
: Sets the minimum threshold for overwriting results. If the threshold is not reached,jest
Will return failuretestMatch
:Jest
Files used to test tests can be matched with re
Jest hook function
Describe/test describe,test represents an execution block (scope) through which tests can be grouped, or if there is no describe, the entire file is a Describe.
Jest executes all describe processor parts before executing the specific Test block.
describe("unit test".() = >{
it('10 is 10'.() = >{
expect(10).toBe(10)
})
test('A is A'.() = >{
expect('A').toBe('A'); })})Copy the code
jest
Can supportbeforeAll
.afterAll
.beforeEach
andafterEach
To write the initialization code.- By default,
before
和after
Block can be applied to each test in the file. Also available throughdescribe
Block to group tests. - when
before
和after
Block in thedescribe
When inside a block, it only applies to thatdescribe
Tests within blocks. - When executing the order, it is executed first
describe
, and then execute each hook sub function.
beforeAll(() = > console.log('- beforeAll outside')) / / 1
afterAll(() = > console.log('outside - afterAll)) / / 12
beforeEach(() = > console.log('- beforeEach outside')) / / 2, 6
afterEach(() = > console.log('- afterEach outside')) / / 4 to 10
test(' '.() = > console.log('- the test outside')) / / 3
describe('describe inside'.() = > {
beforeAll(() = > console.log('- beforeAll')) / / 5
afterAll(() = > console.log('- afterAll)) / / 11
beforeEach(() = > console.log('- beforeEach')) / / 7
afterEach(() = > console.log('- afterEach')) / / 9
test(' '.() = > console.log('- the test')) / / 8
})
Copy the code
Jest snapshot test
Jest can test the overall HTML for changes through the Snapshot test, which is currently jEST’s proprietary test method. By comparing before and after snapshots, you can quickly find changes in the UI.
wrapper.html()
Get the entireDOM
toMatchSnapshot()
A snapshot file is generated when the snapshot test is run for the first time, and a snapshot is generated each time after the test is run. Then, a snapshot file is generated. If the snapshot file is not changed, the test passes. Otherwise, the test fails, and the results are output to compare the mismatches.- When code changes, press U through the console to update the snapshot
- At many points
test case
When changing, press I to update the snapshot interactively
import { shallowMount } from '@vue/test-utils'
import Demo from '@/com/Demo.vue';
it('Template DOM structure snapshot test'.() = > {
const wrapper = shallowMount(Demo)
expect(wrapper.html()).toMatchSnapshot()
wrapper.destroy()
})
Copy the code
Jest Mock
The three Mock apis in Jest are jest.fn(), jest.spyon (), and jest.mock().
jest.fn()
jest.fn()
Is to createMock
The simplest way to do a function, if you don’t define the internal implementation of the function,jest.fn()
Returns theundefined
As a return valuejest.fn()
Created by theMock
Functions can also set return values, define internal implementations, or returnsPromise
object
import { ajaxMock } from '.. /.. /__mock__/ajax.mock';
describe('ajax_test'.() = > {
it('whether ajax_ is called'.async() = > {const mockFun1 = jest.fn();
mockFun1.mockReturnValueOnce(456).mockReturnValueOnce(789);
const mockFun2 = jest.fn(() = > { return 456; });
await ajaxMock(mockFun1);
await ajaxMock(mockFun1);
await ajaxMock(mockFun2);
expect(mockFun1).toBeCalled(); / / is carried out
expect(mockFun1.mock.calls.length).toBe(2); // Number of calls
expect(mockFun2.mock.results[0].value).toBe(456); // Return the result
});
});
Copy the code
jest.mock()
Mock () can be used to mock the entire module. Jest. Mock () can be used to mock the entire module
import call from '.. /src/call';
import ajax from '.. /src/ajax';
jest.mock('.. /src/ajax.js');
test('Mock the entire Ajax.js module'.async() = > {await call.getData();
expect(ajax.ajaxGetData).toHaveBeenCalled();
expect(ajax.ajaxGetData).toHaveBeenCalledTimes(1);
})
Copy the code
jest.spyOn()
The jest.spyon () method also creates a mock function, but the mock function not only captures the function invocation, but also executes the spy function normally. In fact, jest.spyon () is the syntactic sugar of jest.fn(), which creates a mock function with the same internal code as the spy function.
import call from '.. /src/call';
import ajax from '.. /src/ajax';
test('Use jest.spyon () to monitor ajax.ajaxGetData to be called properly'.async() => {
expect.assertions(2);
const spyFn = jest.spyOn(ajax, 'ajaxGetData');
await call.getData();
expect(spyFn).toHaveBeenCalled();
expect(spyFn).toHaveBeenCalledTimes(1);
})
Copy the code
Jest report uploaded to Sonar
jest.config.js
Add the configuration
testResultsProcessor: 'jest-sonar-reporter'
Copy the code
sonar-project.properties
Is added to the run command
// The location of XML
sonar.testExecutionReportPaths=test/covrage/test-report.xml
// Location of lcov.info
sonar.javascript.lcov.reportPaths=test/covrage/lcov.info
Copy the code
Jest coverage
After jEST is executed, a coverage statistics table will be generated. All files in the coverage statistics folder will be detected.
Statements
: statement coverage, executed to each statement;Branches
: branch coverage, executed to each if block;Functions
: function coverage, called to every function in the program;Lines
: line coverage, executed to each line in the program
Common assertion of Jest
toBe()
—- Tests specific valuestoEqual()
—- Value of the test object typetoBeCalled()
The —- test function is calledtoHaveBeenCalledTimes()
—- tests the number of times the function is calledtoHaveBeenCalledWith()
—- tests the arguments when the function is calledtoBeNull()
– the result isnull
toBeUndefined()
– the result isundefined
toBeDefined()
– the result isdefined
toBeTruthy()
– the result istrue
toBeFalsy()
– the result isfalse
toContain()
—- array match, check whether containtoMatch()
—- Matches character rules and supports regextoBeCloseTo()
– a floating point numbertoThrow()
—- supports strings, floating point numbers, and variablestoMatchSnapshot()
—-jest
Unique snapshot tests.not.toBe()
Before —-.not
That’s the negative form
References:
- Jest Chinese website
- Vue Test Utils
- jest-sonar-reporter
- unit-test
- Testing JavaScript with Jest (Mock post)
- VUE-UnitTest
Pay attention to UU
Pay attention to the public number [front-end UU], regular access to good articles recommended yo ~