Test-Driven Development (TDD)
Incase your team is not a cross-functional team, then in Agile, Quality assurance (QA) engineers are sometimes recognized as real managers/driving force/motive power as they demand that functionalities be out on time and frequently so that they could complete testing of all the functionalities to help team achieve their iteration (Sprint) goals. But what happens when it doesn’t happens?
At the end of the Iteration you might have completed coding (what developers believes) but as per Definition of Done (DoD) untested codes are not ready for Demo – remember the Agile principles which says “Working software is the primary measure of progress“.
Non-completion of testing/verifications are the major challenge many agile team face and is one of the major reason why many sprints (iterations) fails or teams not able to keep up with their promises (Iteration commitments).
Sometimes teams try to make iterations longer (non-agile way) expecting that they will be able to complete testing within iteration; or sometime completing a demonstrable functionality takes more than one iteration. This approach not only compromises on the agile principles of getting frequent customer feedback but also results in low team productivity – remember the Agile principles which says “Deliver working software frequently,…, with a preference to the shorter timescale.“.
As most of the organizations are certified on certain ISO/CMM level/Six Sigma process and guidelines, and they need to maintain the high quality code standards; but sometime Agile team argue quality auditors, “hey!! we are agile team, we don’t worry about number of defects or defect density, we are more worried about working code and Demo” – remember the Agile principles which says “customer satisfaction through early and continuous delivery of valuable software is the key”.
If the working software is buggy or have accumulated Technical debt, but due to delivery pressure, financial reasons or scarcity of funds, if we ignore Refactoring, remember the cost of maintenance later would be much higher, that’s why Agile team/Product Owners/Management should be cognisant of the Agile principle which says, “Continuous attention to technical excellence“
How often you noticed a developer saying this?
- “We don’t know what code is suppose to do”, because either they don’t understand the requirements or the big picture or it’s a legacy code
- “We can’t prove that our code is working without someone manually verifying that it works”
How often developers feels this?
- “We need to debug the code to see what’s happening inside”; and often root cause analysis takes much longer time.
- “Let us write the code from scratch, can’t maintain this code.”
So let’s find solution in Test-Driven Development approach and Refactoring….
Test-Driven Development (TDD)
What is TDD?
Test-driven development (TDD) is a software development process sometimes also called test-driven design. TDD is part of a larger software design paradigm known as Extreme Programming (XP). It’s one way to think through your requirements or design before you write your functional code.
Kent Beck, who is credited with having developed or ‘rediscovered’ the TDD technique, when asked, “Why does he refers to the rediscovery (not the invention) of test-driven development, he explained: The original description of TDD was in an ancient book about programming. It said you take the input tape, manually type in the output tape you expect, then program until the actual output tape matches the expected output.
After I’d written the first xUnit framework in Smalltalk I remembered reading this and tried it out. That was the origin of TDD for me. When describing TDD to older programmers, I often hear, “Of course, How else could you program?” Therefore I refer to my role as “rediscovering” TDD.
Test-driven development can produce applications of high quality in less time than is possible with older methods.
Proper implementation of TDD requires the developers and testers to accurately anticipate how the application and its features will be used in the real world. Problems are approached in an incremental fashion and tests intended for the same unit of code must often be done many times over.
Three Laws of TDD (as per Robert Cecil Martin ‘Uncle Bob‘)
- You are not allowed to write any production code unless it is to make a failing unit test pass.
- You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
- You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
TDD is both an important agile requirements and agile design technique.
When we are using TDD practice, the Professional Attitude should be
- Think about the tests first
- Break the problem into smaller units
- Treat the test code on par with production code
- Have test as documentation of actual code
- No real design needed
- Takes too much time
- Too complex to learn
- TDD means write all tests first
Steps followed in TDD:
- The first step is to quickly add a test, basically just enough code to fail.
- Next you run your tests, often the complete test suite (automated), to ensure that the new test does in fact fail.
- You then update your functional code to make it pass the new tests.
- Then run your tests again.
- If they fail you need to update your functional code and retest.
- Once the tests pass the next step is to start over.
Let’s compare the TDD when developing and running Acceptance tests and TDD in the case of actual application development.
Unit Testing: As Unit Testing is very important in TDD, make sure to write automated Unit Test suit using any of the xUnit frameworks, which is available for many languages, so that tests could be executed frequently, seamlessly and easily.
Challenges with Traditional approach (Design -> Implement -> Test) of software development:
- Sometimes when you are writing/modifying code, more bugs are introduced than fixed.
- Regression bugs are very common – Situation: something used to work then stops working due to some new feature or bug-fix
- Because of the threat of regression bug, manual testing takes a longer time – Retesting whole product: As product gets bigger, amount of time needed to test it becomes even more bigger
- As code grows bigger, it becomes more and more fragile – Chance of putting in bug when you are working on new code increases
Solution: Automated tests and running them every time you change code base allows you to verify, fix any new bug introduced immediately (quicker than long testing phase
at the end of development)
Refactoring is very important when following TDD.
Commonly used TDD Tools
TDD can be applied to any language and any IDE could be used
– C#, VB.NET, Java, Ruby, C++
– Eclipse, Visual Studio
– jUnit for Java
– nUnit for C#
– cppUnit for C++
– Mocking framework
– Refactoring plugins
– Continuous integration softwares
– Dependency injection framework
The following benefits we have achieved implementing TDD:
- We Incrementally translated the requirements to test units
- We Concentrate on requirements/tests, then concentrate on implementation
- We only wrote as much code as we needed to make the tests pass
- Our tests helped us design our code
- We had to write testable code
- We couldn’t cheat and not write the tests
- Our tests are documentation of what our code does
- We can quickly regression test our code
- We know that our code is working
- We know that our code will continue to work
Resource: I recommend watching this video “What is Test Driven Development (TDD)? With an example”
@Mohammad Sami -Agile Transformation Coach
255 total views, 6 views today