Why does a Google search for “ghunit test example” ask if I mean “junit test example”? Right there, that should have alerted me to how painful this endeavor would be. So far, I have been unimpressed with the documentation I have found for testing (among other things Objective-C related). As I mentioned in my previous post, I have found a few blog posts and user guides that I keep referring back to, however they are in no way complete (but getting better).
My first major task (which I would argue should not have been major) in this series, was to write my first unit test. I was only partly surprised that the book I bought had no references to testing in it. In talking with other developers, I was told ghunit was far and away a better choice than the standard OCUnit, so I went with it. I can’t imagine the pain I would have endured had I gone with OCUnit instead. I spent four nights writing a GHUnit test for a class with one method which would return the number one. It took me two nights to figure out that I had to “Start Tests” under the “Executables” folder. Just goes to show how unfamiliar I still am with the XCode IDE.
The Test
#import "TestDrivenObjectiveC.h" #import <ghunit/GHUnit.h> @interface TestDrivenObjectiveCTest : GHTestCase {} @end @implementation TestDrivenObjectiveCTest -(void) testMethodReturning42DoesNotReturn43AndShouldFail{ TestDrivenObjectiveC *something = [[TestDrivenObjectiveC alloc] init]; int retVal = [something methodReturning42]; GHAssertEquals(43, retVal, @"retVal is not equal to 43!"); } -(void) testMethodReturning42Returns42AndShouldPass{ TestDrivenObjectiveC *something = [[TestDrivenObjectiveC alloc] init]; int retVal = [something methodReturning42]; GHAssertEquals(42, retVal, @"retVal is not equal to 42!"); } @end
The Code
#import <cocoa/Cocoa.h> @interface TestDrivenObjectiveC : NSObject { } - (int) methodReturning42; @end
#import "TestDrivenObjectiveC.h" @implementation TestDrivenObjectiveC - (int) methodReturning42{ return 42; } @end
The Instructions
Prep Work
- Copy GHUnit.framework from here to /Library/Frameworks/ within the Finder
- Create a new project (Cocoa Application)
- Create a new Target (Application – Cocoa) called UnitTests
- In the Target “UnitTests” Info window that pops up, select the General tab
- Add GHUnit.framework
- Click the + to add a Linked Library
- Select GHUnit.framework and click Add
- Add your project as a dependency
- Click the + to add a Direct Dependency
- Select your project and click Add Target
- Close the Target “UnitTests” Info window
- Add GHUnit.framework
- Copy GHUnitTestMain.m into the project
- Right click on UnitTests Target and choose Add->Existing Files…->browse to GHUnitTestMain.m
- Choose to add it only to the UnitTests Target and copy it into the project
Write a Test
- Right click on the project and choose Add->New File…
- Choose Objective-C class
- Give the test a name
- Keep only the UnitTests Target selected
- Subclass GHTestCase
- Add a test method
Write Some Testable Code
- Right click on the project and choose Add->New File…
- Choose Objective-C class
- Give the class a name
- Copy the testable code to the Unit Tests (this is awkward – probably a better way around this)
- Drag the testable .m files down into the UnitTests Compiled folder
Run the Test
- Right click on the UnitTests target and click Build UnitTests
- If that is successful, go to the Executables and right click and select Start UnitTests
- When the window of unit tests opens, click the Run button
- Watch for successful or failed tests!
When I started writing this post a few days ago, I still hadn’t found an excellent resource for what test assertions were available other than reading the source code. But after taking another crack at finding documentation, I ran across GHUnit documentation, which has been improved considerably with a dedicated site for the documentation and now includes information about the test macros.
Next Up
Something useful. More than one method returning the number 42. Somehow, I feel another challenge coming on…