Introduction to the

Every day we are busy writing bugs, sometimes it’s good to stop and look for bugs. Testing is broadly divided into black box testing and white box testing. Unit testing is the latter. It is about designing test cases based on the logic of the program to ensure that the program modules behave as expected.

Front-end unit testing is not much, but it does not mean that it is unnecessary, for some complex data processing, common class library, unit testing is very necessary, as long as the code is modified, there is a risk, the safest way to check whether the code is correct or not is through all the test cases designed. Here’s what you’ll learn from this article:

  1. Node.jsHow to do unit testing, how to generate test reports and test coverage
  2. vue.jsHow do single-file components build a unit test environment from scratch

Node.jsUnit testing

Before unit testing, we need to use a test framework and an assertion library. The test framework is to help us write test cases, and the assertion is mainly used to judge whether the expected output is consistent with the actual output. In this paper, mocha is used as the testing framework and expect.

CommonJS is different from ES6 modularity

Front-end development environments now almost always run in Node.js, but are packaged as static resource files at the end. So unit tests for JavaScript files in a simple project will fail due to modularity differences because ES6 uses import/export and CommonJS uses require/module.exports. To learn how Node.js handles ES6 modules, please refer to Ruan’s article. This article recommends a third-party library, esM, that allows Node.js to load ES6 Modules in just two steps. The usage process is as follows:

  • The installation
npm install esm -D
Copy the code
  • use
const $require = require('esm') (module)
// Note: In the case of export default, you need to obtain the imported module from. Default
const TestModule = $require('ES6Module.js')
Copy the code

The test code

The following is the test code, mainly to test the addition operation and the function of the coriolization process is correct.

class Calc {
  constructor() {
    this.add = this.addFun()
  }
  // The function is currified
  addFun () {
    let args = []
    let calcFun = function (. params) {
      args = args.concat(params)
      return args.reduce((total, current) = > {
        return total + current
      }, 0)
    }

    calcFun.clear = function () {
      args = []
    }

    return calcFun
  }
}

export default = Calc
Copy the code

Write test cases

The test framework uses Mocha and generally writes unit test cases, which are dependent on Describe and IT. Describe is similar to a class in development and is a collection of a class of test cases. It is equivalent to ordinary function and is a concrete test case realization. The following is a simple test case, which briefly lists the basic uses of common and asynchronous tests. For more information, please refer to mocha’s official website

const Calc = require('.. /class/calc.js')
const expect = require('expect.js')

const calcInstance = new Calc()
describe('Test calc add operation'.function () {
  it('should 1 + 2 === 3'.function () {
    expect(calcInstance.add(1.2)).to.be(3)}); it('should summary + 2 === 4'.function () {
    expect(calcInstance.add(2)).to.be(5)}); it('should 1 + 2 === 3 after clear'.function () {
    // Specifies the current test case timeout
    this.timeout(0)
    calcInstance.add.clear()
    // Asynchronous test
    return new Promise(resolve= > {
      setTimeout(() = > {
        resolve()
      }, 2000)
    }).then(() = > {
      expect(calcInstance.add(1.2)).to.be(3)})}); })Copy the code

Unit test metrics

Description of coverage

Coverage is the core index of unit test, which is divided into Statements, Branches, Functions and Lines. A good unit test case ensures that the key logic of the code being tested is covered by the test case. The following is the unit test coverage of the Calc class.

Unit test coverage statistics

The open source component NYC can help us count coverage.

  • The installation
npm install nyc -D
Copy the code
  • The configuration file
// nyc.config.js
module.exports = {
  all: true.include: [ // Contains the test file
    "web/src/lib/**.js".".electron/class/**.js"."web/src/**/*.js"."web/src/**/*.vue"].exclude: [ // Exclude test files
    "web/test/*.spec.js".".electron/test/*.spec.js"].checkCoverage: false.// Test benchmark coverage
  reporter: ['text'.'html'] // Test report format
}
Copy the code
  • use
// package.json
"test-add": "nyc mocha .electron/test/calc.spec.js"
Copy the code

Visualize unit test reports

Mocha officially recommends the use of MochAwesome for generating visual test reports and is very simple to use.

  • The installation
npm install mochawesome -D
Copy the code
  • use
// package.json
"test-add-reporter": "mocha .electron/test/calc.spec.js --reporter mochawesome --reporter-options reportDir=mochaReporter,reportFilename=addReporter"
Copy the code

Matters needing attention

When writing unit test cases, consider not only test coverage but also test case design. Qualified test cases should not only contain normal input and output, but also abnormal input and output judgment. Test cases should not be written with the thinking of development.

Unit testing of vUE components

The official vUE single-file component test scaffolding is also integrated, but take the time to learn how to build a vue single-file component test environment from scratch.

The.vue file cannot be executed directly; it needs to be packaged and compiled into a static resource file that the browser can recognize. There is an open source tool called Mochapack that provides this capability. As the name implies, normal Mocha test cases can be executed directly, but when non-javascript syntax is encountered, an error is reported. The main function of Mochapack is to use WebPack to compile and transform test cases before they are executed without worrying about execution errors. The configuration is as follows:

// Basic configuration
{
  "test-vue-sfc": "mochapack --webpack-config ./build/webpack.test.config.js --require ./web/test/setup.js web/test/demo.spec.js"
}
Copy the code
  • --webpack-configThe specifiedwebpackThe configuration file
  • --requireSpecify the environment dependent state, such asnodejsDoes not exist in thedom, need to introducejs-dom
  • web/test/demo.spec.jsTest cases that need to be executed

Vue test case writing

The test case was executed using NodeJS and there was no browser environment, so we used the official test tool @vue/test-utils to simulate mounting, clicking, etc. The usage method is relatively simple. The following is a simple test case.

import Vue from 'vue'
import ElementUI from 'element-ui'
import TestDemo from '.. /src/components/test-demo.vue'
import { shallowMount } from '@vue/test-utils'

Vue.use(ElementUI)

describe('Test test-demo.vue'.function () {
  this.timeout(0)
  const wrapper = shallowMount(TestDemo)
  wrapper.vm.count = 1
  it('should summary === 1'.function () {
    expect(wrapper.vm.summary).to.be(1)}); })Copy the code

conclusion

For modular units such as generality and complex processing logic, unit testing will benefit a lot. At least, there will be an obvious feedback on the right and wrong of each change. Unit testing should pay attention not only to a certain degree of coverage, but also to the rationality of test case design. The complete code can be referred to the electron demo. This project is the electron development demo, which contains the common pits in my daily development. If you are interested, you can pay attention to them.