TestsTested | ✗ |
LangLanguage | Obj-CObjective C |
License | MIT |
ReleasedLast Release | Jan 2015 |
Maintained by Gabriel Handford.
GRUnit is a test framework for iOS and OSX which runs as a Test (app) target in your project. It's meant to be very similar to XCTest and supports asynchronous testing with timeouts. By default, it is meant to raise an Exception on test failure, so you can use an exception breakpoint and debug in Xcode at the point of failure.
Projects using GRUnit:
This gem makes it easy to setup a test app target.
$ gem install grunit
This will edit your ProjectName.xcodeproj file and create a Tests target, scheme, and a sample test file. Its ok to run this multiple times, it won't duplicate any files, targets or schemes.
$ grunit install -n ProjectName
Setup your Podfile to include GRUnit for the Tests target you just created.
# Podfile
platform :ios, '7.0'
target :Tests do
pod 'GRUnit', '~> 1.0.1'
end
Install your project's pods. CocoaPods will then download and configure the required libraries for your project:
$ pod install
Note: If you don't have a Tests target in your project, you will get an error: "[!] Unable to find a target named Tests". If you named your test target something different, such as "ProjectTests" then the Podfile target line should look like: target :ProjectTests do
instead.
You should use the .xcworkspace
file to work on your project:
$ open ProjectName.xcworkspace
To generate a test in your test target with name SampleTest:
$ grunit add -n ProjectName -f SampleTest
or read the GRTestCase
example below.
If you want to link all the files in your main target to the test target in your project file, run this sync command.
$ grunit sync -n ProjectName
#import <GRUnit/GRUnit.h>
@interface MyTest : GRTestCase
@end
@implementation MyTest
- (void)test {
GRAssertEquals(1U, 1U);
GRAssertEqualStrings(@"a string", @"a string");
GRAssertEqualObjects(@[@"test"], expectedArray);
// See more macros below
// To log in a test and have it show in the UI with this test
GHTestLog(@"Log this number: %@", @(123));
}
// Test with completion (async) callback
- (void)testWithCompletion:(dispatch_block_t)completion {
dispatch_queue_t queue = dispatch_queue_create("MyTest", NULL);
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:2];
GRTestLog(@"Log something and it will show up in the UI and stdout");
// Call completion when the test is done
completion();
});
}
- (void)testRunLoopsWithCompletion:(dispatch_block_t)completion {
// If you are using sockets attached to run loops, you need to
// call wait which will run the default and common run loop modes
[self wait:10]; // Run loops until completion (or timeout after 10 seconds)
}
// For a long test, you can check cancel state and break/return
- (void)testCancel {
for (NSInteger i = 0; i < 123456789; i++) {
if (self.isCancelling) break;
}
}
// Runs before each test
- (void)setUp {
}
// Runs before each test (async)
- (void)setUp:(dispatch_block_t)completion {
completion();
}
// Runs after each test
- (void)tearDown {
}
// Runs after each test (async)
- (void)tearDown:(dispatch_block_t)completion {
completion();
}
@end
To have all your tests in a test case run on the main thread, implement shouldRunOnMainThread
.
@implementation MyTest
- (void)testSomethingOnMainThread {
GRAssertTrue([NSThread isMainThread]);
}
- (BOOL)shouldRunOnMainThread {
return YES;
}
@end
GRUnit works best with an exception breakpoint. So your test run will breakpoint if an error occurs allowing you to interact with the debugger.
When adding the exception breakpoint, you change the action to Debugger Command
of po $eax
so it logs the exception to the console automatically.
GRAssertNil(a1)
GRAssertNotNil(a1)
GRAssertTrue(expr)
GRAssertFalse(expr)
GRAssertNotNULL(a1)
GRAssertNULL(a1)
GRAssertNotEquals(a1, a2)
GRAssertNotEqualObjects(a1, a2, desc, ...)
GRAssertOperation(a1, a2, op)
GRAssertGreaterThan(a1, a2)
GRAssertGreaterThanOrEqual(a1, a2)
GRAssertLessThan(a1, a2)
GRAssertLessThanOrEqual(a1, a2)
GRAssertEqualStrings(a1, a2)
GRAssertNotEqualStrings(a1, a2)
GRAssertEqualCStrings(a1, a2)
GRAssertNotEqualCStrings(a1, a2)
GRAssertEqualObjects(a1, a2)
GRAssertEquals(a1, a2)
GHAbsoluteDifference(left,right) (MAX(left,right)-MIN(left,right))
GRAssertEqualsWithAccuracy(a1, a2, accuracy)
GRFail(description, ...)
GRAssertNoErr(a1)
GRAssertErr(a1, a2)
This project uses GRUnit. Open GRUnit.xcworkspace
and run the Tests target.
Install:
$ grunit install_cli -n ProjectName
Install ios-sim using homebrew (for iOS):
$ brew install ios-sim
Now you can run tests from the command line:
This doesn't work right...
$ grunit run -n ProjectName
#import <GHUnit/GHUnit.h>
with #import <GRUnit/GRUnit.h>
GHTestCase
with GRTestCase
GHAssert...
with GRAssert...
and remove the description argument (usually nil).GHTestLog
with GRTestLog
.GHUnitIOSAppDelegate
with GRUnitIOSAppDelegate
.