Why

The more your tests resemble the way your software is used, the more confidence they can give you.

background

The project is built with UMI framework, and its own built-in JEST testing framework

  • Umi built-in JEST configuration
{
    collectCoverageFrom: [
      'index.{js,jsx,ts,tsx}',
      hasSrc && 'src/**/*.{js,jsx,ts,tsx}', isLerna && ! args.package &&'packages/*/src/**/*.{js,jsx,ts,tsx}',
      isLerna &&
        args.package &&
        `packages/${args.package}/src/**/*.{js,jsx,ts,tsx}`.'! **/typings/**'.'! **/types/**'.'! **/fixtures/**'.'! **/examples/**'.'! **/*.d.ts',
    ].filter(Boolean),
    moduleFileExtensions: ['js'.'jsx'.'ts'.'tsx'.'json'].moduleNameMapper: {
      '\\.(css|less|sass|scss|stylus)$': require.resolve('identity-obj-proxy'),},setupFiles: [require.resolve('.. /.. /helpers/setupFiles/shim')].setupFilesAfterEnv: [require.resolve('.. /.. /helpers/setupFiles/jasmine')].testEnvironment: require.resolve('jest-environment-jsdom-fourteen'),
    testMatch: [
      `${testMatchPrefix}* * /? (*.${testMatchTypes.join('|')}).(j|t)s? (x)`,].testPathIgnorePatterns: ['/node_modules/'.'/fixtures/'].transform: {
      '^.+\\.(js|jsx|ts|tsx)$': require.resolve(
        '.. /.. /helpers/transformers/javascript',),'^.+\\.(css|less|sass|scss|stylus)$': require.resolve(
        '.. /.. /helpers/transformers/css',),'^ (? ! .*\\.(js|jsx|ts|tsx|css|less|sass|scss|stylus|json)$)': require.resolve(
        '.. /.. /helpers/transformers/file',),},verbose: true.transformIgnorePatterns: [
      / / / ^ / *? For compatibility with the TNPM directory structure
      // For example: [email protected]@umi-test
      // `node_modules/(? ! ([^ /] *? umi|[^/]*? umi-test)/)`,].// Used to set the number of jest worker startup. (process.env.MAX_WORKERS ? {maxWorkers: Number(process.env.MAX_WORKERS) }
      : {}),
  }
Copy the code
  • The code for the merge configuration is as follows:
const config = mergeConfig(
  createDefaultConfig(cwd, args),
  packageJestConfig,
  userJestConfig
);
Copy the code

The source code is here: Click jump

Technology stack selection

As the built-in JEST configuration of UMI cannot meet the requirements of our project, JEST is a JavaScript testing framework. If unit testing of DOM is needed, more test libraries need to be introduced

Jest

Jest is built-in to UMI. This is the basis for basic understanding. The document is as follows: jestjs. IO/zh-hans /

ts-jest

Ts-jest is a conversion tool that allows us to write test code in Typescript. It is also a built-in configuration of UMI and rarely needs to be changed. If you need to change it, see the official documentation: Kulshekhar.

React Testing Library

React Testing Library is a solution for Testing the React component. It includes the React DOM /test-utils API, which is the official test tool for React. It is also the official recommended test DOM Library for React. As to why you don’t use the old test library Enzyme, check out this post on the author’s blog:Kentcdodds.com/blog/introd… Usually when writing test code, I am more exposed to React Testing Library, whose documentation is as follows:Testing-library.com/docs/react-…In addition to @testing-library/react, other @testing- Library libraries, such as @testing-library/ user-Event, are used to simulate interactions. @testing-library/react is based on @testing-library/dom, so a basic understanding of @testing-library/dom will help you understand @testing-library/react

Mock Service Worker

The Mock Service Worker (MSW) is used to Mock the result of an Axios request. It executes the REST/GraphQL API and is documented as follows: github.com/mswjs/msw

Using the boot

Unit test writing

Without going into much detail here, you can refer to the official Example and other guidance articles, as well as existing unit test code, to share the following articles

  1. Official demo: testing-library.com/docs/react-…
  2. The author’s blog – Common mistakes with the React Testing Library – kentcdodds.com/blog/common…
  3. Test the react – toolkit – ogzhanolguncu.com/blog/testin…

Note: Writing unit tests increases your understanding and trust in your code

run

The unit test environment is set up, and you just need to execute the corresponding naming

"test": "umi test --no-cache".// Run the unit tests once
"test:watch": "umi test --watch".// Monitor code changes in real time and execute
"test:clear": "umi test --clearCache"."test:coverage": "umi test --coverage".// Execute to output the coverage report
Copy the code

configuration

In some cases, the existing configuration cannot meet your requirements. You can change the configuration as required

  1. jest.config.js
  2. ./src/setupTests.ts

coverage

Use the Istanbul code coverage tools, about coverage index reference: nguyen other this article – www.ruanyifeng.com/blog/2015/0… The coverage objectives of the current project are as follows:

global: {
  branches: 90.functions: 90.lines: 90.statements: 90,},Copy the code

Use YARN test: Coverage to test output coverage reports

Record the problems during the pitting process

Note some problems: to prevent repeated potholes

  1. Jest test fails : TypeError: window.matchMedia is not a function
  2. Jest + react-testing-library: Warning update was not wrapped in act()
  3. Uncaught [Error: Invalid hook call. Hooks can only be called inside of the body of a function component — mock Module introduced in setuptests.ts
  4. The module factory of jest.mock() is not allowed to reference any out-of-scope variable In the inside solution, refer to :github.com/facebook/je…

The follow-up plan

  1. Pulling out the common test code makes writing single tests smoother
  2. Supplement unit tests to meet coverage indicators
  3. Let’s do end-to-end testing
  4. Add to CI/CD