Fix for Missing Code Coverage Files with Xcode

One of the things I’ve been working with lately is code coverage analysis using Xcode and CoverStory.

CoverStory Demo

While the experience is not as polished and complete as Visual Studio 2012, I’ve gotten most things working well enough.

One of the bigger hurdles I ran into was missing code coverage files when using iOS 6 to run unit tests. If I used iOS 5 or 5.1, the code coverage files were generated just fine. However, if I used iOS 6.0 or 6.1 the GCDA files specifically were not created.

I moved past this for a while but, as my code coverage increased, it became more important for me to test the iOS 6 specific code paths. I tried the Apple developer forums but had no luck, so I continued digging myself.

The first thing I noticed was that a brand new project created with Xcode did create GCDA files for iOS 6 and 6.1. This was promising as it meant that the problem was somewhere in my project.

After spending some time comparing project.pbxproj files (thanks to Marc Hoffman for pointing me in that direction), I was finally able to narrow the problem down to its cause. If you have an old enough iOS project, there’s a decent chance you’ll have one of the following flags specified in your Build Settings for Other Linker Flags:

  • -weak_library /usr/lib/libSystem.B.dylib
  • -weak-lSystem

Bad Setting

Among other things these flags allow apps that use features such as blocks and backgrounding to build for iOS 3. As it turns out, this setting also causes GCDA files not to be created when generating code coverage under iOS 6.

There are two options here:

  1. If the flag is not needed anymore you can remove it
  2. If the flag is necessary, you can create a new configuration for unit testing (this is also useful for setting up preprocessor macros)

In Xcode, select your project and select the Info tab. Click the plus button under Configurations and create a new configuration based on Debug.

Add Config
Dupe Debug

Name the new configuration Test.

Name Test

On the Build Settings tab, locate Other Linker Flags. Expand the setting so that each configuration is shown underneath it. For the Test configuration, remove the offending flag.

Clear Flag for Test

Now that the Test configuration is setup not to use the offending flag, you need to tell Xcode to use this configuration when testing. You can do this using schemes. Click on Product, then Scheme, then Edit Scheme (or alternatively press ⌘<). On the left of the scheme sheet select the Test action.

Scheme Test Action

On the Info tab, change Build Configuration from Debug to Test.

Select Test Config

With these settings in place the proper code coverage files should now be generated when running unit tests with iOS 6. Note that the path to the code coverage files will change, as the path is based on the configuration name which is now Test.

CoverStory

This took a while to figure out and hopefully Apple will fix the issue (I’ve submitted a bug report). In the meantime hopefully this post helps others who run into this issue!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s