Blog/Development

What is Test Driven Development(TDD)?

Share:

Facebook
Twitter
Linkedin
Copy link
Copy Link

author

Praise Iwuh

January 23, 2023

What is Test Driven Development(TDD)?

 

Test-driven development (TDD) is a methodology in software development that prioritises testing before production. This approach involves running tests and then using their outcome to determine what code to write. It is also known as Test First Development.


TDD involves short repetitive development cycles that base testing on software requirements rather than just code implementation.

The process begins with writing test cases for every unit of an application and then writing code to pass that test specifically. It is an iterative method of development that comprises building, testing and design (refactoring) to enhance code accuracy and product functionality.


This article aims to discuss TDD in simple terms. It is outlined as follows: 


  • What is TDD? 
  • What is Testing? 
  • Performing TDD Testing 
  • Types of TDD 
  • TDD in Agile development 
  • Tools for TDD 
  • Conclusion 

 

What is Test Driven Development(TDD)?


Test-driven development (TDD) is an Agile software development methodology focusing on testing before writing code. It aims to ensure that the codebase is error-free and that it adheres to the project's requirements. By writing tests first, developers can quickly identify issues with the code and make necessary changes to ensure that the code works as expected.


The process of test-driven development begins with writing an automated unit test for a specific feature of the code. The test should evaluate the feature for any errors and should fail if the feature does not meet the requirements. Once this test has been written, the developer can write the feature's production code. When the code is written, it can be tested against the unit test to ensure it works as expected.


TDD encourages developers to think about the design of the code before writing it. By writing tests first, developers can consider the design of the code and ensure that it meets the project's requirements. This helps prevent any potential issues arising from having poorly designed code.


A unit is the smallest testable functional part of an application, and by running unit testing 

before writing code, TDD enables developers to avoid bugs during the coding process. The 

concept of TDD is to write and correct the failed tests before production(writing code).  


Another benefit of test-driven development is that it helps to ensure that the codebase remains stable. By writing tests for each feature, any changes made to the code can be quickly evaluated against the tests to ensure that it does not break any existing code. This helps to ensure that the codebase remains stable and that any changes to the code do not introduce any new errors.


What is Testing?

Testing is the process of ensuring that a program or application is functional for the specified purpose for which it was developed. It determines if your code does what you have written it to do and is a critical component of any software development lifecycle, as it saves time, cost and inconveniences of deploying flawed products. It can generally be approached either manually or through automation.


Manual Testing: Manual testing involves physically navigating your application or code to test functionality and uncover bugs or vulnerabilities. 

 

Automated Testing: Automated testing, on the other hand, uses written code to scan other code for functionality and shortcomings. As a result, automated testing is typically broader and faster.


Using both methods in tandem is the recommended procedure for thorough testing. This way, you can locate and uncover both known and unknown vulnerabilities.

   

Performing TDD Testing


Test-driven development focuses on specifying what function your program should perform, creating a test, and then writing just enough code to pass that test.


Basically, the TDD cycle is defined by the following steps: 


  • Write a unit test specifying the program requirements
  • Run a failing test 
  • Write code to pass the test 
  • Refactor the code until it meets the satisfaction 
  • Repeat unit tests over time 


The three major phases of TDD testing are Red, Green and Refactor. 

 

Create Unit Test (Red)

The initial step is to create a test based on the specific functions of the product you plan to make and then run it. This test should fail because you have not applied any code. The key motivation at the red stage is "what" to develop.

 

Create the Code (Green)

The next step involves writing code to pass that test in the simplest way possible. The aim is to quickly find the most straightforward solution by writing just enough code to pass the test. Once this test is passed, you can move on to optimisation in the next stage. Here the question is "how" to develop.

 

Refactor

The goal at this stage is not to fix code but to improve and optimise it to suit the specified requirement better and to deliver the best performance. Developers should take care during refactoring to avoid altering the program's external behaviour. The important questions to ask here are "what can I do more efficiently?"  


  • Can my test suite be more expressive? How? 
  • Can I make my code more descriptive? How? 
  • Can my test suite provide more reliable feedback? How? 
  • Can I reduce duplication in my code? How? 


