摘要:在互联网时代,随着业务增长,前端需求激增,软件产品功能迭代加快,前端代码质量越来越受到重视,如何在有限时间内保证前端代码质量。就此问题将介绍前端JavaScript代码覆盖率工具Istanbul,分析lstanbul的四种代码覆盖率测量指标,并通过具体实例阐述lstanbul在前端单元测试中的应用。应用结果表明lstanbul能快速定位未被测试覆盖的代码,以此完善测试用例,提升软件产品质量。
关键词:软件测试;单元测试;代码覆盖率;lstanbul
中图分类号:TP319 文献标识码:A
文章编号:1009-3044(2020)08-0059-03
1 背景
软件测试是软件工程中重要一环,用于验证产品代码按照预期工作,是保障软件产品质量的重要手段。其中,单元测试是对软件最小执行单元的测试活动,能尽早发现软件缺陷,是软件测试的基础。以往单元测试只针对服务器端语言,随着web业务的发展,前端代码日趋复杂,使得对JavaScript进行单元测试尤为重要。
代码覆盖率是软件测试的度量指标,反映测试用例对被测软件代码的覆盖程度,量化测试工作。通过代码覆盖率测试能及时确认未被测试用例执行的代码,提前发现代码逻辑分支不合理之处,提升产品代码的可靠性和稳定性。
2 Istanbul介绍
Istanbul是前端JavaScript常用的代码覆盖率测试工具,以土耳其名城伊斯坦布尔命名,它可以静态直接统计JavaScript文件,也可以结合测试框架在单元测试中对JavaScript文件进行覆盖率统计。
Istanbul提供了四种代码覆盖率测量指标。语句覆盖率(statement coverage)统计代码中所有可执行语句的执行率。分支覆盖率(branch coverage)统计代码中所有分支的执行率,即判断的取真分支和取假分支是否都被执行了。函数覆盖率(func-tion coverage)统计代码中所有函数的被调用率。行覆盖率(linecoverage)统计代码中所有有效代码行的执行率,其与语句覆盖率类似,在代码规范的情况下,行覆盖率和语句覆盖率应该是一致的。以上四种测量指标是Istanbul的输出结果,每个指标均列出了覆盖的数量和比例,其中分支覆盖率能深入发现代码逻辑中的缺陷,是四种覆盖中最强的覆盖。
运行npm install istanbul-g将Istanbul安装为全局模塊,安装成功后运行istanbul help可查看其帮助信息。
3 Istanbul收集覆盖率信息
下面来看一个使用Istanbul收集覆盖率信息的简单实例,测试文件simple.js见图1。
运行istanbul cover simple.js,得到4个覆盖率测量指标结果见图2。
以上结果显示,simple.js有4个语句,执行了3个,因此语句覆盖率为75%;有2个分支,执行了1个,因此分支覆盖率为50%;有0个函数,调用了0个,因此函数覆盖率为100%;有4行代码,执行了3行,因此行覆盖率为75%。
Istanbul会在coverage/lcov-report目录下生成HTML报告,可直观查看到覆盖率详细信息,定位没有被覆盖到的代码。打开coverage/lcov-report/index.html文件,页面中展示各文件夹下文件的代码覆盖率见图3。
点击相应文件夹,可见该文件的代码覆盖率统计情况见图4。
绿色部分表示该行代码被完整执行,红色部分表示该行代码没有被执行,即未覆盖a= false的情况。
4 Istanbul代码覆盖率标准检查
Istanbul除了收集覆盖率信息,还可根据测试要求设定满意的代码覆盖率标准,来检查覆盖率是否达到设定的指标,如果未达标则打印错误信息。
4.1 百分比标准
对测试文件simple.js运行istanbul check-coverage -state-ment 85
该命令设置语句覆盖率标准为85%,运行结果见图6。
因测试文件simple.js的语句覆盖率为75%,未达到设定的语句覆盖率标准85%,故报错提示语句覆盖率未达标。
4.2 绝对值标准
对测试文件simple.JS运行istanbul check-coverage -branch一1
该命令设置允许有1个分支未被覆盖,运行结果见图7。
因测试文件simple.js有1个分支未被执行,符合设定的分支覆盖率标准,故通过了覆盖率测试,运行结果无报错。
4.3 百分比标准和绝对值标准结合使用
百分比标准和绝对值标准可结合使用,对测试文件simple.js运行istanbul check-coverage -statement 85 -branch—l -functionl00 -line一1
该命令共设置了4个覆盖率标准:语句覆盖率标准为85%,允许1个分支未被执行,函数覆盖率标准为100%,允许1行代码未被执行。这4个标准间是“与”的关系,即只要1个标准未达标,则报错。运行结果见图8。
因测试文件simple.js语句覆盖率为75%,未达到设定的语句覆盖率标准85%,故报错提示语句覆盖率未达标。
5 Istanbul结合Mocha测试框架
测试框架提供脚本运行的环境,是运行测试的工具。实际应用中,Istanbul总是与测试框架结合使用,Mocha是一款流行的JavaScript单元测试框架,适用于浏览器和Node.js环境。Mo-cha用describe块和it块来进行测试用例分组,测试脚本中包含一个或多个describe块,每个describe块包含一个或多个it块。describe为测试套件testsuite,表示一组相关的测试,该函数包含两个参数,第一个参数是测试套件名称(在测试报告中显示的描述),第二个参数是实际执行的函数。it块为单个测试用例testcase,表示一个独立的测试,它是真正执行的部分,该函数包含两个参数,第一个参数是测试用例名称(在测试报告中显示的描述),第二个参数是实际执行的函数。运行npm install mo-cha—g将Mocha安装为全局模块,安装成功后运行mocha -help可查看其帮助信息。
断言可判断源代码的执行结果与预期结果是否一致,若不一致则抛出错误。Mocha不提供断言,可搭配Chai使用。Chai是流行的JavaScript测试断言库,适用于Node.JS和浏览器的行为驱动测试以及测试驱动测试,能搭配测试框架一起使用。运行npm install chai—g将Chai安装为全局模块。
以下为判断输入是否为数字的脚本文件。定义srtP为正则表达式,使用test0方法,将输入值与srtP进行匹配,若不匹配说明输入包含非数字,返回false。若匹配,说明输入均为数字,返回true。脚本文件my.Js见图9。
修改my.Js文件,把模块中希望被外界访问的内容定义到exports对象中,以便在测试脚本中使用(require引用该模块),修改后文件isNum.js见图10。
编写单元测试脚本testNum.js见图11,测试用例包含1个测试单元,若输人数字4则得到true。将测试脚本放在test目录下。
运行istanbul cover node—global/ node—modules/ mocha/ bin/_mocha,进行代码覆盖率检查,结果见图12。结果显示1个测试用例成功通过,函数覆盖率为100%,但语句覆盖率、分支覆盖率、行覆盖率未达到100%。
查看coverage/lcov-report下HTML報告见图13,可知num为false的分支未覆盖,需添加新的测试用例来覆盖缺失的测试场景。
完善测试用例,测试脚本testNum.js见图14,测试用例分为2个测试单元,若输入数字4则得到true,若输入字母d则得到false。
再运行istanbul cover node_global/node_modules/mocha/bin/_mocha进行代码覆盖率检查,结果见图15。结果显示2个测试用例都成功通过了,语句覆盖率、分支覆盖率、函数覆盖率、行覆盖率均为100%。
查看coverage/lcov-report下HTML报告见图16.显示已覆盖num为false的分支。
6 结束语
代码覆盖率测试能发现未被覆盖的代码,这部分代码出现不可预知行为的机率较大,有存在问题的风险,影响代码质量,应引起足够重视。Istanbul能从语句、分支、函数、行四种测量维度提供覆盖率信息,帮助迅速定位未被执行的代码,指导有针对性地补充测试用例,尽可能地发现更多潜在代码缺陷,提高代码质量,为用户提供稳定可靠的软件产品。
参考文献:
[1]陈卫俊,赵璨,周磊,互联网单元测试及实践[M].北京:电子工业出版社,2008.
[2]王飞,向螈.C++Test在核电数据库软件单元测试中的应用研究[J].电脑知识与技术,2019,15(12):1-3.
[3]褚悦,代码覆盖率驱动的测试用例管理系统的设计与实现[D].西安:西安电子科技大学,2017.
[4]尤嘉.Node.js进阶之路[Ml.北京:清华大学出版社,2017.
【通联编辑:谢媛媛】
收稿日期:2020-01-25
基金项目:2017年国家重点研发计划(项目编号:2017YFB0802300)
作者简介:史蓓娜(1986-),女,江苏常州人,研究实习员,学士,研究方向为计算机应用。