在测试异常时,使用XCode会出现错误的代码覆盖率结果

6
我正在为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 的行没有被标记为已测试。

有什么想法吗?

2个回答

3

@throw所在的那一行代码没有被覆盖到(因为异常被抛出了),所以它没有被标记为已覆盖。你可以提交一个错误报告,但是对于他们来说,修复这个问题可能会非常困难。如果它在分支语句中是单独的一行代码,那么很难确定是否进行了测试,但是如果前面有执行过的代码行,那么你就只能假设该代码行也已经被测试了。

不好的消息是,你永远无法达到100%。


这正是我担心的 :( (我已在该行设置了断点,所以我知道正在进行测试,但能够自动化该测试会很好!) - deanWombourne

0

更糟糕的问题是,在相同条件块中的@throw之前的行计数器似乎也无法覆盖。因此,简单地在@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'只是一个示例宏。它与其他宏相同。'#'只是一个有效字符(对于某些预编译器),使其看起来特殊。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接