Test Driven Development in iOS


Test-Driven Development (TDD) is a development approach that emphasizes writing tests before writing the actual code. TDD can help ensure the reliability and maintainability of your code. In this post, we’ll explore the Red-Green-Refactor cycle of TDD by building a simple calculator class in Swift, focusing only on the addition function.


The Red-Green-Refactor Cycle


This cycle is the cornerstone of TDD, consisting of three essential steps:

  1. Red: Write a failing test. Ideally with one assertion per unit test.
  2. Green: Write the minimum code to make the test pass.
  3. Refactor: Improve the code without changing its behavior.

Let’s apply this cycle to create a Calculator class with an addition function.


Step 1: Red - Write a Failing Test


We’ll start by writing a failing test for our addition function.

In a TDD context, this means creating a test case that checks whether the addition operation behaves as expected.



    import XCTest

    final class CalculatorTests: XCTestCase {
        
        var sut: Calculator!

        override func setUp() {
            super.setUp()
            sut = Calculator()
        }

        func testAddition() {
            let result = sut.add(a: 5.0, b: 3.0)

            XCTAssertEqual(result, 8.0, "Adding 5.0 to 3.0 should equal 8.0")
        }

        override func tearDown() {
            sut = nil
            super.tearDown()
        }
    }


In this test, we create an instance of the Calculator class, call its add method with two numbers, and assert that the result is equal to the expected answer, which is 8.0.


Step 2: Green - Make the Test Pass


The code won’t compile at this stage in many cases. For us, the add function as well as the Calculator class don’t exist yet. So we will have to first declare these two to fix the compile errors. And then, if we run the test, it will fail.

Now that we have a failing test, it’s time to make it pass. We’ll implement the Calculator class with a basic addition function:



    final class Calculator {
        func add(a: Double, b: Double) -> Double {
            return a + b
        }
    }


Our addition function takes two numbers as parameters and simply returns their sum.


Step 3: Refactor - Improve Code Quality


At this point, our test passes, but we can further improve our code’s quality. For instance, we can add comments, improve variable names, and ensure code readability. Refactoring aims to enhance the code without changing its behavior.



    final class Calculator {
        func add(_ num1: Double, to num2: Double) -> Double {
            num1 + num2
        }
    }


Now we can make changes to our test as well.



    import XCTest

    final class CalculatorTests: XCTestCase {

        func testAddition() {`X
            let calculator = Calculator()
            let result = calculator.add(5.0, to: 3.0)
            XCTAssertEqual(result, 8.0) // We expect the result to be 8.0
        }
    }


Conclusion

In this post, we’ve walked through the Red-Green-Refactor cycle of Test-Driven Development using Swift. We’ve created a Calculator class with an addition function, ensuring that our code is reliable and maintainable. TDD can be a powerful tool in your development process, helping you write clean and bug-free code from the start.