Front-end precision test exploration: real-time coverage statistics tool

background

With the growth of business and the consequent surge in front-end demand, how to ensure the quality of the front-end code within a limited time.
Through the unilateral guarantee of testing students, it is still inevitable that front-end online problems are inevitable, and there are areas where regressions are not in place or missing tests. , At the same time, there is no objective data to quantify the level of test quality.

By supplementing the single test method, some problems can be found in advance and the cost of problem solving can be reduced. However, due to the business form, the demand changes frequently, the function iteration is fast, and the single test is supplemented and maintained. The cost of the project is relatively high, and there is no single test method in most of the front-end projects of the business side. Therefore, when the development is self-testing, the perception is relatively weak, there is no quantitative data, and there is no unified indicator to check before the project is tested. Test is for development. I don’t understand the self-test status;

at the same time, the front-end lacks an integration test coverage statistics framework like jacoco, and it is unable to collect coverage through integration tests. There is still no data quantification for the quality of the test phase. In
combination with the points mentioned above, we propose a front-end The need to integrate test coverage statistics tools to improve the quality of development self-testing and project testing quality, while helping to supplement scenarios where regressions are not in place or missing tests, and to improve online quality.


Technical selection

First of all, the premise of coverage collection requires the completion of code instrumentation work. The instrumentation method comes from two open source coverage statistics frameworks, istanbul.js and istanbul-middleware (hereinafter referred to as im). Several instrumentation methods are provided. In fact, im is also encapsulated on the basis of istanbul.js. The ability comes from
all the instrumentation methods of istanbul-lib-instrument , which can be roughly divided into two types-1. instrumentation before running 2. instrumentation at runtime

####
Instrument

before running nyc instrument manually instrument the compiled JS file to form a new JS file after instrumentation


babel-plugin-istanbul

The babel plug-in provided by istanbul can be directly implanted in the code compilation and packaging stage Instrumentation code is
suitable for front-end projects using babel, both react and vue-based projects are available

####Instrument
im.hookLoader

at runtime is suitable for server-side file mounting such as node applications.
When the application starts, a hook method will be added at the require entry, so that when the application starts, all the code after the instrumentation is loaded


im. .createClientHandler is

suitable for client-side JS mounting, such as react and vue js
by specifying the root path, will intercept all js file requests of this path, and return the code after the instrumentation, that is, the action
effect of the browser requesting static resources and babel -plugin-istanbul is similar, the difference is that this method will only return the instrumentation code when the browser requests js, which is a dynamic process

Insertion method Features Advantage Disadvantage
nyc Manually insert source js files locally, and generate post-instrument files The compiled js can be manually inserted, regardless of the engineering framework Files after manual instrumentation need to be uploaded by themselves, which will affect the original packaging and publishing process; not applicable to server-side instrumentation
babel-plugin-istanbul When Babel is compiled, instrumentation code is automatically generated Low cost of transformation, quick automatic pile insertion Limited to projects that use babel
im.hookLoader Add a hook method at the require entrance to return the instrumented code Low cost of transformation, quick automatic pile insertion Only applicable to server-side instrumentation
im.createClientHandler Intercept the GET method of the browser requesting static resource files, and return the instrumented JS Automatic instrumentation, no need to modify the original packaging process and scripts Only applicable to client instrumentation; this method is based on express and is limited to projects that use express

Finally, the instrumentation method we used
App (node)-istanbulMiddleware.hookLoader
Client (react & vue)-babel-plugin-istanbul


Modular design

uPJQTe.png
It is mainly divided into three modules. First obtain traceable code through code instrumentation, then report the code line coverage records generated by user behavior in real time, and finally present coverage related information.

Code instrumentation


The client side
uses the babel-plugin-istanbul plug-in, which can be completed in the babel compilation stage

The Node side

relies on the capabilities provided by istanbuljs-istanbul-lib-hook and istanbul-lib-instrument
rewrite the istanbulMiddleware.hookLoader method, mount the file before the node starts, add hook functions before the require method, and add code instrumentation

Examples of instrumentation results

uPJmy6.png
uPJnOK.png

The instrumented JS will add a coverage method to maintain and point to the coverage information attribution, and is used to obtain the coverage information of the file.
At the same time, the method in the js will leave a mark on the path of the execution process, and it will be executed afterwards. Update the corresponding row or block information in the coverage information in real time

Data reporting


When the Node-side
application is released, write the corresponding project and branch information, create a timer, and upload the _global.coverage variable in real time, which is the coverage information


The client-
side reporting is quite special. Unlike the server-side, the client-side can maintain coverage variables and timer methods globally after publishing. All data generation and consumption on the client-side follows the life cycle of the page, so it is not very controllable, so An additional container is needed for processing. We chose to report through the chrome plug-in, through the global management of coverage information objects, and notification issuance to achieve the reporting process. The detailed workflow of the plug-in is as follows

uPJEWR.png

Coverage server

  • Inherit the function of istanbul middleware
  • Support branch dimension reception and query coverage
  • Coverage replacement when code changes, support for storing and viewing historical versions

Mainly based on istanbul-middleware for secondary development, extended istanbulMiddleware.createHandler method

uPJMwD.png

/:ns/:repo /:ns/:repo/show The
two coverage display interfaces have added three input parameters, ns, repo, and branch, which are used to distinguish different coverage rates
and add an additional parameter history. Pass the variable flag Get historical coverage

/client/:ns/:repo?branch={}&source={} body carries coverage information
and reports according to application and branch information. After receiving the reported information, it will first obtain the existing coverage under the branch and then report it this time. Information is merged. The
merge is traversed and merged according to the file name. If a file is found to have a different coverage structure between the old and the old
, a code change will be discarded. The old coverage rate will be taken as the new coverage rate and the old coverage rate will be stored in the history. Version

Page display


Full coverage display
Use istanbulmiddle native report generation

Incremental coverage rate display.

Compare the master difference through the gitlab interface, and display the respective coverage rates in separate files. The same as the full coverage rate, but it is refined. The overall page is completed with vue muse-ui

uPJmy6.png

Based on the master branch, incremental file coverage

uPJnOK.png

Full file coverage directory structure

work process

uPJ3Yd.png

It is mainly divided into 3 parts, corresponding to the access, reporting, and display mentioned in the previous section. The
client code instrumentation is completed through the babel plug-in, and the instrumentation plug-in provided to the node side can be used to complete the server-side code instrumentation and timing reporting function in one step.
Cooperate with the provided chrome plug-in to complete the coverage report task of the client. The coverage
server is responsible for the reception and storage of information, and returns to the front-end data information. The
front-end is responsible for data information display


Business practice

Access to the test environment release platform to realize the multi-version real-time coverage collection and display function in the dimensions of applications and branches, seamlessly docking the project test environment, after each application in the project is released, the coverage rate report is automatically turned on, and the project is tested in real time Record, can be viewed in real time. Before the project is tested, give development quantitative indicators, after the project test, the final coverage data can be given to help test students to check and improve the uncovered functions.

Currently in the e-commerce education and industry two businesses Since the tool is limited to the qa environment, it can only collect the project data tested in the qa environment. In the functional testing phase, from the perspective of the usage data, the incremental line code coverage reached more than 80% (currently The increment only reaches the file dimension, not the row dimension), and the uncovered rows mainly include four types: exception capture, defensive coding, and redundant codes that are not added this time without concern, which belong to the allowable range.

Guess you like

Origin blog.csdn.net/YZcoder/article/details/101268945