TDD Best Practices: Unit testing in iOS with GHUnit (Part 1)
2012-09-27 15:54
603 查看
From: http://longweekendmobile.com/2011/02/23/tdd-best-practices-testing-in-ios4-with-ghunit-part-1/
EDIT: This post is still relevant and useful for installing/setting up unit tests on iOS with GHUnit. However, as of Xcode 4, we have also begun using OCUnit again. See the article discussing which one is right for you.
Most Web frameworks (RoR, symfony, etc.) support test-driven development (TDD), and Long Weekend absolutely drinks the Kool-Aid (did you know it was actually Flavor Aid?).
Then we became iOS developers… right. “Let’s do the time warp again.”
Effective testing at both the unit and functional level is key to writing good code: tests enable you to refactor mercilessly, catch regressions almost immediately, and for the regressions you don’t catch, you write new tests so they never come back again. Liquid confidence.
We’re starting to get our TDD mojo back on iOS as well, with these 2 tools:
GHUnit – a TDD-friendly, debug-able unit testing framework that runs in real time on the device & simulator
UI Automation with Instruments – an Apple-provided (since iOS SDK 4.0) framework for functional integration testing that runs in real time on the device & simulator
In this part 1, we’ll cover GHUnit. Part 2, to be released later, will cover UI Automation.
GHUnit’s documentation isn’t bad, but they list “Installing” prior to “Building”. You have to build the library before you can install it into your project = a gotcha. Let’s do that.
First, clone a copy of the GHUnit repository from github (as a submodule would be smart). We usually put our external libraries in a separate directory as not to get confused:
Unfortunately, as of this writing, the authors of GHUnit haven’t updated their project file to the latest Xcode SDK settings, so you have to change their project file to allow it to build (if you have iOS SDK 4.2+).
Use XCode to open the GHUnitIPhone.xcodeproj project file in the Project-IPhone subdirectory.
Your “Base SDK” will probably be missing.
Navigate to Project -> Edit Project Settings menu.
Change “Base SDK for all configurations” to “Latest iOS (currently set to x.x)”. In my current case, x.x is 4.2.
Close the project file and re-open it.
XCode should now play nice and tell you it knows how to build this project.
But not so fast, GHUnit likes to be built from the command line, per this page in their documentation. Fire up a Terminal window and navigate to your gh-unit/Project-IPhone subdirectory. Make the sucker:
The Makefile will churn for a bit, and you’ll eventually see the end of the script:
Let’s look at the template test class.
Note the 2 separate setup methods,
Be careful not to use mutable objects (or objects with mutable properties) in the
Also, if I am testing a class, I usually add a
Then, my setup and teardown methods look like this:
That way, when testing, I can just freely reference
The
A few final “gotchas” and tips:
Don’t forget to add any libraries/frameworks your app uses to the GHUnit target as well.
Make sure not to include your
When using mock data, it’s helpful to put it in a separate directory from your app’s real data. Use the “blue folders” in XCode for this; use NSBundle’s
There are plenty of resources on the web about how to write effective unit tests – so I won’t delve into that in this post, but I hope that this has provided you with the base to get started writing your own unit tests for Objective-C and iOS.
EDIT: This post is still relevant and useful for installing/setting up unit tests on iOS with GHUnit. However, as of Xcode 4, we have also begun using OCUnit again. See the article discussing which one is right for you.
Most Web frameworks (RoR, symfony, etc.) support test-driven development (TDD), and Long Weekend absolutely drinks the Kool-Aid (did you know it was actually Flavor Aid?).
Then we became iOS developers… right. “Let’s do the time warp again.”
Effective testing at both the unit and functional level is key to writing good code: tests enable you to refactor mercilessly, catch regressions almost immediately, and for the regressions you don’t catch, you write new tests so they never come back again. Liquid confidence.
We’re starting to get our TDD mojo back on iOS as well, with these 2 tools:
GHUnit – a TDD-friendly, debug-able unit testing framework that runs in real time on the device & simulator
UI Automation with Instruments – an Apple-provided (since iOS SDK 4.0) framework for functional integration testing that runs in real time on the device & simulator
In this part 1, we’ll cover GHUnit. Part 2, to be released later, will cover UI Automation.
How-To: effective iOS unit testing with GHUnit
GHUnit was born from GTM’s (Google Toolkit for Mac) unit testing, which itself was already a much better step forward than Apple’s own XCode-provided OCTest framework (based on SenTest). GHUnit is a breeze to work with once you get it set up, but there are some non-trivial steps.1. Building the GHUnit Framework
I’ll assume that you are using git as your source version control software.GHUnit’s documentation isn’t bad, but they list “Installing” prior to “Building”. You have to build the library before you can install it into your project = a gotcha. Let’s do that.
First, clone a copy of the GHUnit repository from github (as a submodule would be smart). We usually put our external libraries in a separate directory as not to get confused:
> cd /your/project/directory > mkdir external-libs > git submodule add git://github.com/gabriel/gh-unit.git external-libs/gh-unit
Unfortunately, as of this writing, the authors of GHUnit haven’t updated their project file to the latest Xcode SDK settings, so you have to change their project file to allow it to build (if you have iOS SDK 4.2+).
Use XCode to open the GHUnitIPhone.xcodeproj project file in the Project-IPhone subdirectory.
Your “Base SDK” will probably be missing.
Navigate to Project -> Edit Project Settings menu.
Change “Base SDK for all configurations” to “Latest iOS (currently set to x.x)”. In my current case, x.x is 4.2.
Close the project file and re-open it.
XCode should now play nice and tell you it knows how to build this project.
But not so fast, GHUnit likes to be built from the command line, per this page in their documentation. Fire up a Terminal window and navigate to your gh-unit/Project-IPhone subdirectory. Make the sucker:
> make
The Makefile will churn for a bit, and you’ll eventually see the end of the script:
** BUILD SUCCEEDED **
2. Installing GHUnit into Your Project
So, now it’s time to add that framework that you’ve just built into your project. For this part, you can follow GHUnit’s installation instructions as-is. Why rewrite what already works? You don’t have to follow the two optional steps at the bottom of their instructions.3. Being Awesome With Unit Tests
GHUnit follows standard unit testing framework guidelines: there are methods that are called once at the beginning and end of each test class, and then methods that are called once before and after each test method.Let’s look at the template test class.
-setUpClassand
-setUp. Either of these can be used for setup/initialization of objects that you’ll use in your tests, but they are different.
Be careful not to use mutable objects (or objects with mutable properties) in the
setUpClassmethod. These should go in the
setUpmethod, which will keep each of your unit tests atomic and independent.
Also, if I am testing a class, I usually add a
@propertyto the test class in the interface (and synthesize it in the implementation):
self.testObjectin each test and know that I have a new, fresh object in each test. Not having to bother with initialization and releasing allows your tests to focus on what they’re supposed to do: test your code.
The
-setUpClassmethod is useful for more expensive operations like loading test assets. In our case for a recent app, we had property list files that needed to be read into a dictionary. This is immutable data, so we put this in
-setUpClass, defined an instance variable for it, and used it in each test method.
4. Running Your Tests
As part of the GHUnit installation process, you should have created a separate target in your XCode project. Switch to that target, build, and debug your app. That’s it; the GHUnit interface should appear in your simulator/device instead of your app.A few final “gotchas” and tips:
Don’t forget to add any libraries/frameworks your app uses to the GHUnit target as well.
Make sure not to include your
YourTestCase.mtest classes into your app’s regular target.
When using mock data, it’s helpful to put it in a separate directory from your app’s real data. Use the “blue folders” in XCode for this; use NSBundle’s
pathForResourcemethod to get it out.
There are plenty of resources on the web about how to write effective unit tests – so I won’t delve into that in this post, but I hope that this has provided you with the base to get started writing your own unit tests for Objective-C and iOS.
相关文章推荐
- Pragmatic Unit Testing in C# with NUnit, 2nd Edition
- Pragmatic Unit Testing in Java with JUnit 书评
- Unit Testing in C# with Nunit
- [iOS] 养成TDD好习惯(1):create first project with unit test
- Pragmatic Unit Testing in Java with JUnit 书评
- 电子书下载:Pragmatic Unit Testing in C# with NUnit
- Java Unit Testing with JUnit in NetBeans
- Pragmatic Unit Testing in Java with JUnit
- 《Pragmatic unit testing:in java with Junit》阅读
- 《Pragmatic Unit Testing In Java with JUnit》—单元测试之道读后感
- Computer vision with iOS Part 2: Face tracking in live video
- Unit Testing in Xcode 4 – use OCUnit and SenTest instead of GHUnit
- [寻书]请问谁有《Pragmatic Unit Testing in C# with NUnit 》的电子版,请发给我一下,谢谢!
- Testing SQL queries with Spring and DbUnit, part 1
- How To Use Git Source Control with Xcode in iOS 7
- [Angular Unit Testing] Testing Services with dependencies
- [Test] Easy automated testing in NodeJS with TestCafe
- iOS-Best Practices for Interacting with a Remote Peripheral Device(API Reference) the sixth part
- Unit Testing in Java: How Tests Drive the Code
- ios 提交 App Store Error Problem with Icon.png (Icon specified in the Info.plist not found under the t