Showing posts with label TDD. Show all posts
Showing posts with label TDD. Show all posts

Tuesday, 8 March 2011

Leaders in Agile - TDD - Virtual conference

On Wednesday 2nd March I attended a virtual conference on Test Driven Development (TDD) hosted by bzmedia. Guest speakers were Kent Beck and Mark Seeman.



TDD is an Agile methodology where software is written in small increments by creating a test that fails then writing the code to make the software pass the test. Once passed, another test is created, the code implemented to pass the test and so on.

A test takes an input, defines an expected output and compares the actual output with the expected one

By breaking up the code into these small chunks (where each chunk should only take around 15mins), comprehensive unit tests are created, and design decisions are made, by the developer as the code is being produced.

The software is complete once you have run out of tests to implement.

In following this method it is possible to reduce the cost of fixing defects on the basis that the longer a defect exists, the longer it will take to find and fix.



unit tests


There are 2 types of tests: those that test the functionality/logic of the code and those that test the implementation. Implementation tests are owned by the software architect; the developer has ownership of the unit tests which test the logic in the code. It is the unit tests that form the basis of TDD and provide the framework required to develop working code.

Not all the functionality can or should be tested; focus on the most important logic

To effectively build unit tests the code needs to be abstract, i.e it needs to function as a separate unit to everything else. This way any external influence can be ruled out as a cause on the results of the test, if the code does have some dependencies then it should be possible to create test doubles which can be used to provide controlled input to the code being tested.



deferred design decisions


Throughout the development, design decisions are being made. The test will be given a name which can then be given to the object/function that is being tested, likewise the names of variables will come out of creating the test. In the end the test suite will define how to communicate with the code (the Interface)

Best practices should be strictly adhered to: objects/classes should be loosely coupled, refactor to avoid repeating yourself by creating helper objects/methods to facilitate code re-use. As the unit tests will already be in place for the existing functionality it will make it easier to validate the changes made during refactoring.



maintaining tests


One of the more challenging aspects of TDD is keeping the test suite up-to-date.

It is not unreasonable to expect twice as much test code as that in the actual software

Even though there will be a lot of test code it would not make sense to create tests for the test suite so the complexity of unit tests should be really simple.

Refactoring is an important part of maintenance so helper methods/classes/frameworks should be used to isolate complexity, this comes at a cost though of creating coupling. The dependency of the tests on the helper methods means that one of the biggest challenges is writing the interface for them as any change to it could break many tests. It is important to minimise the coupling and therefore the chances of creating these fragile tests as they tend to get abandoned or changed when they break.
The code is written to pass the test; the test is not written to pass the code


Summary



  • Reduced defect costs

  • Defer bugs to the test suite rather than the software

  • Software designed during development, by developer

  • Tests are written one at a time

  • Tests should be written to fail, then software coded to pass

  • Tests are automated

  • Keep time tests take to run minimal

  • Outsourcing development isnt Agile