11月阅读周·编写可测试的JavaScript代码:代码覆盖率之持久化覆盖率信息篇

举报
叶一一 发表于 2024/11/25 09:07:56 2024/11/25
【摘要】 背景去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。没有计划的阅读,收效甚微。新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一本书籍。这个“玩法”虽然常见且板正,但是有效,已经坚持阅读十个月。已读完书籍:《架构简洁之道》、《深入浅出的Node.js》、《你不知道的JavaScript(上卷)》、《你不知道的JavaScri...

背景

去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。

没有计划的阅读,收效甚微。

新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一本书籍。

这个“玩法”虽然常见且板正,但是有效,已经坚持阅读十个月。

已读完书籍《架构简洁之道》、《深入浅出的Node.js》、《你不知道的JavaScript(上卷)》、《你不知道的JavaScript(中卷)》、《你不知道的JavaScript(下卷)》、《数据结构与算法JavaScript描述》、《WebKit技术内幕》、《前端架构:从入门到微前端》、《秒懂算法:用常识解读数据结构与算法》、《JavaScript权威指南》、《JavaScript异步编程设计快速响应的网络应用》

当前阅读周书籍编写可测试的JavaScript代码

持久化覆盖率信息

持久化覆盖率信息,也就是将信息从浏览器的内存中取出来并保存在本地磁盘里。这里的“本地”是表示运行测试文件的Web服务器。每个页面在刷新时,页面上所加载的JavaScript的覆盖率信息都会被清除,因此在刷新页面之前,必须要把覆盖率信息保存到磁盘的某个地方,否则它将永远消失。

单元测试

在学会本地保存覆盖率信息之前,需要阅读本节内容。对于单元测试,持久化覆盖率信息和持久化单元测试结果有同样的问题——也就是说,需要向服务器发送POST或Ajax请求进行持久化。通常,不用Web服务器就可以运行单元测试:将HTML文件加载到浏览器中,然后运行测试即可。然而,要持久化测试结果和覆盖率信息的话,需要Web服务器的帮助才行。

YUI Test提供了一些辅助钩子,可以以各种格式获取该信息:

var testRunner = Y.Test.Runner;
testRunner.subscribe(testRunner.TEST_SUITE_COMPLETE_EVENT, getResults);
testRunner.run();
function getResults(data) {
  var reporter = new Y.Test.Reporter('http://www.yourserver.com/path/to/target', Y.Test.Format.JUnitXML);
  reporter.report(results);
}

在每一个测试套件的底部使用上述代码片段,元测试报告就会以JUnit XML格式发送到服务器上,该格式可以被Hudson/Jenkins和许多其他的构建工具所识别。YUI还提供了XML、JSON以及TAP格式的输出。对于XML和JSON格式,我们需要自己进行处理,但是对于TAP格式,Perl语言里有大量的工具可以识别它。

传递测试结果的时候,还可以顺便捎回覆盖率结果:

function getResults(data) {
  // Use JUnitXML format for unit test results
  var reporter = new Y.Test.reporter('http://www.yourserver.com/path/to/target', Y.Test.Format.JUnitXML);
  // Toss in coverage results
  reporter.addField('coverageResults', Y.Test.Runner.getCoverage(Y.Coverage.Format.JSON));
  // Ship it
  reporter.report(results);
}

reporter对象上的addField方法,允许向服务器回传任何数据。在本例中,我们回传的是覆盖率结果,将其编码为JSON,并和单元测试结果一起传递。注意,JSON是覆盖率信息的唯一智能输出形式,它是YUI覆盖率报表工具所期望的格式。

上述代码的最终结果是,向服务器发送携带results和coverageResults参数的POST请求。至此,这两块数据就可以保存到本地文件系统中了。

集成测试

使用Selenium对集成测试的覆盖率信息进行持久化遵循类似的模式。在运行Selenium测试之后,以及导航离开当前页面之前,必须进行覆盖率信息的收集并将其传递到服务器。Selenium提供的tearDown和after钩子可用于存放这些代码,以确保可以捕获覆盖率信息。

使用Selenium时,最好的办法是使用全局变量_yuitest_coverage,该变量保存了所有的覆盖率信息。使用Selenium1的示例代码如下:

String coverage = selenium.getEval('JSON.stringify(window._yuitest_coverage)');

使用Selenium2/WebDriver的示例代码如下:

String coverage = (String)((JavaScriptExecutor) driver).executeScript('return JSON.stringify(window._yuitest_coverage)');

然后简单地将coverage字符串输出到文件中,理想情况下,在测试之后会将其命名为像testClick.coverage.json这样的名称。

要记住,如果应用程序包含iframes框架,对iframe框架页面代码所生成的覆盖率信息不会被保存到顶级_yuitest_coverage变量。在顶级主窗口收集到代码覆盖率信息之后,需要告知Selenium1,要使用类似如下代码:

selenium.SelectFrame('src=foo.html');

使用上述代码,可以获取_yuitest_coverage变量的内容。

总结

可以使用任何Selenium选择符,选择要从中提取代码覆盖率的iframe。

确保要将每个iframe的_yuitest_coverage数据聚合到总覆盖率报告。


作者介绍
非职业「传道授业解惑」的开发者叶一一。
《趣学前端》、《CSS畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏️ | 留言📝

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。