Principles of TDD

Write the test first

More traditional software development methodology involves writing code and testing it later. On the other hand, Test Driven Development flips the script by requiring developers to write a test first, run the test and then improve on the code.

 

Write enough code to pass the test

The aim is to write a quick first test (first development) and make it pass with the simplest change to the production code possible.


Subsequent code updates and testing

Depending on the result of the test, the outcome is either 'red' or 'green'. A test that has passed is represented as green, and you can refactor from one green test to another. Following a refactor, if all tests are green, you can proceed to your next failing test. 

 

Example 

Here we depict an example of TDD using a non-technical subject such as building a shed: 

 

1. You expect the shed to be two metres high. 

2. The test fails because you have built no shed. 

3. You erect a pillar and put a thatch roof on it.  

4. The test passes. 

 

Next: 

1. You expect the shed to cover an area of eighty square metres.  

2. The test fails because you only use one pillar and a handful of thatch. 

3. You add three more pillars and expand your roofing. 

4. The test passes. 

 

Next: 

1 ∙You expect the shed to withstand heavy rainfall and wind. 

2∙ The test fails because the pillars are lightweight and unprotected. 

3∙ You build a wall around the pillars. 

4∙ The test passes. 

 

This would continue on and on until the shed is complete. 

 

Importance of failing tests 

While it may seem like wasting time, failed tests are as essential as passed ones. This is because it points out that all code used is necessary and functional. Failing tests help you better identify your product goal, its challenges, and how to surpass them.

 

Types of TDD 

There are two major types of Test-driven development models: 

Acceptance TDD (ATDD)

An acceptance test is a formal description of the expected behaviour of a software product as written from an end user's point of view. Acceptance TDD involves testing to meet the requirements of the end user as specified in the acceptance test before developing code. It is almost identical to Behaviour-driven development(BDD), with the major difference being that ATDD prioritises the accuracy of specified requirements, while BDD emphasises overall user behaviour.


Developer TDD (DTDD)

This is the basic TDD testing where a developer creates a unit test before writing production code to pass that test. A unit is the smallest testable functional part of a system, and by running unit testing before writing code, TDD enables developers to avoid bugs during the coding process.


TDD in Agile development

Agile development is an ever-evolving and constantly improving methodology that thrives on conti nous feedback. Iteration and incremental development characterise the Agile SDLC, and this means TDD is tailor-made for Agile. The by-product of its test-first nature is that feedback is received and implemented early and continuously through every phase of the project. By translating customer feedback into bug fixes and adding new features, the system regularly adapts to make everything work as intended.


Relationship with Agile Model Driven Development (AMDD) 

Agile model-driven development is an approach to software development where extensive models are created before writing source code. AMDD plays an essential role in scaling agile software development. It is also useful for scaling TDD because although it excels at detailed specification and validation, TDD could be less functional for the overall design. Since the detailed specification is only a part of the entire picture, we sometimes need to look past TDD to utilise AMDD. Below is a detailed process of scaling TDD using AMDD.


Envisioning

Typically done on the first week of an initiative, this is the process of picturing tests, identifying your system's scope, and developing an architecture for it. The goal is to explore the requirements and define an overall strategy. This involves high-level requirements and architecture modelling.  

 

Iteration modelling

This is where the team defines the work to be done in every iteration. Work items will be added incrementally in every iteration. Items with higher priority are taken into consideration, and the team decides how to implement the specified requirements.


Model storming

Involves a team deliberating issues on a whiteboard or paper. This session will take an estimated 5 to 10 minutes, during which team members gather together to share the whiteboard. When a team member identifies an issue they want to resolve, they seek help from other teammates. The group members then assess the issue and carry on. They will analyse the issues until they cannot find the major problems.


 

Executable specification using Test-driven Development (TDD)

An executable specification is an automated test that shows and verifies how the application delivers a specific requirement. The automated tests are part of the production process and run whenever a change is made to the application. During development, it is normal for the team to model storm for several minutes before coding and refactoring, for as long as several days at a time to implement the model. This is where the team members will spend most of their time.


