diff options
author | thomasvl@gmail.com <thomasvl@gmail.com@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3> | 2009-01-30 15:17:34 +0000 |
---|---|---|
committer | thomasvl@gmail.com <thomasvl@gmail.com@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3> | 2009-01-30 15:17:34 +0000 |
commit | 2ae297214778005d95354f207753180edca51ec4 (patch) | |
tree | 137e6628c4b905693478e0f20f4912788e0a266e | |
parent | ba7d45cf8c3b1938a51a9b3580919c61bf750f9d (diff) |
- Added simple accessor to get the number of tests that pass/fail from the
iphone test delegate, should make it easy for any app driving tests to check
the results for anything they need to do.
- If the iPhone unittesting support is exiting when done, it now properly sets
the exit code based on test success/failure.
-rw-r--r-- | ReleaseNotes.txt | 3 | ||||
-rw-r--r-- | UnitTesting/GTMIPhoneUnitTestDelegate.h | 11 | ||||
-rw-r--r-- | UnitTesting/GTMIPhoneUnitTestDelegate.m | 95 |
3 files changed, 70 insertions, 39 deletions
diff --git a/ReleaseNotes.txt b/ReleaseNotes.txt index 993c885..d7e34b3 100644 --- a/ReleaseNotes.txt +++ b/ReleaseNotes.txt @@ -221,6 +221,9 @@ Changes since 1.5.1 - GTMNSWorkspace+Running gives a variety of ways of determining the attributes of running processes. +- If the iPhone unittesting support is exiting when done, it now properly sets + the exit code based on test success/failure. + Release 1.5.1 Changes since 1.5.0 diff --git a/UnitTesting/GTMIPhoneUnitTestDelegate.h b/UnitTesting/GTMIPhoneUnitTestDelegate.h index f12a9b6..4583b5d 100644 --- a/UnitTesting/GTMIPhoneUnitTestDelegate.h +++ b/UnitTesting/GTMIPhoneUnitTestDelegate.h @@ -21,11 +21,18 @@ // Application delegate that runs all test methods in registered classes // extending SenTestCase. The application is terminated afterwards. // You can also run the tests directly from your application by invoking -// gtm_runTests and clean up, restore data, etc. before the application +// runTests and clean up, restore data, etc. before the application // terminates. -@interface GTMIPhoneUnitTestDelegate : NSObject +@interface GTMIPhoneUnitTestDelegate : NSObject { + @private + NSUInteger totalFailures_; + NSUInteger totalSuccesses_; +} // Runs through all the registered classes and runs test methods on any // that are subclasses of SenTestCase. Prints results and run time to // the default output. - (void)runTests; +// Fetch the number of successes or failures from the last runTests. +- (NSUInteger)totalSuccesses; +- (NSUInteger)totalFailures; @end diff --git a/UnitTesting/GTMIPhoneUnitTestDelegate.m b/UnitTesting/GTMIPhoneUnitTestDelegate.m index ab33932..39de1f5 100644 --- a/UnitTesting/GTMIPhoneUnitTestDelegate.m +++ b/UnitTesting/GTMIPhoneUnitTestDelegate.m @@ -34,10 +34,8 @@ static int MethodSort(const void *a, const void *b) { return strcmp(nameA, nameB); } -@implementation GTMIPhoneUnitTestDelegate - // Return YES if class is subclass (1 or more generations) of SenTestCase -- (BOOL)isTestFixture:(Class)aClass { +static BOOL IsTestFixture(Class aClass) { BOOL iscase = NO; Class testCaseClass = [SenTestCase class]; Class superclass; @@ -49,15 +47,19 @@ static int MethodSort(const void *a, const void *b) { return iscase; } +@implementation GTMIPhoneUnitTestDelegate + // Run through all the registered classes and run test methods on any // that are subclasses of SenTestCase. Terminate the application upon // test completion. - (void)applicationDidFinishLaunching:(UIApplication *)application { [self runTests]; - // Using private call to end our tests if (!getenv("GTM_DISABLE_TERMINATION")) { - exit(0); + // To help using xcodebuild, make the exit status 0/1 to signal the tests + // success/failure. + int exitStatus = (([self totalFailures] == 0U) ? 0 : 1); + exit(exitStatus); } } @@ -66,29 +68,30 @@ static int MethodSort(const void *a, const void *b) { // the default output. - (void)runTests { int count = objc_getClassList(NULL, 0); - NSMutableData *classData = [NSMutableData dataWithLength:sizeof(Class) * count]; + NSMutableData *classData + = [NSMutableData dataWithLength:sizeof(Class) * count]; Class *classes = (Class*)[classData mutableBytes]; _GTMDevAssert(classes, @"Couldn't allocate class list"); objc_getClassList(classes, count); - int suiteSuccesses = 0; - int suiteFailures = 0; - int suiteTotal = 0; + totalFailures_ = 0; + totalSuccesses_ = 0; NSString *suiteName = [[NSBundle mainBundle] bundlePath]; NSDate *suiteStartDate = [NSDate date]; - NSString *suiteStartString = [NSString stringWithFormat:@"Test Suite '%@' started at %@\n", - suiteName, suiteStartDate]; + NSString *suiteStartString + = [NSString stringWithFormat:@"Test Suite '%@' started at %@\n", + suiteName, suiteStartDate]; fputs([suiteStartString UTF8String], stderr); fflush(stderr); for (int i = 0; i < count; ++i) { Class currClass = classes[i]; - if ([self isTestFixture:currClass]) { + if (IsTestFixture(currClass)) { NSDate *fixtureStartDate = [NSDate date]; NSString *fixtureName = NSStringFromClass(currClass); - NSString *fixtureStartString = [NSString stringWithFormat:@"Test Suite '%@' started at %@\n", - fixtureName, fixtureStartDate]; + NSString *fixtureStartString + = [NSString stringWithFormat:@"Test Suite '%@' started at %@\n", + fixtureName, fixtureStartDate]; int fixtureSuccesses = 0; int fixtureFailures = 0; - int fixtureTotal = 0; fputs([fixtureStartString UTF8String], stderr); fflush(stderr); id testcase = [[currClass alloc] init]; @@ -99,8 +102,8 @@ static int MethodSort(const void *a, const void *b) { if (!methods) { // If the class contains no methods, head on to the next class NSString *output = [NSString stringWithFormat:@"Test Suite '%@' " - "finished at %@.\nExecuted 0 tests, with 0 " - "failures (0 unexpected) in 0 (0) seconds\n", + @"finished at %@.\nExecuted 0 tests, with 0 " + @"failures (0 unexpected) in 0 (0) seconds\n", fixtureName, fixtureStartDate]; fputs([output UTF8String], stderr); @@ -134,7 +137,6 @@ static int MethodSort(const void *a, const void *b) { if (returnType // True if name starts with "test" && strcmp(returnType, @encode(void)) == 0 && method_getNumberOfArguments(currMethod) == 2) { - fixtureTotal += 1; BOOL failed = NO; NSDate *caseStartDate = [NSDate date]; @try { @@ -147,39 +149,58 @@ static int MethodSort(const void *a, const void *b) { } else { fixtureSuccesses += 1; } - NSTimeInterval caseEndTime = [[NSDate date] timeIntervalSinceDate:caseStartDate]; - NSString *caseEndString = [NSString stringWithFormat:@"Test Case '-[%@ %s]' %s (%0.3f seconds).\n", - fixtureName, name, - failed ? "failed" : "passed", caseEndTime]; + NSTimeInterval caseEndTime + = [[NSDate date] timeIntervalSinceDate:caseStartDate]; + NSString *caseEndString + = [NSString stringWithFormat:@"Test Case '-[%@ %s]' %@ (%0.3f " + @"seconds).\n", + fixtureName, name, + failed ? @"failed" : @"passed", + caseEndTime]; fputs([caseEndString UTF8String], stderr); fflush(stderr); } } [testcase release]; NSDate *fixtureEndDate = [NSDate date]; - NSTimeInterval fixtureEndTime = [fixtureEndDate timeIntervalSinceDate:fixtureStartDate]; - NSString *fixtureEndString = [NSString stringWithFormat:@"Test Suite '%@' finished at %@.\n" - "Executed %d tests, with %d failures (%d unexpected) in %0.3f (%0.3f) seconds\n\n", - fixtureName, fixtureEndDate, fixtureTotal, - fixtureFailures, fixtureFailures, - fixtureEndTime, fixtureEndTime]; + NSTimeInterval fixtureEndTime + = [fixtureEndDate timeIntervalSinceDate:fixtureStartDate]; + NSString *fixtureEndString + = [NSString stringWithFormat:@"Test Suite '%@' finished at %@.\n" + @"Executed %d tests, with %d failures (%d " + @"unexpected) in %0.3f (%0.3f) seconds\n\n", + fixtureName, fixtureEndDate, + fixtureSuccesses + fixtureFailures, + fixtureFailures, fixtureFailures, + fixtureEndTime, fixtureEndTime]; fputs([fixtureEndString UTF8String], stderr); fflush(stderr); - suiteTotal += fixtureTotal; - suiteSuccesses += fixtureSuccesses; - suiteFailures += fixtureFailures; + totalSuccesses_ += fixtureSuccesses; + totalFailures_ += fixtureFailures; } } NSDate *suiteEndDate = [NSDate date]; - NSTimeInterval suiteEndTime = [suiteEndDate timeIntervalSinceDate:suiteStartDate]; - NSString *suiteEndString = [NSString stringWithFormat:@"Test Suite '%@' finished at %@.\n" - "Executed %d tests, with %d failures (%d unexpected) in %0.3f (%0.3f) seconds\n\n", - suiteName, suiteEndDate, suiteTotal, - suiteFailures, suiteFailures, - suiteEndTime, suiteEndTime]; + NSTimeInterval suiteEndTime + = [suiteEndDate timeIntervalSinceDate:suiteStartDate]; + NSString *suiteEndString + = [NSString stringWithFormat:@"Test Suite '%@' finished at %@.\n" + @"Executed %d tests, with %d failures (%d " + @"unexpected) in %0.3f (%0.3f) seconds\n\n", + suiteName, suiteEndDate, + totalSuccesses_ + totalFailures_, + totalFailures_, totalFailures_, + suiteEndTime, suiteEndTime]; fputs([suiteEndString UTF8String], stderr); fflush(stderr); } +- (NSUInteger)totalSuccesses { + return totalSuccesses_; +} + +- (NSUInteger)totalFailures { + return totalFailures_; +} + @end |