Retired Document
Important: This document may not represent best practices for current development. Links to downloads and other resources may no longer be valid.
Configuring Xcode for Code Coverage
Q: How can I configure my Xcode project to work with the GCOV code coverage tool?
A: Code Coverage allows you to identify what parts of your source code were executed during a test. Xcode supports code coverage testing with GCOV
for iOS and OS X applications. When set up for GCOV use, Xcode generates .gcno files when compiling your app and .gcda data files when your app exits. The following steps show you how to set up your project in Xcode to generate these GCOV files.
Create a separate build configuration named
GCov_Build
.To keep your code coverage build separate from your Debug and Release, make a new build configuration named
GCov_Build
by duplicating Debug. See Add a Build Configuration for more information about duplicating a build configuration.Configure your application to work with
GCOV
at the project-level.Navigate to the Build Settings pane of your project, then update your settings for
GCov_Build
as follows:Make sure that
Compiler for C/C++/Objective-C
is set to a version ofApple LLVM Compiler
.Make sure that
Generate Debug Symbols
is set toYES
.Set
Generate Test Coverage Files
toYES
.Set
Instrument Program Flow
toYES
.
Compile your project to generate .gcno files.
First set up your scheme to use
GCov_Build
when building and running your application as shown in Figure 2, then select Product > Build to compile your project. The compiler will create .gcno files in your build folder. Use the Projects organizer in Xcode to navigate to your application derived data's folder, then search within the Build/Intermediates directory for your .gcno files.
Run your application to generate .gcda files.
Select Product > run to run your application. As your application runs, Xcode collects data about what parts of your code are used. It is important to give inputs to the application that will exercise the code you want to test. Xcode will write out the coverage data to .gcda files when your application exits.
OS X developers must use their application's Quit menu item to completely exit it.
iOS applications do not exit. Therefore, iOS developers should temporarily modify their application to force coverage data to be written out to .gcda files. Use any of the following methods to do so:
Set the
UIApplicationExitsOnSuspend
key to YES in your Info.plist file and send your running application to the background by pressing the home button.Add a call to __gcov_flush() in your application to force the coverage data to be written out to .gcda files. For instance, you may want to insert a call to __gcov_flush() in
applicationDidEnterBackground:
as shown in Listing 1 to write out coverage information every time the home button is pressed.Listing 1 Using __gcov_flush() to force coverage data to be written out to .gcda files
#import "AppDelegate.h"
#include <stdio.h>
extern void __gcov_flush();
@implementation AppDelegate
- (void)applicationDidEnterBackground:(UIApplication *)application
{
__gcov_flush();
}
…..
@end
Retrieve .gcda files.
The .gcda files are usually placed in the same build directory containing your .gcno files. However, if your application is sandboxed, then you may not be able to write to this build directory. You can workaround this issue by using the
GCOV_PREFIX_STRIP
andGCOV_PREFIX
environment variables to change the location of your .gcda files.GCOV_PREFIX_STRIP
specifies the number of path components to be removed from the default build directory andGCOV_PREFIX
specifies a path to substitute in their place.For instance, if your build directory is located at “/Users/Me/Library/Developer/Xcode/DerivedData/<application>/build” and you want to write it to your app's Documents directory, then first query the actual path of your app's sandbox, next assign this path to
GCOV_PREFIX
using the setenv() function as follows:NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
setenv("GCOV_PREFIX", [documentsDirectory cStringUsingEncoding:NSUTF8StringEncoding], 1);
and finally set
GCOV_PREFIX_STRIP
to 7 to strip your app's full path as shown in Figure 3.
After that the .gcda files are written to your app sandbox, copy them into the same directory containing your .gcno files. iOS developers should follow steps described in Copying App Data from a Container on an iOS Device to retrieve .gcda files from their devices. OS X developers should navigate to their app’s sandbox container (~/Library/Containers/<bundle_id>
) on their Mac to retrieve these files.
Use GCOV to view your results.
Navigate to the directory containing both your .gcno and .gcda files in the Terminal application, then run the gcov tool on each source file for which you want to see the coverage data as seen in Listing 2.
Listing 2 Running gcov on a source file
$ cd <path/to/directory with .gcda and .gcno files>
$ls
AppDelegate.d MyApplication_dependency_info.dat main.d
AppDelegate.dia ViewController.d main.dia
AppDelegate.gcda ViewController.dia main.gcda
AppDelegate.gcno ViewController.gcda main.gcno
AppDelegate.o ViewController.gcno main.o
MyApplication.LinkFileList ViewController.o
$ xcrun gcov </path/to>/MyApplication/MyApplication/ViewController.m
File '</path/to>/MyApplication/MyApplication/ViewController.m'
Lines executed:69.23% of 13
</path/to>/MyApplication/MyApplication.m:creating 'ViewController.m.gcov'
$ cat ViewController.m.gcov
-: 0:Source:</path/to>/MyApplication/MyApplication/ViewController.m
-: 0:Graph:ViewController.gcno
-: 0:Data:ViewController.gcda
-: 0:Runs:0
-: 0:Programs:0
-: 1:
-: 2:#import "ViewController.h"
-: 3:
-: 4:@interface ViewController ()
1: 5:@property (strong) NSMutableArray *menuArray;
-: 6:@end
-: 7:
#####: 8:@implementation ViewController
-: 9:
-: 10:
1: 11:- (void)viewDidLoad
-: 12:{
1: 13: [super viewDidLoad];
1: 14: [self loadData];
1: 15:}
-: 16:
1: 17:-(void)loadData
-: 18:{
1: 19: NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Menu" ofType:@"plist"];
1: 20: self.menuArray = [NSMutableArray arrayWithContentsOfFile:plistPath];
-: 21:
1: 22:}
-: 23:
-: 24:
#####: 25:- (void)didReceiveMemoryWarning
-: 26:{
#####: 27: [super didReceiveMemoryWarning];
-: 28: // Dispose of any resources that can be recreated.
#####: 29:}
-: 30:
-: 31:@end
Document Revision History
Date | Notes |
---|---|
2014-03-12 | Updated for Xcode 5. Was previously titled as "Using GCOV from Xcode." |
2007-02-23 | New document that illustrates how to set up Xcode for code coverage. |
Copyright © 2014 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2014-03-12