Why do we need unit tests?

  • The “bugs” that helped us hide in advance:
    • We usually only run the general process after the development is complete and then put the pressure on QA, but testing every case through the interface is very troublesome, and if QA misses the test, it will bury hidden bugs online.
    • For new requirements, we may not be very clear about the existing logic, so when we add new logic, we can further avoid the potential risk of changing the code through unit testing
  • Code quality:
    • More often than not, code suitable for unit testing is more readable. We have to break down complex components into finer grained components, and complex computing into finer grained tool modules to make unit testing more suitable.

What scenarios need unit testing?

  • UI base component library
  • Computing Tools Module (UTIl)
  • Simple business base components
  • Store using

Granularity of coverage

  • The UI base component library: computed and Watch properties, pure computed methods, the important template branch, emit for events
  • Computing tools module (util: 100% coverage)
  • Simple business base components: computed and Watch properties, pure computed methods, important template branches, emit for events
  • Vuex: Get and mutation use mock state to determine whether they work properly. Action only needs mock COMMIT to determine whether the action call can function with mutation

Vue unit test tool introduction

  • Test framework JEST:jestjs.io/The commonly used unit test frameworks are Jasmine and Mocha + Chai. Different from these frameworks, JEST is more integrated and provides richer functions. Making good use of the functions provided by JEST can greatly improve the execution efficiency of test cases. Jest features:
    • Test cases are executed in parallel, more efficiently
    • Powerful Mock functionality
    • Built-in code coverage checking, no need to introduce additional tools
    • JSDOM integration enables direct DOM related testing
    • Easier to use and requires little extra configuration
    • The ES Module Import code can be tested directly
    • There is a snapshot test function to test the UI of frameworks such as React
  • Vue Test Utils: Vue-utils.vuejs.org/ is the official Vue Test utils.js unit Test utility library for testing Vue components

Basic environment construction

init product

yarn init
Copy the code

add jest

yarn add --dev jest
Copy the code

Add example

src/test1.js

function sum(a, b) {
  return a + b;
}
module.exports = sum;
Copy the code

SRC / – test__ / test1. Test. Js

const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});
Copy the code

run

jest
Copy the code

Support for es6

add babel

yarn add --dev babel-jest @babel/core @babel/preset-env
Copy the code

Add configuration babel.config.js

// babel.config.js
module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          node: 'current',
        },
      },
    ],
  ],
};
Copy the code

Add example

src/test2.js

export const sum = function (a, b) {
  const c = 3;
  return a + b + c;
}
Copy the code

SRC / – test__ / test2. Test. Js

import {sum} from '.. /test2'; test('adds 1 + 2 + 3 to equal 6', () => { expect(sum(1, 2)).toBe(6); });Copy the code

run

jest
Copy the code

Important Configuration description

Add jest.config.js, which is the default configuration file name for Jest, and also allow jest to be specified with the –config parameter

jest --init
Copy the code

Important configuration fields

Module.exports = {mock module automock: false, // collect test coverage // collectCoverage: false, // global variables // e.g. // globals: { // 'ts-jest': { // tsConfig: path.join(__dirname, './tsconfig.jest.json'), // babelConfig: true, // diagnostics: false // }, // 'vue-jest': { // tsConfig: path.join(__dirname, './tsconfig.jest.json'), // }, // FeatureFlags: {}, / /}, // A map from regular expressions to module names that allow to stub out resources with a single module // // moduleNameMapper: {// '^@test$': {// '^@test$': Path.join (__dirname, './__mocks__/test.js'), //}, // Test directory. The default is the current directory. Process.cwd () is the test directory where you allow test commands rootDir: null, // this can be used for initialization operations such as installing UI component libraries // setupFiles: [], // Test file format // testMatch: [/ / "/ __tests__ / * * / * * *. [jt] s? (x)", / / "* * /? (*) + (spec | test). [tj] s? (x)" / /, / / test directory / / testPathIgnorePatterns ignored: [/ / "/ node_modules / / /, / / the file content of escape, such as image transformation, js ts file escape / / transform: {/ / '^. + \ \. JSX? $': 'babel-jest', // '^.+\\.tsx? $': 'ts-jest', // '^.+\\.vue$': 'vue-jest', // '\\.svg$': path.join(__dirname, './jest-transforms/fileTransformer.js'), // } };Copy the code

Support the typescript

install

yarn add --dev ts-jest @types/jest
yarn add --dev typescript
Copy the code

Generating a Configuration File

Generate the tsconfig.json configuration file

tsc --init
Copy the code

Add tsconfig. Jest. Json

{
  "extends": "./tsconfig",
  "compilerOptions": {
    "module": "commonjs"
  }
}
Copy the code

Modify the jest. Config. Json

// globals: { // 'ts-jest': { // tsConfig: './tsconfig.jest.json', // babelConfig: true, // diagnostics: false // } // }, // transform: { // "^.+\\.(js|jsx)$": "babel-jest", // '^.+\\.tsx? $': 'ts-jest' // }Copy the code

example

src/test3.ts

export const sum = function (a: number, b: number): number {
  const c = 3;
  return a + b + c;
}
Copy the code

SRC / – test__ / test3. Test. Ts

import {sum} from '.. /test3'; test('adds 1 + 2 + 3 to equal 6', () => { expect(sum(1, 2)).toBe(6); });Copy the code

Vue components are supported

install

Yarn add --dev vue-jest@vue /test-utils vue-template-compiler [email protected] yarn add vueCopy the code

Modify the jest. Config. Js

globals: { 'ts-jest': { tsConfig: './tsconfig.jest.json', babelConfig: true, diagnostics: false }, 'vue-jest': { tsConfig: './tsconfig.jest.json', }, }, transform: { "^.+\\.(js|jsx)$": "babel-jest", '^.+\\.tsx? $': 'ts-jest', '^.+\\.vue$': 'vue-jest' }Copy the code

example

src/Test4.vue

<template>
    <div class="test-wrapper">
        {{message}}
    </div>
</template>

<script language="ts">
  export default {
    name: 'Test',
    props: {
      message: {
        type: String,
        default: ''
      }
    },
    methods: {
    }
  };
</script>
Copy the code

src/tests/test4.test.ts

Import {mount} from '@vue/test-utils' import test from '@vue/test-utils' import test from '.. /test4.vue' import {sum} from ".. /test3"; // Now mount the component and you get the wrapper const wrapper = mount(Test, {propsData: {message: 'test'}}) // You can access the actual Vue instance via 'wrapper.vm' const vm = wrapper.vm Console.log (wrapper) test('vue components', () => {expect(wrapper. Find ('.test-wrapper').exists()).tobe (true); expect(wrapper.find('.test-wrapper').text()).toBe('test'); });Copy the code