iOS增量代码覆盖率可以用来评估开发的自测质量,以及多轮测试后的测试质量。这里会解析iOS代码覆盖率的收集,上报,合并这些环节当中涉及到的技术点。
GCDAProfiling
clang编译参数 GCC_GENERATE_TEST_COVERAGE_FILES 以及 GCC_INSTRUMENT_PROGRAM_FLOW_ARCS 产生的相关函数是可以由上层进行替换的,这里可以在项目当中接入 GCDAProfiling 源码进行相关修正。
https://github.com/llvm-mirror/compiler-rt/tree/master/lib/profile
- 修正 cannot merge previous GCDA file 等错误
每次调用 __gcov_flush
的时候,都会重新check一下对应的 gcda文件(比如: main.m -> main.gcda,AppDelegate.m -> AppDelegate.gcda) 是否有结构变动。默认情况下如果 gcda文件 产生了变动,那么会直接报错,无法进行 代码覆盖率信息 的写入,因此如果出现这种错误,这里可以选择将这个 gcda文件 标记删除,详见 _bs_mark_need_remove
。
1 | void llvm_gcda_emit_arcs(uint32_t num_counters, uint64_t *counters) { |
在 llvm_gcda_end_file 当中处理需要删除的 gcda文件,逻辑如下图所示。
1 | void llvm_gcda_end_file() { |
gcda文件
可以通过 GCOV_PREFIX 以及 GCOV_PREFIX_STRIP 指定 gcda文件 的生成路径,比如放到 Caches目录。
1 | NSString *codeCoverageDataDir = [BSCodeCoverage codeCoverageDataDir]; |
如果需要在真机上收集gcda文件,可以考虑搭建一个简易的文件服务器去存储客户端上报的gcda文件。
gcno文件
编译器生成的描述 源文件 结构的文件,需要根据项目target,arch信息在DerivedData目录下面去查找。
1 | 如: Demo这个target下面的 main.m 文件对应的 真机 gcno路径 |
Coverage.info
lcov可以通过gcda以及gcno文件生成Coverage.info这个中间产物,Coverage.info易于阅读以及解析,可以用来做后续的问题排查以及html报告生成。
1 | Coverage.info文件内容: |