Test-driven development in Swift

Test-driven development in Swift

After we have seen Unit Testing and how to write them, today we will talk about Test-driven development in swift.

One of the methodologies in software development that has been developed by Kent Beck is the “Extreme Programming”, and it’s based on 12 rules or practices. one of them is that developer has to write a unit test and all of the software has to be tested, and all tests have to pass before the developer takes the green light to release to the customer.

Unit Test vs TDD

first, let’s see what is the difference between the Unit test and Test-driven development. In Unit Test you write code to test your code. that’s mean you first write code then you write tests to verify your logic and code that you wrote. but that’s not the case in TDD, where you first write tests that fail and then write code to make the tests pass, and then you refactor your code.

The three rules of TDD

Robert C. Martin wrote on his website Uncle Bob rules to describe the TDD. They are:

  1. You are not allowed to write any production code unless it is to make a failing unit test pass.
  2. You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
  3. You are not allowed to write any more production code than is sufficient to pass the one failing unit test.

You must begin by writing a unit test for the functionality that you intend to write. But by rule 2, you can’t write very much of that unit test. As soon as the unit test code fails to compile, or fails an assertion, you must stop and write production code. But by rule 3 you can only write the production code that makes the test compile or pass, and no more.

What is Test-driven development?

TDD is where you first write a test that fails, and then you write code to make it pass, and then you refactor your code to be as simple as possible.

TDD Flow

writing automated tests is seen as not real work and boring compared to building new features. TDD, however, turns testing into a design activity. We use our tests to make sure our code is doing what we want it to do. It also keeps code as simple as possible so it’s easier to understand and modify, especially since developers spend more time reading code than writing it.

using TDD to develop gives us feedback about the quality of both its implementation (does it work) and design (is it well structured).

An example of TDD

we will use the same Calculator example we wrote in the previous post. now when opening the project and run the test it should pass.

let’s start by writing the acceptance criteria for our tests, and we have to answer the following questions:

  • Precondition: what is the system state before we invoke the method?
  • Invocation: what is the method signature? what is the input and what is the output of the method?
  • Assertion: what is the expected result of the method?

In our Calculator example, we want to add new methods, for example, we want to add the power method, so let’s answer the previous questions

  • Precondition: None.
  • Invocation: the method should take two Integers, x, and y, and return an integer which is the result of x to the power of y.
  • Assertion: the result should be an integer equal to x to the power of y.

Red step

go to CalculatorTest.swift and write the following code:

                    
func testPowerMethod() throws {
let calcualtor = Calcualtor()
let result = calcualtor.power(x: 5,y: 2)
}

before you complete writing the test you will see the red alert to tell you that there is something wrong, so you have to start writing some code here

writing test power method

Green Step

go the Calculator.swift file and create the method power

                    
func power(x: Int, y: Int) -> Int {
return 0
}

run the test again, and now it will be green

make the test green

notice we did not focus on any thing except making the test pass

Red, Again

now let’s continue with our test, and write the assertion

                    
func testPowerMethod() throws {
let calcualtor = Calculator()
let result = calcualtor.power(x: 5,y: 2)
XCTAssertEqual(result, 25)
}

now run the test again using “Command + U ” and it will fail again. because we did not write the body of the power function to give the correct result

Have the Green Ligh again

to have the green light again we should go to Calculator.swift file and implement the power method body like this:

                    
func power(x: Int, y: Int) -> Int {
var result = 1
var i = y
while (i != 0) {
result *= x
i -= 1
}
return result
}

and it when run the test again it will turns green.

Refactor the code

after we get the correct result from the method now it’s time to refactor it to make sure that your code is as simple as possible. So how can we do that here?

let’s get ride of the for-loop and try to use the built it pow(_, _) method in swift. The problem is this method accept doubles instead of Integers so we have to convert them

                    
func power(x: Int, y: Int) -> Int {
return Int(pow(Double(x), Double(y)))
}

and now we are done!

Conclusion

As you can see Test-driven development, is simple and easy and maybe you would feel it’s unnecessary and you can skip part of it, but you can’t because it will not be TDD any more.

All you have to remember is the Red, Green, Refactor, and that’s it you focus on writing your tests and code and nothing else, and the more you work with TDD the more you will feel that you can’t live without it.

Before you go..

if you liked this article please do clap and share it with friends.

and if you wanted to have a discussion or reach me you can go to my website and get in touch.

Leave a Reply

Your email address will not be published. Required fields are marked *