测试异常时,XCode上的代码覆盖率不正确

时间:2012-03-15 12:53:43

标签: objective-c ios xcode unit-testing code-coverage

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

有什么想法吗?

2 个答案:

答案 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'只是一个示例宏。它与其他宏相同。 '#'只是一个有效的字符(对于一些预编译器),它使它看起来很特别。