我正在为iOS创建一个静态库,并且正在尝试为其单元测试获取代码覆盖率数据。我正在使用CoverStory来可视化生成的代码覆盖文件。
我获得了大多数测试的正确信息。
但是,任何验证应该抛出异常的测试都没有被标记为已测试。
例如方法
- (void)shouldThrow:(BOOL)throw {
if (throw)
@throw [NSException exception...];
NSLog(@"not thrown");
}
测试
- (void)testShouldThrow {
STAssertThrows( [myObject shouldThrow:YES], @"Should have thrown an exception");
STAssertNoThrow( [myObject shouldThrow:NO], @"Should not have thrown an exception");
}
通过所有测试(即正确抛出异常)。但是,代码覆盖率不会显示为100% - @throw
on的行未被标记为已测试。
有什么想法吗?
答案 0 :(得分:3)
@throw上的行未完成(因为抛出了异常),因此它不会被标记为已覆盖。您可以提交错误,但这可能很难修复。如果它是分支语句中的单行,则可能很难判断它是否已经过测试,但如果它之前有行已经执行过,那么你只需要假设它也是如此。
糟糕的是你永远无法达到100%。
答案 1 :(得分:0)
更糟糕的问题是,在相同条件块中@throw之前的行的计数器似乎也不是coveralbe。因此,在@throw作为标记之前简化编写代码不会有助于解决问题。
然而,我发现包含变量的条件(“if(YES)”,“if(1 == 1)”不在案例中)始终是可以考虑的。因此,我们可以做的一件棘手的事情是首先定义一个简单的条件变量,然后在@throw之前添加一个包含该变量的条件测试。
static BOOL __trivialYES = YES; //for cover @throw, and never use 'const'
然后
if(__trivialYES) @throw ...;
这应该有助于解决问题,为方便起见,您可以定义自己的宏来执行这些操作。
#define #throw if (__trivialYES)
然后是throw语句:
#throw ...;
这可能会使覆盖测试更好。
PS:'#throw'只是一个示例宏。它与其他宏相同。 '#'只是一个有效的字符(对于一些预编译器),它使它看起来很特别。