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

  1. JestSimple installation and configuration, very easy to use, almost zero configuration, through the NPM command installation can run directly
  2. JestAssertion libraries are automatically integrated, eliminating the need to introduce third-party assertion libraries
  3. JestBuilt-in code coverage reporting allows you to collect code coverage information across the project, including untested files.
  4. JestThe 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 speed
  5. JestprovidesnapshotFunction, by comparing the UI code generated snapshot file, to achievevueAutomatic testing of the framework
  6. jestCan generate sonarQube required test coverage reports, data can be uploaded to sonar
  7. vueOfficially recommended unit testing framework, yesvueFrame friendly, andvueScaffolding 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-utilsVue Test Utils is the official Vue. Js unit Test utility library
  • babel-jest: Automatically compile JavaScript code using Babel
  • vue-jest: Use vue-jest to compile. Vue files
  • jest-serializer-vue: the module that generates the serializer for vue snapshots, which will be required for Snapshot Tests
  • jest-transform-stub: deal with CSS preprocessor | | picture font
  • jest-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 case
  • bailThe: parameter specifies to stop the execution of subsequent test cases if one of them fails
  • moduleFileExtensions: jestType of file to be tested
  • moduleNameMapper: Mapping from regular expressions to module names, similar to Alisa for Webpack
  • transform: Preprocessor configuration
  • snapshotSerializers: JestA list of paths to the snapshot serializer modules used in the snapshot test
  • testResultsProcessor: Custom result handler, usedjest-sonar-reporterThe outputsonarCommon test data formats required
  • collectCoverage: Indicates whether to perform coverage collection
  • collectCoverageFrom: Files that need to be collected for coverage are executed in sequence
  • coverageReporters: JestIn the configuration of writing coverage reports, add”text“Or”text-summary“View the coverage summary in the console output
  • coverageDirectory: JestThe directory that outputs the overwrite information file
  • coveragePathIgnorePatterns: Indicates the directory where the coverage information needs to be skipped
  • coverageThreshold: Sets the minimum threshold for overwriting results. If the threshold is not reached,jestWill return failure
  • testMatch: JestFiles 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
  • jestCan supportbeforeAll.afterAll.beforeEachandafterEachTo write the initialization code.
  • By default,beforeafterBlock can be applied to each test in the file. Also available throughdescribeBlock to group tests.
  • whenbeforeafterBlock in thedescribeWhen inside a block, it only applies to thatdescribeTests within blocks.
  • When executing the order, it is executed firstdescribe, 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 pointstest caseWhen 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 createMockThe simplest way to do a function, if you don’t define the internal implementation of the function,jest.fn()Returns theundefinedAs a return value
  • jest.fn()Created by theMockFunctions can also set return values, define internal implementations, or returnsPromiseobject
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.jsAdd the configuration
testResultsProcessor: 'jest-sonar-reporter'
Copy the code
  • sonar-project.propertiesIs 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 values
  • toEqual()—- Value of the test object type
  • toBeCalled()The —- test function is called
  • toHaveBeenCalledTimes()—- tests the number of times the function is called
  • toHaveBeenCalledWith()—- tests the arguments when the function is called
  • toBeNull()– the result isnull
  • toBeUndefined()– the result isundefined
  • toBeDefined()– the result isdefined
  • toBeTruthy()– the result istrue
  • toBeFalsy()– the result isfalse
  • toContain()—- array match, check whether contain
  • toMatch()—- Matches character rules and supports regex
  • toBeCloseTo()– a floating point number
  • toThrow()—- supports strings, floating point numbers, and variables
  • toMatchSnapshot()—-jestUnique snapshot tests
  • .not.toBe()Before —-.notThat’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 ~