Code Coverage and fopen$UNIX2003 Problems
A couple of readers have reported they were unable to get code coverage on LLVM working properly after following my description in Code Coverage with Xcode 4.2. The problem would manifest itself in a somewhat cryptic error during execution of the unit tests:
Detected an attempt to call a symbol in system libraries that is not present on the iPhone:
fopen$UNIX2003 called from function llvm_gcda_start_file
The discussions have been lively with various suggestions on tweaking compiler flags, inclusion of libraries, missing files in target, etc. It wasn’t until I ran into the problem myself – even after following my own advice step by step – that I decided to dig deeper into the cause of the problem. Fortunately it turned out that the solution had already been described in the discussions and it’s a rather simple one too.
(more…)
Code Coverage with Xcode 4.2
This tutorial is just a small follow-up on one of my earlier posts about how to set up code coverage in Xcode.
With the release of Xcode 4.2 code coverage is finally supported using Clang / LLVM. Opposed to what I described in the earlier post you no longer need to force the use of GCC to get code coverage metrics in your unit tests. Since Apple has also decided to drop support for GCC you are more or less forced to switch to Clang / LLVM anyway.
In Xcode 4.2 it’s fairly simple to set up code coverage. If you have defined a custom build setting or build rule that enforces GCC 4.2 you will need to remove those first.
Next you’ll need to enable the two build settings “Generate Test Coverage Files” and “Instrument Program Flow” as shown below:
Using NSURLProtocol for Injecting Test Data
In earlier posts I described methods for unit testing asynchronous network access and how to use mock objects for further control of the scope of these unit tests. In this tutorial I’ll present an alternative way of providing reliable test data by customizing the NSURLProtocol class in order to deliver static test data.
A few months ago Gowalla made the networking code used in their iPhone client available as open source on GitHub. The AFNetworking library as it is called is a “A delightful iOS networking library with NSOperations and block-based callbacks“. One of the things that first caught my eye was the built-in support for accessing JSON based services with just a few lines of code.
The simplicity of the AFNetworking interface inspired me to give it a test spin and write ILBitly which provides an Objective C based wrapper for the Bitly url shortening service. It’s very easy to use AFNetworking and especially the JSON support that is accessed using a single class methods. Unfortunately this simplicity also makes it quite difficult to write self-contained unit and mock tests using OCMock. This is mainly because OCMock doesn’t support mocking of class methods. My attempts with other techniques such as method swizzling wasn’t successful either.
It wasn’t until a few days ago when I noticed a discussion on GitHub about how to properly mock the interface to AFNetworking. In the discussion Adam Ernst suggested to use a customized NSURLProtocol for doing the task. That finally gave me the missing clue on how to solve the testing problem.
(more…)
Covering it all up
In the previous two posts I described how you can create unit tests for threaded code as well as how you can de-couple your tests from external errors on the internet.
In this post I’ll show how to use GCOV and CoverStory to ensure that you are actually testing all parts of your code. Or at least obtain knowledge about which parts of your code that are being tested and which parts that are not being tested by your unit tests.
Having a high degree of code coverage in your unit tests helps to ensure that your code will continue working as expected even after you change parts of it, e.g. when fixing bugs, re-factoring it, adding new features, etc.
The coverage data can also be used to show when you have added enough tests to your code. Once you have obtained full test coverage of a certain function, adding more tests for that same function will probably not help you find more bugs in the code. Instead you can now focus your efforts on adding new functionality without having to worry about it breaking behind your back.
Using Mock Objects to Stabilize Unit Tests
In the previous post I presented one way of implementing unit tests for iOS code that access the internet asynchronously. In this post I’ll go through how to use Mock Objects to further stabilize and optimize these tests. If you’re unfamiliar with the concept of Mock Objects I’ll suggest you first read A Brief History of Mock Objects or this Wikipedia article.
As mentioned in the previous post, it is possible that the unit tests may fail due to some outside factor even though our code is working perfectly. This could for instance be an internet service that is temporarily down or malfunctioning, or it could be your own ISP that have some problems.
By replacing the code that access the internet by Mock Objects that mimic the same behavior the unit tests can be made completely independent of external factors. Additionally by mocking the internet access the unit tests will also execute substantially faster . A speed increment by a factor 1000 or more is not unusual.
In Test Driven Development the complete Unit Test suite should ideally be executed as part of your normal compile setup. This means that execution times in the order of seconds for just a single test is an absolutely no-go. As Noel Llopis states in this blog post, the total execution time for the full test suite of your entire project should be less than 2 seconds. Whether the limit is 1, 2 or maybe even 3 seconds is not important, but the point is that it should be so fast that it doesn’t contribute to the perceived build time.
In the following I’ll show how to mock the network access code for ILGeoNames using OCMock by Mulle Kybernetik.
(more…)
