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.