Xcode5代码覆盖率(来自CI构建的cmd-line)

时间:2013-08-23 04:21:39

标签: objective-c code-coverage xcode5 lcov

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

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

我正在使用的cmd-line是:

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。 。 。是否有一个cmd-line会产生覆盖,或者这是一个Xcode错误?

6 个答案:

答案 0 :(得分:15)

以下是SenTestKit的修补程序 - 只需将此类添加到测试目标即可。类似的事情应该与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()

答案 1 :(得分:2)

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

使用iOS 6.1模拟器

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

  • 通过偏好设置/下载
  • 安装iOS6.1模拟器
  • 使用以下cmd-line:

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

答案 2 :(得分:1)

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

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

完整说明如下:http://www.bubblefoundry.com/blog/2013/09/generating-ios-code-coverage-reports/

答案 3 :(得分: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

答案 4 :(得分: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。

答案 5 :(得分:0)

更新:新接受的答案

在某些情况下,需要在应用程序内部完成覆盖刷新。解决方案的大纲in this question提供了详细信息。