INTRODUCTION TO TEST DRIVEN DEVELOPMENT
What is Test-driven Development?
Test-driven development (TDD) is a software development approach in which test cases are developed using software requirements to specify and validate what the code will do before the software is fully developed. In another word, test-case for each functionality is created and tested first before actual development of the application.
Why use TDD?
Let’s assume you are a web developer. You have just finished creating user registration features. It is not enough to test this features just by interacting with the web browser, because part of the code might not be good enough and you are not sure what will happen when changes are made or new features introduced.
Many programmers think test-driven development is a good practice but there is never enough time to use it. However, the simple concept of TDD is to write and correct the failed tests before writing new code. This helps to avoid duplication of code as we write a small amount of code at a time in order to pass tests. According to Kent Beck (American software engineer) in 2003 stated that TDD encourage simple design and inspire confidence.
Test-driven Development cycle
The core of TDD revolves around five (5) simple steps which are repeated throughout software development life cycle. The aim is to ensure that code is simple and efficient while fulfilling all functional requirements.
Let’s take a look at the steps involve;
1. Add a test:
In test-driven development each new feature begins with writing a test. To write a test you must clearly understand the feature’s specification and requirements.
Let take user registration as an example. It encompasses features like generating form element, handling user entry, database connection and so on. However, it would be quite difficult to create a single test case that encompasses all these features.
Test-driven development encourages you to write the smallest possible test that is necessary to meet the needs of the actively developed feature.
For example, test case can be as small as checking input field is not blank.
2. Run all test to see if some test fail:
This step is to make sure that all test cases written are working correctly. It shows that the new test does not pass without requiring new code because it is expected that new code should be written to make a new test passed, and it rules out the possibility that the new test is flawed and will always pass. The new test should fail for the expected reason. This step increases the developer’s confidence in the new test.
By confirming that the new test fails — and does so for the reason(s) you expect — you can be confident that the test is useful, and will be beneficial once you write the code necessary to pass the test.
3. Write code to pass the test:
The next step is to write some code that causes the test to pass. Code written here will likely be rough and is subject to change numerous times in the future.
Write code to pass the input field not blank example in step 1.
4. Run the test:
Once your new code is written, confirm that the test passed. In our input field not blank example, submitting the registration form with blank fields will cause the test to fail while entering text in the input fields allows the test to pass. If all test cases passed, the programmer can be confident that the new code meets the test requirements and does not break any existing features.
5. Refactor code:
At this step, even though you now have the test passes, the process of writing the code that makes the test passed might have introduced some duplications and inconsistencies. The main purpose for refactoring is to fix those problems and also simplify the codebase.
Starting with another new test, the cycle is then repeated to push forward the functionality. The process is repeated with each new test slowly growing the entire codebase to a completed functional feature.
Another way for referring to the steps outlined above is called Red-green-refactor. A red test is a failing test because code did not exist, while a green test is a passing test after which the required code is written, and the refactor means checking the code structure and improve it without changing it external behavior.
By repeating this process for every single piece of functionality, a developer obtains full test code coverage, which will provide excellent design and easy application maintenance in the future.
The image below show a typical test-driven development cycle
There exists quite a common opinion that TDD is more time- consuming and costly. However, it is no doubt the case for the short-term only. TDD approach has obvious advantages in the long run, which attracts both customers and developers.