JavaScript coverage rate statistics and javascript coverage rate

Source: Internet
Author: User

JavaScript coverage rate statistics and javascript coverage rate
Main requirements 1. Support for browser & nodejs

Because javascript can be run in both the browser environment and nodejs environment, you need to be able to measure the unit test coverage in both environments.

2. Transparent and seamless

When writing unit test cases, you do not need to write more code to support coverage rate statistics. You can directly calculate the coverage rate without modifying the previous write cases.

Principle

There are few articles about javascript coverage. The figure below is based on reading the Open Source javascript coverage tool istanbul and the coverage plug-in Karma-coverage of the open source test framework karma. The core idea of javascript coverage rate statistics is to inject statistical code into the corresponding position of the source code. After the code is run, the program running path is determined based on the statistical code statistics, and finally the coverage rate statistics report is generated.

1. Conversion (instrument)
  • Use the open-source tool Esprima to analyze the source code and generate a syntax tree
  • Inject Statistical Code at the corresponding position in the syntax tree, assign values to the corresponding global variables when the program runs to this position, and ensure that the Code Execution Process can be known based on the global variables after execution.
  • Use the open-source tool Escodegen to generate the corresponding javascript code based on the injected syntax tree, that is, the converted code (instrumented code)

Note: The advantage of syntax analysis here is that for writing nonstandard code (such as multiple statements in one row), it is still able to well count information such as branch coverage and combination coverage.

2. run)

In this step, you must first load the converted code:

  • Nodejs: directlyrequireHook the statement to achieve seamless implementation, which will be detailed later
  • Browser environment: You need to pass the converted code to the browser. If it is a test framework with server such as karma, it needs to be transmitted to the browser through socket. After the execution, the execution result containing the coverage information is sent back to the server to generate the test report.

Then execute the unit test, and the statistical information will be mounted to the global variable.thisBelow. For the browser environment,thisYeswindowFor the nodejs environmentthisYesglobal.

3. generate a report)

This step generates reports in specific formats, such as html, lcov, cobertura, and teamcity, based on the coverage information in the global scalar.

Example
//source codefunction abs(num){    if(abs > 0)        return num;    else        return -num;}
//instrumented codevar __cov_iypKC$dWI6uJFmvxThycaA = (Function('return this'))();if (!__cov_iypKC$dWI6uJFmvxThycaA.__coverage__) { __cov_iypKC$dWI6uJFmvxThycaA.__coverage__ = {}; }__cov_iypKC$dWI6uJFmvxThycaA = __cov_iypKC$dWI6uJFmvxThycaA.__coverage__;if (!(__cov_iypKC$dWI6uJFmvxThycaA['/Users/lonfee88/Codes/testframe/coverage-jasmine-istanbul-karma/abs.js'])) {   __cov_iypKC$dWI6uJFmvxThycaA['/Users/lonfee88/Codes/testframe/coverage-jasmine-istanbul-karma/abs.js'] = {"path":"/Users/lonfee88/Codes/testframe/coverage-jasmine-istanbul-karma/abs.js","s":{"1":1,"2":0,"3":0,"4":0},"b":{"1":[0,0]},"f":{"1":0},"fnMap":{"1":{"name":"abs","line":1,"loc":{"start":{"line":1,"column":-15},"end":{"line":1,"column":17}}}},"statementMap":{"1":{"start":{"line":1,"column":-15},"end":{"line":6,"column":1}},"2":{"start":{"line":2,"column":1},"end":{"line":5,"column":14}},"3":{"start":{"line":3,"column":2},"end":{"line":3,"column":13}},"4":{"start":{"line":5,"column":2},"end":{"line":5,"column":14}}},"branchMap":{"1":{"line":2,"type":"if","locations":[{"start":{"line":2,"column":1},"end":{"line":2,"column":1}},{"start":{"line":2,"column":1},"end":{"line":2,"column":1}}]}}};}__cov_iypKC$dWI6uJFmvxThycaA = __cov_iypKC$dWI6uJFmvxThycaA['/Users/lonfee88/Codes/testframe/coverage-jasmine-istanbul-karma/abs.js'];function abs(num){__cov_iypKC$dWI6uJFmvxThycaA.f['1']++;__cov_iypKC$dWI6uJFmvxThycaA.s['2']++;if(abs>0){__cov_iypKC$dWI6uJFmvxThycaA.b['1'][0]++;__cov_iypKC$dWI6uJFmvxThycaA.s['3']++;return num;}else{__cov_iypKC$dWI6uJFmvxThycaA.b['1'][1]++;__cov_iypKC$dWI6uJFmvxThycaA.s['4']++;return-num;}}
Node. js integration coverage

The hook can directly and seamlessly load the converted code, and hook the following two statements:

  • require
  • vm.createScript

The code to hook require is throughModule._extensions['.js']Implemented by assigning values:

Function hookRequire (matcher, transformer, options) {options = options | |{}; var fn = transformFn (matcher, transformer, options. verbose), postLoadHook = options. postLoadHook & typeof options. postLoadHook = 'function '? Options. postLoadHook: null; Module. _ extensions ['. js'] = function (module, filename) {var ret = fn (fs. readFileSync (filename, 'utf8'), filename); if (ret. changed) {// load the code after the instrument and run the module. _ compile (ret. code, filename);} else {// load the original code and run originalLoader (module, filename);} if (postLoadHook) {postLoadHook (filename );}};}

Hook makes coverage integration simple, and does not even need to write code. For example, Mocha coverage integration only needs to use the following call method:

istanbul cover _mocha -- -R spec test/spec
Browser integration coverage

Browser integration coverage is a little tricky. Fortunately, istanbul provides APIs:

  1. Convert the code (call the istanbul Instrumenter Interface)
  2. Send the instrumented code to the browser (implemented by yourself)
  3. Send the execution result containing the coverage information back to the server (implemented by yourself)
  4. Generate a coverage report based on the returned Coverage Information (call the Reporter interface of istanbul)

Program implementation code coverage and path analysis detection, C ++, C #, Java, and JavaScript (any programming language)

If you use source code plug-in, you need to perform lexical and syntax analysis on the input program to create a syntax analysis tree (there are some ready-made tools such as bison, which can be used by anlr ), the language analysis tree is used to obtain the control flow relationship of the program, and then the basic blocks of the program can be analyzed. To obtain the coverage rate and program execution path, insert the basic blocks and use the inserted probes to record their execution.
 
Function for counting news browsing times using javascript

For the number of views of a news piece, it is better to add a field corresponding to this news piece in the database to count the number of views, initialized to 0

Every time you click a link to the news, xmlHttp is used (I will only do this ..) Asynchronously access the background page and update this field in the background program to make it + = 1. Isn't that enough.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.