Simplified asserts in OCUnit
I just started jusing OCUnit and find the asserts a bit cumbersome. In JUnit I can write a test to compare numbers like below. This test will obviously fail, but this shows the nice, simple assert I can write for two numbers and the feedback I get: "expected <2> but was <3>" with very little code.
What I tried 开发者_运维技巧so far i XCode is:
Which works, but is not as elegant as JUnit. Do you know if it exists assertion macros alà JUnit for XCode (OCUnit)? Also, is it possible to get the red/green bar in XCode?
The first thing to be aware of is that OCUnit (aka SenTestingKit.framework) are integrated with Xcode, but not really a part of Xcode proper. OCUnit started as third-party code and became the de facto standard for Objective-C unit testing, so Apple adopted it and now maintains it.
More to the point, the output you're seeing seems somewhat odd. I'm using Xcode 3.2.1 which comes with Snow Leopard. I tried the following test:
- (void) testNumbers {
int number1 = 2;
int number2 = 3;
STAssertEquals(number1, number2, nil);
STAssertEquals(4, 5, nil);
}
Here's are the errors I see in the Xcode build results pane/window:
-[ExampleTest testNumbers] : '2' should be equal to '3'
-[ExampleTest testNumbers] : '4' should be equal to '5'
When I double-click on the error in the build log, Xcode jumps directly to the line of the failed assertion.
The OCUnit macros certainly aren't perfect, but the example you used above was incredibly verbose. The macros require either 2+ or 3+ arguments. (STFail
is the exception, and only requires 1+ arguments.) The last required argument is always an optional format string for a description, and any other parameters are used to substitute in those placeholders, just like you'd do with printf()
or NSLog()
. If you pass nil
, you just get the default error without extra detail.
I generally only add a description when the test really requires context. For example, what the test and/or the subject(s) of the assertion actually mean. More often than not, I just include this information as comments around the assertion. Simpler is better. :-)
To answer your last question, there's not currently a way to get a red/green bar in Xcode like you'd see with JUnit. That might be a nice addition, but not something I'd personally consider critical. YMMV.
As others have said, you can make the macros a little easier to stomach by passing nil
as the last argument. This will get you the default output if the test fails. You can, of course, supply your own string when you want. I often find this is useful for code that has methods that return a BOOL
or an id
but take an NSError*
by reference like this:
- (void)testFoo {
NSError *err;
STAssertTrue([bar fooMethodReturningBOOLError:&err], @"Error: %@ (%@)", err, [err userInfo]);
}
Regarding the red/green bar, you do get a red/green result as the last step of the build in the build window, but it's not as visible as in other IDEs. There's lots of good psychology literature suggesting that making it much more prominent would be a good idea. Definitely file an enhancement request at bugreport.apple.com. You can reference rdar://7685315
(my ticket to this effect).
There is a great framework available now called OCHamcrest. It allows your test assertions to read like a sentence and in general you don't have to provide a failure description, which for me is the last thing I wan't to do in a test because it has to be maintained.
Here is the github https://github.com/hamcrest/OCHamcrest
Here is a sample from the readme
NSCalendarDate* date = [NSCalendarDate dateWithString:@"26 Apr 2008" calendarFormat:@"%d %b %Y"];
assertThat(date, is(onASaturday()))
The assertions are very OCUnit friendly and adding your own assertions is fairly straight forward.
Why not create your own wrapper for that?
OCUnit dumps the results of the run into the console window, there's no GUI integration, sorry. I find it's fairly convenient, but I'm used to it.
精彩评论