Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective C - Best practice for Unit Testing with multiple test inputs

I'm writing unit test codes for an existing project. The project is in Objective-C and I have to test few functions with a number of inputs to the test cases. For example, I have a test case to test a function calculator where two parameters are inputted. Currently I create array to store the set of input values to run the test. The code used are as follows:

- (void)setUp {
    [super setUp];
    self.vcToTest = [[BodyMassIndexVC alloc] init];
    input1 = [[NSMutableArray alloc] initWithObjects:@"193", @"192", @"192", @"165", @"155", @"154", nil];
    input2 = [[NSMutableArray alloc] initWithObjects:@"37", @"37", @"36", @"80",@"120", @"120", nil];
}



- (void)testCalculatorSuccess {
    for (int i=0; i<input1.count; i++) {
        NSArray *expectedResult = [[NSArray alloc] initWithObjects: @"9.93", @"10.04", @"9.77", @"29.38", @"49.95", @"50.60", nil];
        NSString *actualResult = [self.vcToTest calculateResult:input1[i] andInput2:input2[i]];
        XCTAssertEqualObjects(actualResult, expectedResult[i]);
    }

}

I searched for best practices online but was not able to find any. Can someone help me with this? Am I running the test in the right way? What is the best practice to be followed in such cases? Should I create a test case for every set of input?

like image 372
Naveen George Thoppan Avatar asked Aug 04 '26 04:08

Naveen George Thoppan


1 Answers

In my experience, the key consideration should be how easy it will be to maintain the test suite over time. Your current approach will cause problems down the road in two ways:

  1. If you want to use different numbers for you BMI calculation you need to use a different test class (because you're locking in the values in the setup method).

  2. If you ever decide to use different math or multiple BMI equations you'll have to update the arrays anywhere you're checking those values.

What I would suggest is to instead create a CSV or plain text file that has the height, weight, and expected BMI values in it. That keeps the test data together. Then in your test methods, load the file and check your actual BMI against the expected BMI.

You have the flexibility here to mix and match test data, or use different test files for different BMI equations. Personally, I also like the fact that you can keep old data files around as you change things, in case you ever want to rollback or add legacy algorithm support.

A quick and dirty version would look something like this:

- (NSArray *)dataFromFileNamed:(NSString *)filename {
    NSString *path = [[NSBundle bundleForClass:[self class]] pathForResource:filename ofType:nil];
    // load the data however its formatted
    // return the data as an array
    return loadedData;
}

- (void)testBMIFormulaInCmAndKgSuccess {
    NSArray *testData = [self dataFromFileNamed:@"BMI_data_01.txt"];
    for (int i=0; i < testData.count; i++) {
        NSArray *dataSet = testData[i];
        CGFloat height = dataSet[0];
        CGFloat weight = dataSet[1];
        CGFloat expectedBMI = dataSet[2];
        NSString *actualResult = [self.vcToTest calculateBMIforHeight:height andWeight:weight];
        XCTAssertEqual(actualResult, expectedBMI);
    }
}
like image 158
Nima Yousefi Avatar answered Aug 05 '26 19:08

Nima Yousefi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!