Agile teams do most of their detailed modelling through executable specifications, often customer tests or development tests. This works because model storming assists thinking through larger, cross-entity issues, while TDD teaches you to think through focused issues pertinent to a single entity at a time. With refactoring, you can make little adaptations to your design while your program maintains high quality.

 

Reviews

This encompasses model reviews and even code inspections. It is optional and can be done either for single iterations or the entire project. It is an excellent source of feedback.



Difference between TDD and AMDD

TDD

AMDD

TDD refers to Test Driven Development.

 

AMDD refers to Agile Model Driven Development.

 

TDD  develops the test cases before the

software is fully developed and makes

necessary updates based on test results

AMDD is an Agile version of Model Driven Development (MDD), where extensive models are designed before source code is written.

 

This technique focuses more on the

implementation of a feature.

This technique focuses more on the

implementation of functionality.

It shortens the programming feedback

loop

It shortens the modelling feedback loop

It does not address the agile scaling

issues.

It addresses the Agile scaling issues.

It promotes the development of high-

quality code.

It promotes high-quality communication with stakeholders and developers.

It provides detailed specifications.

It is better for thinking through bigger

issues

Participants are programmers.

Participants are stakeholders, data

professionals, and business analysts.

It is not visually oriented.

It is visually oriented

TDD has a more limited scope than AMDD

AMDD has a larger scope than TDD



 

 

Advantages of TDD 

The following are the main advantages of Test Driven Development in Software Engineering: 

 

Identify bugs early

A test-first approach uncovers bugs very early in the development cycle. It also gives more precise insight into understanding the requirements and how to use codes to meet them. TDD ensures that all production codes pass tests based on user requirements.


Enhance overall design

TDD addresses one small feature at a time. This means every unit is independently tested, resulting in more efficiently written code than broader focused testing methods.

 

Detailed documentation

These tests can act as documentation. The TDD process details how code works and the changes in the project, resulting in well-structured documentation and a clear roadmap of the whole project.


 

Better code quality and flexibility

In TDD, developers visualise which specific problems they aim to solve before testing and writing code. This results in the delivery of high-quality products with fewer flaws and cleaner code.

 

Lower costs

By reducing flaws, minimising bugs, making code maintenance more manageable, and improving general efficiency, Test-driven development can significantly decrease the project's cost. A joint study by Microsoft and IBM showed that four development teams who adopted TDD recorded a 40-90% reduction in their defect density.


Disadvantages of TDD

 

Slow development process

Because developers must first write tests must and run them for failure, the TDD method can stall the development cycle longer than necessary. The preoccupation of developers with building test cases allows them less time to work on code. In a project with limited timelines, this can be a big negative.

 

Difficult to learn and operate

Test-driven development requires a higher modelling skillset than most developers have. 

 

Difficult to maintain and support

The need to adapt to changes in user requests can be a bother, as code will be adapted or created to run new tests for each request. Also, the bigger project is, the more difficult it is to maintain the multiple unit tests.


Frameworks for Test-Driven Development 


Many frameworks support test-driven development. Some popular ones among them are: 

 

csUnit: An open-source  tool for .Net projects unit testing 

DocTest: A unit testing framework for Python testing framework 

JUnit: A unit testing framework for Java. 

NUnit: A .Net projects TDD testing framework 

PHPUnit: A PHP projects testing framework 

PyUnit: A Python unit testing framework  

TestNG: A Java testing framework 

RSpec: A framework for Ruby projects. 

 


When to use TDD 

 

The Test-driven development model is best applied in environments where:  


  • You are trying to define layers within your application 
  • You have detailed specifications of the design, business decisions and budget and time constraints
  • You have a small-scale project 
  • You are working in a team

 

Conclusion

Overall, test-driven development is an important tool for software development. By writing tests first, developers are able to ensure that the code works as expected and that any changes to the code do not introduce any new errors. This helps to ensure that the codebase remains stable and that the project meets its requirements. TDD improves feedback and correctness and gives you a framework to clearly visualise your code at an early stage.

Related post

Recent Posts

Need help with a project?

Let's solve it together.