[技术博客]JSCover+selenium得到js代码覆盖率

本文档讲解了咱们是如何使用JSCover来得到Selenium的测试样例的js代码文件的执行覆盖率的。javascript

事实上网上有挺多博客讲这玩意儿了,不过彻底按照网上已有的教程去弄的的话,并没有法知足咱们的须要。html

参考连接:java

  1. https://www.cnblogs.com/bhlsheji/p/4
  2. https://stackoverflow.com/questions/9495625/selenium-is-there-any-js-javascript-code-coverage-tool-which-we-can-integrate
  3. http://tntim96.github.io/JSCover/manual/manual.xml

工具介绍

Selenium

浏览器自动化测试工具。能够模拟用户对浏览器的操做,从而起到自动化测试的效果。具体怎么用,网上一堆教程,不赘述了。python

selenium会在测试样例的编写中被使用,咱们还会使用selenium的executeScript调用JSCover提供的hook来保存覆盖率数据。git

JSCover

js代码覆盖率检测工具。原理是插桩js代码,该项目在github上开源,它也有托管在github上的官网。附带一提,根据个人使用经验来看,有问题不要查百度、也不要查它的user manual,而是应该查github上的issue。github

JSCover咱们只使用它的JSCover-all.jar文件,下下来之后就拿出来这个就好了。chrome

原理性流程

  1. 使用JSCover对js代码进行插桩,使得咱们可以得到代码覆盖率。
  2. 对插桩后的代码执行测试样例。
  3. 将各测试样例的代码覆盖率导出保存起来。
  4. 合并各测试样例的代码覆盖率
  5. 使用合并后的代码覆盖率文件生成测试报告

流程示意图

实际流程的分步讲解

0. 预准备jscoverage.js

这一步是由于jscover自身存在的问题,缘由以后再讲解。总之先得在不启用local-storage的状况下对代码进行一次插桩,获得jscoverage.jsjson

示例指令:java -Dfile.encoding=UTF-8 -jar JSCover-all.jar -fs D:/code_origin D:/code_instrumented浏览器

  • -Dfile.encoding=UTF-8:设定编码,避免网页代码中的中文在插桩后变成乱码。
  • -jar JSCover-all.jar:指定JSCover-all.jar的所在路径。
  • -fs:指定使用文件插桩模式。咱们只使用该模式,除此以外还有proxy模式,不过咱们不使用,缘由见最下。
  • D:/code_originD:/code_instrumented:前者为原来的js代码文件所在的目录,后者为想把插桩后的代码保存到的目录。

执行完上述指令后,应该就能在插桩后的代码的所在目录(也就是示例中的D:/code_instrumented)中找到jscoverage.js文件,将它保存到一个合适的地方,留待以后使用。工具

1. 代码插桩

代码插桩分为两部分,一部分是给网页的js代码文件插桩,使得执行时可以获得覆盖率变量。另外一部分是在测试样例的执行末尾利用selenium提供的executeScript调用JSCover提供的hook,这本质就是个动态插桩的过程,它使得咱们可以保存下来覆盖率数据。

网页的js代码文件插桩

示例指令:java -Dfile.encoding=UTF-8 -jar JSCover-all.jar -fs --local-storage D:/code_origin D:/code_instrumented

事实上,它和上一步“预准备”中的指令的差异仅在于--local-storage而已。local-storage的含义是“是否启用HTML5的local-storage功能来保存代码覆盖率变量”。若是不启用的话,JSCover就会用一个js变量来保存代码覆盖率变量,而众所周知,js变量是没法跨页面的,这也就致使每当咱们切换页面时,代码覆盖率变量就会丢失。因此咱们须要启用local-storage来保存代码覆盖率变量。

不过JSCover在local-storage模式下生成的jscoverage.js文件存在bug,因此咱们在上一步“预准备”时须要先在非local-storage下生成一个jscoverage.js文件。这个文件仅仅是用来显示测试报告用的,不会影响到代码覆盖率数据。

hook调用

这一部分能够参考参考连接3(官方手册)中的作法。官网代码的python版:

json_str = driver.execute_script("return jscoverage_serializeCoverageToJSON();")

以后将json_str保存成jscoverage.json,而后放到插桩后的代码所在目录下,覆盖掉原来的jscoverage.json文件就好了。

不过由于官网这种作法是一个类一个jscoverage.json,一个类在selenium中就表示一类测试样例,而咱们有好多好多类测试样例,因此就会有好多好多代码覆盖率文件jscoverage.json。因此咱们须要在执行时分别保存它们,在所有执行完后再合并它们。合并会在后面再讲解。

假设咱们有三个Selenium的测试类,分别将叫TC_A, TC_B, TC_C。那咱们能够生成相似如下的一个目录结构

- coverage
    - TC_A
        - jscoverage.json
    - TC_B
        - jscoverage.json
    - TC_C
        - jscoverage.json

这仅仅只须要在保存json_str时操做一下就好了,再也不赘述。

2. 执行测试样例

这一部分和平时如出一辙,仅仅须要注意要执行插桩后的网页代码文件,而不是插桩前的。

3. 合并代码覆盖率文件

在执行测试样例后,一切正常的话,就能获得相似在第一步中描述的那样的代码覆盖率文件的目录结构了:

- coverage
    - TC_A
        - jscoverage.json
    - TC_B
        - jscoverage.json
    - TC_C
        - jscoverage.json

示例指令: java -cp JSCover-all.jar jscover.report.Main --merge coverage/* D:/code_instrumented

  • coverage/*:也就是上述的目录结构的顶层目录的路径。
  • D:/code_instrumented:合并后的代码覆盖率文件的保存目录。咱们直接指定为插桩后的代码的所在目录,省去手动覆盖的麻烦。

注意,若是只有一个jscoverage.json的话,是没法使用上述指令进行合并的,毕竟只有一个,JSCover会报错。这时候请手动复制那惟一一个jscoverage.json,覆盖掉原来的jscoverage.json

4. 生成测试报告

把咱们在“预准备”时搞到的jscoverage.js翻出来,而后覆盖掉插桩后的代码所在目录下的jscoverage.js,再修改一下它,将jscoverage_isReport改成true:

var jscoverage_isReport = true;

最后打开jscoverage.html便可。可能会啥都没,这时候你打开浏览器的控制台看看报啥错吧,例如chrome的话,一般而言都是Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.,而后百度百度解决一下,或者换个浏览器再试试,或者本身改改jscoverage.html,都行。我是最后直接用Edge打开了。

最后应该是这样子的:

点开一个文件的话,就能看见哪些行被覆盖了,哪些没有:

不使用JSCover的Proxy模式的缘由

Proxy模式要方便不少,能够省去插桩网页代码的步骤。由于proxy模式下,jscover会截获全部浏览器的发包和收包,对于全部发过来的js文件,它都会自动进行插桩。

不过由于JSCover的Proxy模式须要修改浏览器代理。而咱们目前的本地测试环境使用了Fiddler做为浏览器代理,这两个代理冲突了,也就只能二选一,因此咱们没有使用JSCover的Proxy模式,不过要是你的项目不使用浏览器代理来搭建本地测试环境,能够考虑用用JSCover的proxy模式,真的方便不少。

相关文章
相关标签/搜索