๐Ÿงช Front-end laboratory: tends to summarize front-end research fields and schemes; ๐Ÿš front-end canteen: focuses on horizontal comparison and evaluation of front-end; ๐Ÿ“” front-end small notes: summarizes basic knowledge and experience of front-end

Why testing is needed

In the process of iterative development, how to ensure that our core functions are not affected and regression verification can pass smoothly?

The answer may be testing, lots of testing, as comprehensive as possible.

The cover chart shows a typical pyramid of testing, from bottom to top, unit testing, visual testing, and integration testing.

So, where do we start ๐Ÿค”? Let’s take a closer look at the differences:

Unit Testing

  • Easy to write and easy to run.
  • Ensure that program inputs and outputs are as expected.
  • If you have little time to write tests, they should be your first choice.

Visual Testing/UI Testing

  • Even if you have 100 percent unit test coverage, it doesn’t mean that components look great on devices and browsers, such as a slight change in the width and height of an element or a change in the response logic of a button.
  • The goal of visual testing is to restore the actual browser environment and make the visual rendering of the code manageable.

Integration Tests/Integration Tests

  • Even if two components have unit and visual tests, there is no guarantee that they will work together.
  • On a larger scale, integration testing ensures that the units of a system work closely together to accomplish tasks as expected.
  • E2eTest end-to-end testing can also be incorporated into the scope of integration testing.

Obviously, for someone like me who has never been exposed to a testing framework and wants to start writing tests, it’s a no-brainer to start with unit testing.

Here we choose Jest as our unit testing framework, with the NPM trend of the current popular testing framework:

What is Jest?

Jest is an elegant and concise JavaScript testing framework.

Jest supports Babel, TypeScript, Node, React, Angular, Vue, and many more!

\

Since Jest, like React, is an open source organization owned by Facebook, Jest is pretty much the best test framework for a project based on React.

If your project does not support TS, follow Jest’s official startup documentation to install Jest.

If you need to support TS and need type validation for TS, you are advised to install TS-Jest, which is not different from JEST except when you install and create config.

using npm using yarn
Prerequisites npm i -D jest typescript yarn add --dev jest typescript
Installing npm i -D ts-jest @types/jest yarn add --dev ts-jest @types/jest
Creating config npx ts-jest config:init yarn ts-jest config:init
Running tests npm tor npx jest yarn testor yarn jest

What does the test need to do? (wip)

For a front-end student with only one test experience, the following three abilities are generally concerned at the beginning:

  • Assertion (core function, validating input and output)
  • Asynchronous (for requests or other asynchronous scenarios)
  • Code coverage (CoVRage, which measures the completeness of the test project)

Jest provides built-in support for all of the above functions so that more complex scenarios can be explored on their own.

1, the assertion

Regular code

// Check whether a value is True
export const isTrue = (target: any) = > {
  return Boolean(target) && target ! = ="false";
};
Copy the code

The test code

describe("isTrue".() = > {
  test("case1".() = > {
    expect(isTrue("true")).toEqual(true);
  });
  test("case2".() = > {
    expect(isTrue("false")).toEqual(false);
  });
});
Copy the code

2, asynchronous

Asynchronous request code

export const requestMock = () = > {
  return new Promise((resolve, reject) = > {
    try {
      setTimeout(() = > {
        resolve({ statu: "200" });
      }, 1000);
    } catch(err) { reject(err); }}); };Copy the code

The test code

You can use await and async in your code. You can also get data in the Promise returned by the test, but don’t omit the return.

describe("Request".() = > {
  test("async & await".async() = > {await expect(requestMock()).resolves.toEqual({ statu: "200" });
  });

  test("promise".() = > {
    return requestMock().then((data) = > {
      expect(data).toEqual({ statu: "200" });
    });
  });
});
Copy the code

3. Coverage

After writing the basic test, what can we do if we want to know the coverage of a single test?

Jest will look for tests in the project based on config and execute them in full. Finally, it will output a coverage report like this:

Viewing test results

Jest prints the name, verification result, and time spent for each test on the console.

Which scenarios are suitable for writing single tests?

When business needs are not urgent, perfect single tests can guarantee code quality, and everyone is willing to do it.

When business needs are particularly urgent, the time cost of writing a single test is an issue to consider.

In what scenarios can you consider writing a single test, even if your business needs are urgent?

  1. Business core module
  2. Complex data links

