Test Driven Development(TDD) practice with Objective-C

I joined the event held by WWCKL on 11th March 2015, talking about Test Driven Development.
The meetup event’s link is here : link

WWCKLHere I will go through how I implement Unit Test in Objective-C using Xcode, possibly, I will do for Swift language after that. Hopefully it will be helpful to someone who may see this, though it is not very popular language in Malaysia. I was testing it in NodeJS at the very beginning, but there is someone posted his excellent work in Github.

Don’t worry, I put my Objective-C version in Github too, you can either download from there or read the details as below.

First, open a single view application.
new project

And then add a model in your project (MVC Model-View-Controller structure)

addCalculatorObject

Here is my code:
Calculator.h

#import <Foundation/Foundation.h>

@interface Calculator : NSObject

- (int)addWithString:(NSString *)string;

@end

Calculator.m

#import "Calculator.h"

@implementation Calculator

- (int)addWithString:(NSString *)string
{
    int result = 0;
    
    // Handling delimiters
    if (string.length > 2) {
        if ([[string substringWithRange: NSMakeRange(0, 2)] isEqualToString:@"//"])
        {
            // Remove @"//"
            string = [string substringFromIndex:2];
            NSLog(@"remove //: %@", string);
            
            // Get delimeter string
            NSArray *tempArray = [string componentsSeparatedByString:@"\n"];
            NSString *delimeterString = [tempArray objectAtIndex:0];
            NSLog(@"delimeterString: %@", delimeterString);
            
            // Remove first \n to get the numbers string
            NSString *newString = [tempArray objectAtIndex:1];
            for (int i = 2; i < tempArray.count; i++) {
                 newString = [NSString stringWithFormat:@"%@,%@", newString, [tempArray objectAtIndex:i]];
             }
             NSLog(@"numberString: %@", newString);
             string = newString;

             NSArray *delimeters = [delimeterString componentsSeparatedByString:@"["];
             for (NSString *delimeter in delimeters) {
                 // Skip first object
                 if ([delimeter isEqualToString:@""]) {
                     continue;
                 } else {
                     // Remove ] behind delimeter
                     NSString *cleanDelimeter = [delimeter stringByReplacingOccurrencesOfString:@"]" withString:@""];
                     NSLog(@"delimeter: %@", cleanDelimeter);
                     // Replace , instead of the delimeter
                     if (cleanDelimeter.length > 0) {
                        string = [string stringByReplacingOccurrencesOfString:cleanDelimeter withString:@","];
                    }
                }
            }
            
        }
    }
    
    
    
    // Replace @"\n"(newline) with @","(comma)
    string = [string stringByReplacingOccurrencesOfString:@"\n"
                                               withString:@","];
    NSLog(@"final string: %@", string);
    
    // Split the numbers into array
    NSArray *numbers = [string componentsSeparatedByString:@","];
    
    // Sum up the numbers
    for (NSString *number in numbers) {
        result += number.intValue;
    }
    
    return result;
}

@end

After that, you create testcase for calculator
chooseTestCaseClass

addCalculatorTestCase

Insert the following test case you wanted:

#pragma mark - Test Calculator Add Functions
- (void)testCalculatorWithEmptyString {
  Calculator *calculator = [[Calculator alloc] init];
  int result = [calculator addWithString:@""];
  XCTAssertEqual(result, 0, @"Should have matched");
}

- (void)testCalculatorWithSingleNumber {
  Calculator *calculator = [[Calculator alloc] init];
  int result = [calculator addWithString:@"1"];
  XCTAssertEqual(result, 1, @"Should have matched");
}

- (void)testCalculatorWithNumbers {
  Calculator *calculator = [[Calculator alloc] init];
  int result = [calculator addWithString:@"1,2,3,4,5"];
  XCTAssertEqual(result, 15, @"Should have matched");
}

- (void)testCalculatorWithNewLineAndNumbers {
  Calculator *calculator = [[Calculator alloc] init];
  int result = [calculator addWithString:@"1,2\n3"];
  XCTAssertEqual(result, 6, @"Should have matched");
}

- (void)testCalculaterWithSingleDelimeter {
  Calculator *calculator = [[Calculator alloc] init];
  int result = [calculator addWithString:@"//[::]\n1::2,3\n4::5"];
  XCTAssertEqual(result, 15, @"Should have matched");
}

- (void)testCalculaterWithMultipleDelimeters {
  Calculator *calculator = [[Calculator alloc] init];
  int result = [calculator addWithString:@"//[***][&][@]\n1***2&3&4***5@6@7,8\n9,10"];
  XCTAssertEqual(result, 55, @"Should have matched");
}

Run your test!
You can choose the certain testcase to run by clicking the arrow button beside:
beforeRunTest

The simulator will be prompt while testing, nevermind, you will still get your result.
afterRunTest

You can also refer to the console log for details
testingConsoleLog

Leave a comment