This article is written by Zoffi, a member of the team. We have authorized the exclusive use of Doodle Big Front, including but not limited to editing, original annotation and other rights.
background
Testing is an important means to ensure the quality of r&d product deliverables, as well as a part of the software life cycle. R&d students are also important participants in this cycle. After all, bugs are written by students 🐒 so how should R&D students understand testing?
The test profile
We can roughly classify tests in two ways, test types and test phases
Type test
- Functional testing: mainly to verify whether the function meets the requirements, whether missing
- Performance test: mainly focus on system capability, such as QPS and TPS of back-end service, FCP and FMP of front-end
- Robustness testing: focus on the boundary data of the system, whether illegal data will cause system crash, etc
- Safety testing: testing to verify whether the product conforms to the definition of safety requirements and product quality standards
Testing phase
- Unit testing: This stage is mainly the developer to check and verify the current minimum available features
- Integration testing: Testing of a subsystem consisting of several sub-functions after a unit test is passed
- Regression testing: Checking the correctness of existing features
- System testing: The final round of testing done before a product is released, testing the entire system
The relationship between test type and test phase
Testing phase | Test type | participants |
---|---|---|
Unit testing | Functional testing, robustness testing | Research and development of students |
Integration testing | Functional testing, robustness testing | Research and development of students |
Regression testing | Functional testing, robustness testing, security testing | Research & test students |
The system test | Functional testing, performance testing, robustness testing, security testing | Testing students |
Take a chestnut
So let’s say we have an elevator
Functional test: open the door, shut the door, call, decreased rising capsules, capsules, different floors stay and floor call robustness test: according to the call button up and down, don’t choose the floor at the same time, choose all floors, load test, power test safety testing: overload alarm test, the car door jam alarm test performance test: No load time from the first floor to the top layer, full load time from the first floor to the top layer
The market situation
For front-end students, front-end testing is divided into two types, UT and E2E. UT test is often referred to as unit test. We write test cases around function modules and functions. Combine these test cases to form test suits to complete our unit tests. The current mainstream test frameworks: JEST, Mocha, Jasmine
The E2E test is an end-to-end test, in which we pay more attention to the correctness of the entire operational link of the current mainstream test frameworks: Ourselves, Pupeteer, Nightwatch, PhantomJS, and Selenium
The selection
Jest, which is produced by Facebook, integrates Expect, Chalk, JsDOM, Jasmine, Sinon and other test libraries. At the same time, some plug-ins can be used to get through the E2E test to achieve full coverage of UT and E2E tests
Jest profile
Jest is a driver framework that runs test cases and presents test results. We write specific test cases in modules, and each module is an independent test environment. The JEST test suite life cycle has beforeAll, beforeEach, afterAll, afterEach basic apis have describe, Test, expect
Jestjs. IO/zh-hans /doc…
Come a chestnut 🌰 :
- GitHub:github.com/willchou/ut…
- CodeSandBox: CodeSandBox. IO/s/agitated -…
Because jest. UseFakeTimers () does not run properly in CodeSandBox, test suits in example 2 cannot run
import {initConfig, login, resetPassword, getChildrenAssetsByAssetId, addAsset} from '.. /src/utils';
// This module is executed before all test cases run
beforeAll(() = > {
initConfig();
})
describe('account test'.function () {
describe('#login()'.function() {
test('should return true'.function () {
return login('test'.'test').then((res) = >{ expect(res).toBeTruthy(); }); })})// Describe can be nested
describe('#resetPassword()'.function () {
test('should return true'.function() {
return resetPassword('test'.'test'.'test1').then((res) = >{ expect(res).toBeTruthy(); })});// Describe can contain multiple test cases
test('should return assets array'.function () {
return getChildrenAssetsByAssetId('1').then((res) = > {
return expect(res).toEqual([{
assetId: '11'.assetName: '11',}]); })})})})// Test case can be run without describe
test('should return true'.function () {
return login('test'.'test').then((res) = > {
expect(res).toBeTruthy();
});
})
test('should return full resp'.function() {
return addAsset('1'.'1', {
responseRaw: true,
}).then((res) = > {
return expect(res).toMatchObject({
data: {
success: true.code: 200.msg: ' '.result: true,},status: 200.statusText: 'OK',})})})Copy the code
- Detect the results by Expect assertion, as in the above example
- Asynchronous processing is supported. For details, see the preceding example
- Mock methods to make the test more focused on the function being tested (see Example 2)
- Test UI rendering consistency using Snapshot (see Example 2)
- Test Coverage report, JEST — Coverage
Function code:
// example 2
// mock function + snapshot
// src/Clock.jsx
import React, {useEffect, useState} from 'react';
const Clock = () = > {
const [now, setNow] = useState(Date.now());
useEffect(() = > {
const timer = setTimeout(() = > {
setNow(Date.now());
}, 1000);
return () = > {
clearTimeout(timer); }}, [])return (
<div>
timestamp is {now}
</div>
);
}
export default Clock;
Copy the code
Test code:
// test/Clock.test.js
import React from 'react';
import render from 'react-test-renderer';
import Clock from '.. /src/Clock';
jest.useFakeTimers();
Date.now = jest.fn(() = > 1615972229101);
beforeEach(() = > {
jest.clearAllTimers();
})
test('clock snapshot'.() = > {
const tree = render.create(<Clock />).toJSON();
expect(tree).toMatchSnapshot();
})
test('setTimeout tests'.() = > {
const tree = render.create(<Clock />).toJSON();
expect(setTimeout).toHaveBeenCalledTimes(2);
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 1800);
})
Copy the code
Test results:
Next, we update clock. JSX, line 18 text is updated. At this time, the snapshot result changes, we need to manually update the snapshot result, otherwise the test case will still use the old version of snapshot as a reference, resulting in the test results do not meet expectations:
import React, {useEffect, useState} from 'react';
const Clock = () = > {
const [now, setNow] = useState(Date.now());
useEffect(() = > {
const timer = setTimeout(() = > {
setNow(Date.now());
}, 1800);
return () = > {
clearTimeout(timer); }}, [])return (
<div>
the timestamp is {now}
</div>
);
}
export default Clock;
Copy the code
Without updating snapshot:
Update snapshot and test:
./node_modules/.bin/jest -u
conclusion
The test needs to invest a lot of resources in development and maintenance, and the short-term benefits are not great, but in the long run, it can help the students who develop and test to save a lot of regression testing time. At the same time, THE UT test should also be a source of confidence for students. UT testing may not be appropriate for every project and team, and it is not appropriate to invest resources in UT testing in scenarios where short-term one-off projects and team development resources are insufficient. Therefore, it is necessary to make a comprehensive assessment based on the actual situation of the project and team resources