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
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:
- If the flag is not needed anymore you can remove it
- 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.
Name the new configuration 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.
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.
On the Info tab, change Build Configuration from Debug to Test.
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.
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!