Testing And Benchmarking in Objective-C
Here’s the translation of the Go testing and benchmarking example to Objective-C:
#import <Foundation/Foundation.h>
#import <XCTest/XCTest.h>
// We'll be testing this simple implementation of an
// integer minimum. Typically, the code we're testing
// would be in a source file named something like
// `IntUtils.m`, and the test file for it would then
// be named `IntUtilsTests.m`.
int IntMin(int a, int b) {
return (a < b) ? a : b;
}
// A test is created by subclassing XCTestCase and implementing
// test methods with names beginning with "test".
@interface IntMinTests : XCTestCase
@end
@implementation IntMinTests
- (void)testIntMinBasic {
int ans = IntMin(2, -2);
XCTAssertEqual(ans, -2, @"IntMin(2, -2) = %d; want -2", ans);
}
// Writing tests can be repetitive, so it's idiomatic to
// use a table-driven style, where test inputs and
// expected outputs are listed in an array and a single loop
// walks over them and performs the test logic.
- (void)testIntMinTableDriven {
NSArray *tests = @[
@[@0, @1, @0],
@[@1, @0, @0],
@[@2, @-2, @-2],
@[@0, @-1, @-1],
@[@-1, @0, @-1]
];
for (NSArray *test in tests) {
int a = [test[0] intValue];
int b = [test[1] intValue];
int want = [test[2] intValue];
int ans = IntMin(a, b);
XCTAssertEqual(ans, want, @"IntMin(%d, %d) = %d; want %d", a, b, ans, want);
}
}
@end
// Benchmark tests in Objective-C are typically done using
// the -measureBlock: method of XCTestCase. The framework will
// run the block multiple times to get an average execution time.
@interface IntMinBenchmark : XCTestCase
@end
@implementation IntMinBenchmark
- (void)testPerformanceIntMin {
[self measureBlock:^{
for (int i = 0; i < 1000000; i++) {
IntMin(1, 2);
}
}];
}
@end
To run these tests, you would typically use Xcode’s built-in test runner. If you’re using the command line, you can use xcodebuild
like this:
$ xcodebuild test -scheme YourScheme -destination 'platform=iOS Simulator,name=iPhone 12'
This will run all the tests in your test target and provide output similar to:
Test Suite 'IntMinTests' started.
Test Case '-[IntMinTests testIntMinBasic]' passed.
Test Case '-[IntMinTests testIntMinTableDriven]' passed.
Test Suite 'IntMinTests' passed.
Test Suite 'IntMinBenchmark' started.
Test Case '-[IntMinBenchmark testPerformanceIntMin]' passed.
Test Suite 'IntMinBenchmark' passed.
The performance test results will include the average execution time and standard deviation.
Note that Objective-C uses XCTest framework for unit testing and benchmarking, which is somewhat different from Go’s testing package. XCTest is integrated with Xcode and provides a rich set of assertion macros and performance measurement tools.
Unlike Go, Objective-C doesn’t have a built-in benchmarking tool that’s separate from the testing framework. Instead, performance tests are run as part of the regular test suite using the -measureBlock:
method.
Remember to add your test files to your Xcode project’s test target to ensure they’re included when running tests.