查找可覆盖的内容

这是"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::UtilsMoarVM::Bytecode模块中创建了一组不错的功能,以及新的Code::Coverable模块。若喜欢可进行小额赞助。
阅读 7
0 条评论