These two types of requirements, often debugging and rework costs are very high.

If we solve more than 80% of the hidden problems through single testing and type inference up front, the development experience will be very smooth and the time cost of single testing will be solved.

Mocking & Transform

CSSMocking

npm install -D identity-obj-proxy
Copy the code
// package.json (for CSS Modules)
{
  "jest": {
    "moduleNameMapper": {
      "\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js"."\.(css|less)$": "identity-obj-proxy"}}}Copy the code

On style objects, all of your classnames are returned as is (e.g. Styles. foobar === ‘foobar’)

SVGMocking

Create a svgtransform.js file in the root directory

module.exports = {
  process() {
    return "module.exports = {};";
  },
  getCacheKey() {
    // The output is always the same.
    return "svgTransform"; }};Copy the code

Configure the transform rule for SVG in jest.config.js

module.exports = {
  ...
  transform: {
    "^.+\.(ts|js|html)$": "ts-jest"."^.+\.svg$": "<rootDir>/svgTransform.js",}};Copy the code

JsDOM

Install test-library/jest-dom, which provides a set of custom JEST matchers that can be used to extend JEST.

npm install --save-dev @testing-library/jest-dom
Copy the code
// In your own jest-setup.js (or any other name)
import '@testing-library/jest-dom'

// In jest.config.js add (if you haven't already)
setupFilesAfterEnv: ['<rootDir>/jest-setup.js']
Copy the code

Now you can start writing test cases ๐Ÿ‘

import React from 'react';
import { render, screen } from '@testing-library/react';
import App from './App';

test('renders learn react link'.() = > {
  render(<App />);
  const linkElement = screen.getByText(/learn react/i);
  expect(linkElement).toBeInTheDocument();
});
Copy the code

Awesom Jest Resources

There are only two examples here, but the others are awesome-jest

1. Jest-electron

Jest + Electron Basic Practice — JEST – Electron

Run the jest single test code in electron (the bottom is Chrome), run the Node code in the browser, and get a relatively complete UI test capability.

Specific pain points: Canvas rendering UI test, interactive animation, multi-render

2. Jest-puppeteer

Jest – Using With Puppeteer

Allow puppeteer to be driven by jest

Actions that can be done:

  1. E2e, UI testing on headless browsers
  2. Use puppeteer’s capabilities to simulate browser operations (such as page hopping, button clicking, form filling), assert the text contained in the page, test the page structure, and create page screenshots.

Explore some frequently asked questions ๐Ÿค”

What if Jest’s cold start time is a little long

  1. --watch / --watchAllStart Jest’s Watch Mode, and the speed of secondary startup will be faster, which is also a way to solve the problem
  2. --runInBand(alias-i )
  1. Run all tests continuously in the current process, rather than creating a work pool for the child processes that run the tests
  2. This feature reduces the time it takes to create a process pool, which is useful when debugging several single tests, but is not as efficient as enabling a multi-process strategy if the number of tests is large

Jest configuration policy for the Monorepo process

  1. You can configure a generic copy under rootjest.config.jsContains the configuration values of all types of JEST
  2. If a custom Jest Config is required for each package/project, jest Config provides itprojectsConfiguration item under rootjest.config.jsJest will try to run tests in all defined projects after being configured inJest-project Configuration item description
module.exports = {
  projects: [
    '<rootDir>/packages/projectA/jest.config.js'.'<rootDir>/packages/projectB/jest.config.js']};Copy the code

Serve with the VSCODE plugin ๐Ÿ› 

Jest Run It

A VS Code extension that helps you run and debug Jest tests from the editor. You no longer need to run the entire test suite for the test you changed ๐ŸŽ‰

  • Provides a test case list panel
  • You can run and debug tests separately from each test code file
  • Action icon for running debugging at the file level

If you don’t want to debug code in the browser and want a full debugging experience in the editor, use it!

A few minor problems

TypeError: Jest: a transform must export a process function.ย 

  1. checkjest ๅ’Œ ts-jestAre the versions of the
  2. Clear the installation package and reinstall the latest version

Refer to the article

  1. jestjs.io/zh-Hans/
  2. React – Test Environment
  3. Nuggets – How to Do Unit Testing with Jest
  4. Zhihu – Front-end Testing Framework JEST
  5. Developers – How to Test a Component Library