A Brief Introduction to Test Driven Development (TDD) in Swift & iOS

Enes Buğra Yenidünya
Geek Culture
Published in
6 min readJun 21, 2021

What is Test Driven Development (TDD)

Test-driven development (TDD) is a software development process relying on software requirements being converted to test cases before software is fully developed, and tracking all software development by repeatedly testing the software against all test cases. This is opposed to software being developed first and test cases created later.

See the wikipedia for more details.

Test Driven Development Cycle

There are 5 steps in the TDD flow:

  1. Read, understand, and process the feature or bug request.
  2. Translate the requirement by writing a unit test. If you have hot reloading set up, the unit test will run and fail as no code is implemented yet.
  3. Write and implement the code that fulfills the requirement. Run all tests and they should pass, if not repeat this step.
  4. Clean up your code by refactoring.
  5. Rinse, lather and repeat.
Test Driven Development Cycle

Test Driven Development in Xcode

We will write our first test method on Xcode with an example project. Also I will proceed by performing 5 steps with a scenario suitable for the cycle I mentioned above.

1-) Feature Request

Let’s say there is a feature request forwarded to us by our Product Owner. It’s content is as follows, the password entered by the user must be validated before registration. Here is the validation rule:
- Passwords entered by the user must be equal to each other.

2-) Red

Let’s jump into Xcode and write our failing test method. Note the name of the test function and the comment lines inside.

Failing Test Method

As you can see in the screenshot above, the name of the function is too long. This is because of an unwritten test method naming convention using by the developers. The steps are as follows:

test<SystemUnderTest>_>ConditionOrStateChange>_<ExpectedResult>

  1. The name of the method must start with the word “test” or Xcode does not detect the method.
  2. “System Under Test” must be placed after the word “test”.
  3. “Condition or State Change” after underscore.
  4. “Expected Result” after another underscore.

There are 3 comments lines in the method. It’s called The AAA Pattern.

Arrange: Also known as “Given”. It is the part where all variables and models are defined.

Act: Also known as “When”. It is the part where the method to be tested is triggered and the result is returned.

Assert: Also known as “Then”. This is the part where the expected result is evaluated.

We started to write our test method and got an error. The reason for our error is that we do not have a class with the name we specified. For this reason we will now create our validator class. And then we will jump into Act part, trigger our isPasswordValid() method. Now we got an error again.

Failing Test Method

As you can see, we follow the TDD Cycle steps. So, next step is to write our isPasswordValid() method.

Completed Test Method

After implementing of isPasswordValid() method, error gone away and we implemented the Assert part. There is a “XCTAssertTrue” Assertion. But wait a second, what is Assertions?

Assertions

A test assertion’s main role is to compare a certain result against a control value, and to fail the current test if those two values don’t match. All unit test methods use Assertions to validate the result produced by the System Under the Test and present the user with a test method result. It is the assertion that will make a decision whether the test method is passing or failing. If you want to deep dive about “Assertions”, at the and of the article I will share two different article links about it.

3-) Green

As the last step, we run the test method we wrote and we see that our isPasswordValid() method passed the test successfully.

Passed Test Method

This means that we have now passed the 3rd step of Test Driven Development Cycle, the Green step.

4-) Refactor

Suppose we refactored to both our isPasswordValid() method and our test method.

5-) Repeat

Now that everything is great, we can continue to write unit test methods for new feature requirements or existing features.

Benefits

  1. Fosters the creation of optimized code.
  2. Helps developers better analyze and understand client requirements and request clarity when they are not adequately defined.
  3. The addition and testing of new functionalities become much easier in the latter stages of development.
  4. Test coverage under TDD is much higher compared to the conventional development models. This is because the TDD focuses on creating tests for each functionality right from the beginning.
  5. Enhances the productivity of the developer and leads to the development of a codebase that is flexible and easy to maintain

Limitations

  1. Big time investment. For the simple case you lose about 20% of the actual implementation, but for complicated cases you lose much more.
  2. Additional Complexity. For complex cases your test cases are harder to calculate, I’d suggest in cases like that to try and use automatic reference code that will run in parallel in the debug version / test run, instead of the unit test of simplest cases.
  3. Design Impacts. Sometimes the design is not clear at the start and evolves as you go along — this will force you to redo your test which will generate a big time lose. I would suggest postponing unit tests in this case until you have some grasp of the design in mind.
  4. Continuous Tweaking. For data structures and black box algorithms unit tests would be perfect, but for algorithms that tend to be changed, tweaked or fine tuned, this can cause a big time investment that one might claim is not justified. So use it when you think it actually fits the system and don’t force the design to fit to TDD.

Conclusion

Following Test Driven Development allows us to make our code cleaner and more understandable, to make sure that all of our logics are tested and are working correctly. This is for sure. As I mentioned above, there are pros and cons. It will definitely be useful to do sample projects to learn and apply more. You can find the relevant links below and get more detailed information.

I hope you now have an idea about Test Driven Development. Please don’t forget to share so others can benefit as well. Feel free to contact with me via my email or Linkedin.

Follow me on Twitter, GitHub and Linkedin.

Resources

--

--

Enes Buğra Yenidünya
Geek Culture

iOS Engineer — Freelancer #iOS #swift #mobileappdevelopment #software #apple