所有测试失败却近100%行覆盖率,如何仅统计通过测试覆盖的代码行?
现有代码与问题现象
被测文件 main.cpp
带覆盖率统计标记的源码如下:
Line data Source code 1 : #include<iostream> 2 : using namespace std; 3 3 : int GreatestOfThree(int a,int b,int c){ 4 3 : if((a>b) && (a>c)){ // a同时大于b、c的分支 5 1 : return a; 6 : } 7 2 : else if(b>c){ // b大于c的分支 8 1 : return b; 9 : } 10 : else{ 11 1 : return c; 12 : } 13 : return 0; 14 : }
测试文件 main_test.cpp
基于GTest编写的测试代码如下:
#include "gtest/gtest.h" #include "main.cpp" TEST(GreaterTest,AisGreater){ EXPECT_EQ(1,GreatestOfThree(3,1,2)); }; TEST(GreaterTest,BisGreater){ EXPECT_EQ(1,GreatestOfThree(1,3,2)); }; TEST(GreaterTest,CisGreater){ EXPECT_EQ(2,GreatestOfThree(1,2,3)); }; int main(int argc,char**argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
从当前覆盖率统计结果看,所有测试用例全部执行失败,但代码行覆盖率依然达到100%。这个结果本身符合常规覆盖率的统计逻辑:覆盖率只统计代码行是否被执行,不关心执行后测试断言是否通过。
现在需要调整统计逻辑,让覆盖率结果只包含通过的测试用例执行到的代码行,可以通过以下方式实现:
实现方法
- 拆分测试执行流程,单独统计通过用例的覆盖率
第一步先全量执行所有测试用例,拿到所有执行通过的用例名称列表;第二步用GTest自带的过滤参数--gtest_filter=指定只运行这批通过的用例,同时开启覆盖率采集,此时生成的覆盖率报告就完全来自通过用例的执行轨迹,不会包含失败用例执行过的代码。 - 使用支持按测试结果过滤覆盖率的工具
部分覆盖率工具原生支持关联测试执行结果,统计时自动剔除失败用例产生的执行记录。比如LLVM工具链下的llvm-cov可以配合测试执行标记,过滤断言失败后的执行轨迹;不少工程化的覆盖率平台也自带「仅统计通过用例覆盖率」的配置项,开启后不需要手动拆分用例执行,就能直接得到符合要求的统计结果。
注意:把
EXPECT_*断言替换成ASSERT_*无法达到目标。ASSERT_*只会在断言失败时终止当前用例的后续执行,但失败前已经跑过的代码依然会被计入覆盖率,没有改变统计口径。
内容的提问来源于stack exchange,提问作者jacky
相关产品推荐
相关产品推荐

