14

如何使用 Xcode 5 和 iOS7 生成代码覆盖率?

在升级之前,我的代码覆盖率很好。现在我看不到任何正在生成的 *.gcda 文件。

我正在使用的命令行是:

xcodebuild -workspace ${module.name}.xcworkspace test -scheme ${module.name} -destination OS=${module.sdk.version},name=iPad -configuration Debug

与 AppCode 一起使用

  • 当我通过 AppCode 执行测试时,我可以看到在 ~/Library/Caches/appCode20/DerivedData 中生成了 *.gcda 文件。. . 我需要它来为我的持续集成构建工作。

从 Xcode IDE 工作

  • 也适用于 Xcode IDE。. . 是否有会产生覆盖的命令行,或者这是一个 Xcode 错误?
4

6 回答 6

15

以下是一个修复SenTestKit- 只需将此类添加到您的 Tests 目标。应该可以做类似的事情XCTest

@interface VATestObserver : SenTestLog

@end

static id mainSuite = nil;

@implementation VATestObserver

+ (void)initialize {
    [[NSUserDefaults standardUserDefaults] setValue:@"VATestObserver" forKey:SenTestObserverClassKey];

    [super initialize];
}

+ (void)testSuiteDidStart:(NSNotification*)notification {
    [super testSuiteDidStart:notification];

    SenTestSuiteRun* suite = notification.object;

    if (mainSuite == nil) {
        mainSuite = suite;
    }
}

+ (void)testSuiteDidStop:(NSNotification*)notification {
    [super testSuiteDidStop:notification];

    SenTestSuiteRun* suite = notification.object;

    if (mainSuite == suite) {
        UIApplication* application = [UIApplication sharedApplication];
        [application.delegate applicationWillTerminate:application];
    }
}

并添加

extern void __gcov_flush(void);

- (void)applicationWillTerminate:(UIApplication*)application {
    __gcov_flush();
}

为什么这行得通?

测试和被测试的应用程序是分开编译的。测试实际上是注入到正在运行的应用程序中,因此__gcov_flush()必须在应用程序内部而不是在测试内部调用。

观察者的小魔法只使我们能够检查测试何时结束,我们触发__gcov_flush()在应用程序内部被调用。

于 2013-09-24T09:17:38.253 回答
2

(这不是答案,而是一种解决方法......我仍然对更好的解决方案非常感兴趣)

使用 iOS 6.1 模拟器

如果您将 iOS 6.1 或更早版本作为部署目标,则可以使用 6.1 模拟器。

  • 通过首选项/下载安装 iOS6.1 模拟器
  • 使用以下命令行:

    xcodebuild -workspace ${module.name}.xcworkspace test -scheme ${module.name} -destination OS=6.1,name=iPad -configuration 调试

于 2013-08-23T05:57:55.607 回答
1

我们发现我们必须添加一些代码才能让 gcda 文件从系统中刷新。

代码添加是添加 extern void __gcov_flush();到文件顶部,然后__gcov_flush();在整个测试套件退出之前调用。

完整的解释在这里:http ://www.bubblefoundry.com/blog/2013/09/generating-ios-code-coverage-reports/

于 2013-10-10T15:33:06.350 回答
1

有了这里的信息,我能够制作出我能想到的侵入性最小的版本。只需添加到您的单元测试并正常运行测试即可。ZZZ 确保它是最后运行的测试套件。

我必须确保将 GCC_GENERATE_TEST_COVERAGE_FILES 和 GCC_GENERATE_TEST_COVERAGE_FILES 编译器标志也添加到我的测试单元目标中以获取覆盖范围。

//
//  Created by Michael May
//

#import <SenTestingKit/SenTestingKit.h>

@interface ZZZCodeCoverageFixForUnitTests : SenTestCase

@end

@implementation ZZZCodeCoverageFixForUnitTests

// This must run last

extern void __gcov_flush();

-(void)testThatIsntReallyATest
{
    NSLog(@"FLUSHING GCOV FILES");

    __gcov_flush();
}


@end

编辑,或 Jasper 的另一种方法:

我将 VATestObserver 从另一个答案中剥离出来:

@interface VATestObserver : SenTestLog
@end

@implementation VATestObserver

extern void __gcov_flush(void);

- (void)applicationWillTerminate:(UIApplication*)application
{
   __gcov_flush();
  [super applicationWillTerminate:application];
}

@end
于 2013-12-18T11:21:55.163 回答
0

这里还有一些文档:

https://code.google.com/p/coverstory/wiki/UsingCoverstory

和一些要使用的源代码:

https://code.google.com/p/google-toolbox-for-mac/source/browse/#svn%2Ftrunk%2FUnitTesting

您需要 GTMCodeCoverageApp.h/.m 和 GTMCodeCoverageTestsXC.h/.m 或 GTMCodeCoverageTestsST.h/.m,具体取决于您使用的是 XCTest 还是 SenTest。

于 2013-12-18T05:03:32.230 回答
0

更新:新接受的答案

在某些情况下,覆盖范围刷新需要在应用程序本身内完成。此问题中的解决方案大纲提供了详细信息。

于 2014-01-11T06:19:54.327 回答