13 Aug

TDD – Test Driven Development

Test-driven development is related to the test-first programming concepts of extreme programming(https://en.wikipedia.org/wiki/Extreme_programming).

Life cycle of test-driven development

1. Write a test
2. Run the written test
3. Write code that corrects the failing test
4. Clean up your code
5. Go to step 1.

In test-driven development approach first step is to “write a test” and each new feature begins by writing a test. Developers must have clear understanding of the specifications/requirements before they start writing any test that defines the function or improvements of the function. The test-first programming for covering the requirements and exceptional conditions can be accomplished through use cases or user stories. This is a differentiating feature of test-driven development versus writing unit tests after the code is written. This makes the developer focus on the requirements before writing the code.

Second, run all tests including new tests using a collection of test data configured to test a program function under various conditions to validate whether tests are working properly or not. If new tests pass without requiring new code then the required behavior already exists.

Third step is to write some code that causes the test to pass. The new code written at this stage is not perfect and may, for example, pass the test in an inelegant way. That is acceptable because it will be improved during the refactor of the growing code base. Here the only purpose of the written code is to pass the test. The developer must not write code that is beyond the functionality that the test checks. If all test cases pass, the developer can be confident that the new code meets the test requirements, and does not break or degrade any existing features. If they do not, the new code must be adjusted until they do.

Fourth, the growing code base must be cleaned up regularly during test-driven development. Duplicate or redundant code must be removed in this phase. Object, class, module, variable and method names should clearly represent their current purpose and use to improve readability and maintainability. By continually re-running the test cases throughout each refactoring phase, the developer can be confident that process is not altering any existing functionality.

Fifth, starting with another new test, the cycle is then repeated to push forward the functionality. If new code does not rapidly satisfy a new test, or other tests fail unexpectedly, the programmer should undo or revert in preference to excessive debugging. Continuous integration helps by providing revertible checkpoints.

Here we will see the example to implement Fibonacci method using Java.

In Fibonacci series, next number is the sum of previous two numbers for example 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 etc. The first two numbers of Fibonacci series are 0 and 1.

The mathematical definition:

Let’s start. f(0) should be 0.

Write first test case

As we write this test we will get an compilation error complaining about the missing fibonacci method.

Let’s create the fibonacci method

Now running the test case makes the bar green.

Let’s create the test for fibonacci(1)=1

Running the above test cases will make the bar red, so update the fibonacci method as below

Now the bar will be green.

We should change the code inside the test cases because it has duplicate code. Therefore it will make one test for all possible values.

Now by extending the test cases as below it will make the bar red, i.e., tests fail.

Change the code as below to make it pass

But the above code can be written as

Even we can change the above code as below

Now you could write more test cases to test the code

And at the end the above code could be changed to

Thanks for reading.

Leave a Reply

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

Time limit is exhausted. Please reload CAPTCHA.