这是"Towards more coverage"博客系列的第 2 部分。
- Code::Coverable:将寻找代码行的逻辑放在单独的分发中,名为
Code::Coverable
,最初考虑用 RakuAST,但未成熟,后发现 MoarVM 字节码文件知道哪些源代码行可执行,为此创建了MoarVM::Bytecode
分发来理解字节码文件结构,添加了coverables
方法返回可执行源代码的行号,其返回值为Pair
,键为#line
指令指定的内容,值为行号。 - A little complication: what:Rakudo 中有
#line
指令,可改变源代码中的行号和文件名,MoarVM::Bytecode.coverables
方法需返回键为"覆盖键"的值为行号的Pair
,多个Pair
表示不同情况。 - Another complication: where:可从 MoarVM 字节码文件获取可覆盖信息,通过
CompUnit::Repository::
模块内部信息找到字节码文件,使用Identity::Utils
分发的bytecode-io
子例程获取,例如测试String::Utils
时可得到其覆盖的行号等信息,"site#sources/2C5249974A64FCC88F16184290DB8B43D6DBE5FA (String::Utils)"为"覆盖键"。 - Final complication: when:字节码文件中的可覆盖信息由语法看到的源代码行确定,静态优化器会更改 AST 导致
else
语句等在执行时几乎不被覆盖,需通过源代码开发启发式规则识别可能不被覆盖的行,如以else
等开头的行,对于难以创建启发式规则的情况,可添加"line ends with # UNCOVERABLE"标记。 - Wrap it up:将所有内容封装在
coverables
子例程中,生成Code::Coverable
对象,包含目标、键、行号列表、源文件等属性。 - Conclusion:这是为 Raku 模块获取测试覆盖的最困难部分,涉及很多工作,但最终在
Identity::Utils
和MoarVM::Bytecode
模块中创建了一组不错的功能,以及新的Code::Coverable
模块。若喜欢可进行小额赞助。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。