際際滷

際際滷Share a Scribd company logo
Test Driven Development
Objective
To realise productivity and quality gains by making extensive use of Test Driven Development
Abstract
(Abstract and TDD details taken from: http://en.wikipedia.org/wiki/Test-driven_development)
TDD relies on the repetition of a very short development cycle: First the developer writes an (initially failing) automated test case that defines a desired
improvement or new function, then produces the minimum amount of code to pass that test and finally refactors the new code to acceptable standards. Kent
Beck, who is credited with having developed or 'rediscovered' the technique, stated that TDD encourages simple designs and inspires confidence.
Proposals
Develop tests for functionality of components - rather than just to test one Jira, and keep them up to date.
Implement Continuous Integration either during the nightly build or on code check-in to SVN. Automated regression tests should enable us to develop new
code and refactor with confidence that we havent broken anything. If any test fails then we will break the whole build!
Incorporate in the Continuous Integration, code analysis tools such as 'Emma' (Check % of code covered by the tests) and 'Findbugs' (Static analysis of the
java code for bugs inc. concurrency issues)
Avoid the problem of tests written by the developer sharing the same blind spots with his code by having another developer, or better yet a tester, write them.
This last proposal is probably controversial but, I think, key to improving quality.
Whilst not going as far as 'pair programming' it would enable us to implement the 'four eyes' principle - at least two people would be independently involved in
the production of every unit of software.
Also, there is much less chance of requirements being misunderstood and any lack of clarity or misunderstanding that does occur can be caught earlier.
Ideally, before a line of code is written.
Finally, it should; help avoid 'scope creep', facilitate knowledge transfers and front-load the testing effort so we can identify problems earlier rather than at the
point of delivery. For example, if the requirements change, the tests will have to be re-written and everyone involved (management, testers and developers)
will be aware of the issue.
TDD Cycle
Add a test
Write a test which, must inevitably fail as the code implementation has not yet been written. As opposed to writing tests after the code is developed this forces
the developer to focus on the requirements before writing the code.
Run all tests and see if the new one fails
This validates that the test harness is working correctly and that the new test does not mistakenly pass without requiring any new code. This step also tests
the test itself ruling out the possibility that the new test will always pass, and therefore be worthless - it should fail for the expected reason!
Write some code
that will cause the test to pass. This code will not be perfect and may, for example, pass the test in an inelegant way. This is acceptable because later steps
will improve and hone it. Important that the code written is only designed to pass the test. No further (and therefore untested) functionality should be predicted
and 'allowed for' at any stage.
Run the automated tests and see them succeed
If all test cases now pass, the programmer can be confident that the code meets all the tested requirements. This is a good point from which to begin the final
step of the cycle.
Refactor code
Improve the code as necessary to attain production quality standards. By re-running the test cases, the developer can be confident that code refactoring is not
damaging any existing functionality.
Remove any artifacts that were introduced - for example magic numbers or strings - in order to make the test pass in earlier stages
Repeat
Starting with another new test, the cycle is then repeated to push forward the functionality. The size of the steps should always be small, with as few as 1 to
10 edits between each test run. 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.
Code Visibility
Test suite code clearly has to be able to access the code it is testing. On the other hand, normal design criteria such as information hiding, encapsulation and
the separation of concerns should not be compromised. Therefore unit test code for TDD is usually written within the same project or module as the code
being tested.
There is some debate among practitioners of TDD, as to whether it is wise to test private methods and data.
Some argue that private members are a mere implementation detail that may change, and it should be sufficient to test any class through its public interface
or through its subclass interface. Others say that crucial aspects of functionality may be implemented in private methods, and that developing this while testing
it indirectly via the public interface only obscures the issue.
My view is that if the private members have no discernible effect on the public behaviour of a class then of what use are they?
Or to paraphrase Danny Blanchflower  if theyre not interfering with play, then what are they doing in the codebase?
In other words, if invoking all the public methods does not, in turn, invoke all the private methods then when may we expect them to be invoked  if ever?
Stubs,mocks and integration tests
When code under development relies on a database, a web service, or any other external process or service, enforcing a unit-testable separation is also an
opportunity and a driving force to design more modular, more testable and more reusable code.
Two steps are necessary:
An interface should be defined that describes the access that will be available.
The interface should be implemented in two ways, one of which really accesses the external process, and the other of which is a Stub or a Mock
Stub objects need do little more than add a message such as Person object saved to a trace log, against which a test can be run to verify correct behaviour.
Mock objects differ in that they themselves contain assertions that can make the test fail, for example, if the person's name and other data are not as
expected.
Shortcomings
Test-driven development is difficult to use in situations where full functional tests are required to determine success or failure, e.g. user interfaces, programs
that work with databases, and some that depend on specific network configurations.
Unit tests created in a test-driven development environment are typically created by the developer who will also write the code that is being tested. The tests
may therefore share the same blind spots with the code.
The high number of passing unit tests may bring a false sense of security, resulting in fewer additional software testing activities, such as integration testing
and compliance testing.
The tests themselves become part of the maintenance overhead of a project. Badly written tests, for example ones that include hard-coded error strings or
which are themselves prone to failure, are expensive to maintain. It is possible to write tests for low and easy maintenance, for example by the reuse of error
strings, and this should be a goal during the code refactoring phase described above.
There is a risk that tests that regularly generate false failures will be ignored, so that when a real failure occurs it may not be detected.
The level of coverage and testing detail achieved during repeated TDD cycles cannot easily be re-created at a later date. Therefore these original tests
become increasingly precious as time goes by. If a poor architecture, a poor design or a poor testing strategy leads to a late change that makes dozens of
existing tests fail, it is important that they are individually fixed. Merely deleting, disabling or rashly altering them can lead to undetectable holes in the test
coverage.
FindBugs
Abstract
'FindBugs' is an example of a static code analysis tool.
It does not run any test cases and in fact knows nothing about the logic of your code. It simply examines it, without actually running it, for what are generally
considered to be bug patterns and bad practices.
As part of a comprehensive programme of code reviews it can be invaluable to catch hard-to-spot coding errors. (Human code review is still necessary)
It is available under an open source licence from 'SourceForge' and takes only a few minutes to install.
Once installed you can use either the built-in GUI, command line tools or plugins (e.g. for Eclipse) to run tests. You need to tell 'FindBugs' where your source
and byte code are and any external classes or jars required to compile it.
Locating the external classes can be tricky if 'FindBugs' reports that it cannot check all your code because a particular class is missing.
Probably easiest to just add every jar/class on your classpath, to begin with.
Example Bug
This check was run against the entire java code base of an application and found 148 possible bugs.
These vary in seriousness and some discretion needs to be exercised in determining if any action is required.
This example is of synchronization using a 'ConcurrentHashMap' (a member of the java.util.concurrent package) as a lock object. Careful analysis is required
to decide if there are going to be a problems with this or not.
There is no point in locking using 'concurrent' classes as they are internally guarded against concurrent access in such a way as to allow multiple threads to
access them at the same time. E.g. in this case each hash bucket will be guarded by a separate lock.
Unless more than one thread tries to access the same bucket concurrently they will be allowed to read/write the map's contents (Except if this code snippet is
the only code that can access the map. That is not the case here as 'status' is exposed through a public method 'handleTick()' which employs no
synchronization when accessing it - correctly, of course)
If the program's correctness does not depend on only one thread at a time being able to access the map then there will probably be no problem with this. For
example, if it's just a case of being a bit over-zealous with the synchronization of something that doesn't need synchronizing.
If the correctness of the program does depend on exclusive access to the map then this code is broken.
At best, this indicates something that should be explained. Why try to lock something that cannot be locked? If you do want exclusive access then why are you
using a 'ConcurrentHashMap'? On a wider note, synchronizing access to ANY resource and then allowing public unsynchronized access to it through another
method, or by synchronizing on a different lock object, is not threadsafe!
Another issue...
NOT picked up by 'FindBugs', is in the public method 'handleTick()'. The return values of putIfAbsent() are ignored!
status.putIfAbsent(info.tickNum, new TickStatus(info.tickNum, info.instrId));
statusInstruments.putIfAbsent(key, new InstrumentStatus(key));
If a non-null value is returned from putIfAbsent() , then the put operation failed and the value returned is the value already associated with the key!

More Related Content

What's hot (15)

A Not-So-Serious Introduction to Test Driven Development (TDD)
A Not-So-Serious Introduction to Test Driven Development (TDD) A Not-So-Serious Introduction to Test Driven Development (TDD)
A Not-So-Serious Introduction to Test Driven Development (TDD)
CodeOps Technologies LLP
Unit Testing
Unit TestingUnit Testing
Unit Testing
Fran巽ois Camus
Google test training
Google test trainingGoogle test training
Google test training
Thierry Gayet
Unit testing
Unit testing Unit testing
Unit testing
dubbu
Test Driven Development (TDD) Preso 360|Flex 2010
Test Driven Development (TDD) Preso 360|Flex 2010Test Driven Development (TDD) Preso 360|Flex 2010
Test Driven Development (TDD) Preso 360|Flex 2010
guest5639fa9
Ian Cooper webinar for DDD Iran: Kent beck style tdd seven years after
Ian Cooper webinar for DDD Iran: Kent beck style tdd   seven years afterIan Cooper webinar for DDD Iran: Kent beck style tdd   seven years after
Ian Cooper webinar for DDD Iran: Kent beck style tdd seven years after
Iranian Domain-Driven Design Community
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
Mireia Sangalo
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
guestc8093a6
Understanding Unit Testing
Understanding Unit TestingUnderstanding Unit Testing
Understanding Unit Testing
ikhwanhayat
TDD - Test Driven Development
TDD - Test Driven DevelopmentTDD - Test Driven Development
TDD - Test Driven Development
Tung Nguyen Thanh
Test driven development
Test driven developmentTest driven development
Test driven development
Harry Potter
Test driven development - Zombie proof your code
Test driven development - Zombie proof your codeTest driven development - Zombie proof your code
Test driven development - Zombie proof your code
Pascal Larocque
Engaging IV&V Testing Services for Agile Projects
Engaging IV&V Testing Services for Agile ProjectsEngaging IV&V Testing Services for Agile Projects
Engaging IV&V Testing Services for Agile Projects
Ravi Kumar
iOS Test-Driven Development
iOS Test-Driven DevelopmentiOS Test-Driven Development
iOS Test-Driven Development
Pablo Villar
Test-Driven Development (TDD)
Test-Driven Development (TDD)Test-Driven Development (TDD)
Test-Driven Development (TDD)
Brian Rasmussen
A Not-So-Serious Introduction to Test Driven Development (TDD)
A Not-So-Serious Introduction to Test Driven Development (TDD) A Not-So-Serious Introduction to Test Driven Development (TDD)
A Not-So-Serious Introduction to Test Driven Development (TDD)
CodeOps Technologies LLP
Google test training
Google test trainingGoogle test training
Google test training
Thierry Gayet
Unit testing
Unit testing Unit testing
Unit testing
dubbu
Test Driven Development (TDD) Preso 360|Flex 2010
Test Driven Development (TDD) Preso 360|Flex 2010Test Driven Development (TDD) Preso 360|Flex 2010
Test Driven Development (TDD) Preso 360|Flex 2010
guest5639fa9
Ian Cooper webinar for DDD Iran: Kent beck style tdd seven years after
Ian Cooper webinar for DDD Iran: Kent beck style tdd   seven years afterIan Cooper webinar for DDD Iran: Kent beck style tdd   seven years after
Ian Cooper webinar for DDD Iran: Kent beck style tdd seven years after
Iranian Domain-Driven Design Community
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
Mireia Sangalo
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
guestc8093a6
Understanding Unit Testing
Understanding Unit TestingUnderstanding Unit Testing
Understanding Unit Testing
ikhwanhayat
TDD - Test Driven Development
TDD - Test Driven DevelopmentTDD - Test Driven Development
TDD - Test Driven Development
Tung Nguyen Thanh
Test driven development
Test driven developmentTest driven development
Test driven development
Harry Potter
Test driven development - Zombie proof your code
Test driven development - Zombie proof your codeTest driven development - Zombie proof your code
Test driven development - Zombie proof your code
Pascal Larocque
Engaging IV&V Testing Services for Agile Projects
Engaging IV&V Testing Services for Agile ProjectsEngaging IV&V Testing Services for Agile Projects
Engaging IV&V Testing Services for Agile Projects
Ravi Kumar
iOS Test-Driven Development
iOS Test-Driven DevelopmentiOS Test-Driven Development
iOS Test-Driven Development
Pablo Villar
Test-Driven Development (TDD)
Test-Driven Development (TDD)Test-Driven Development (TDD)
Test-Driven Development (TDD)
Brian Rasmussen

Viewers also liked (17)

published paper
published paperpublished paper
published paper
Amara CHIKE
Daily agri commodity report by epic research of 17 january 2017
Daily   agri commodity report by epic research of  17   january 2017Daily   agri commodity report by epic research of  17   january 2017
Daily agri commodity report by epic research of 17 january 2017
Epic Research
Mapa mental de autoestimaMapa mental de autoestima
Mapa mental de autoestima
Ana Pacheco
Corona chair campos-torres-velez
Corona chair campos-torres-velezCorona chair campos-torres-velez
Corona chair campos-torres-velez
Hector Torres
Daniela espinoza hardware.pptDaniela espinoza hardware.ppt
Daniela espinoza hardware.ppt
Espinoza0599
Consell Escolar Municipal de Barcelona, consell educatiu de la ciutat
Consell Escolar Municipal de Barcelona, consell educatiu de la ciutatConsell Escolar Municipal de Barcelona, consell educatiu de la ciutat
Consell Escolar Municipal de Barcelona, consell educatiu de la ciutat
Ajuntament de Barcelona
Covariance vs Correlation
Covariance vs CorrelationCovariance vs Correlation
Covariance vs Correlation
Aniruddha Deshmukh
portfolio final
portfolio finalportfolio final
portfolio final
Amy Powell
Levonorgestrel.Levonorgestrel.
Levonorgestrel.
anette paniagua
DiapogramaDiapograma
Diapograma
Alejandro Guanochanga
Custom Filled Aerosol print
Custom Filled Aerosol printCustom Filled Aerosol print
Custom Filled Aerosol print
BEN WATSON
Macam-Macam Fungsi
Macam-Macam FungsiMacam-Macam Fungsi
Macam-Macam Fungsi
Ana Sugiyarti
Entrevista Entrevista
Entrevista
Karla Hern叩n
containerd and what it means for the container ecosystem
containerd and what it means for the container ecosystemcontainerd and what it means for the container ecosystem
containerd and what it means for the container ecosystem
Justin Steele
Intermediate Level Apprenticeship in Customer Service in the Business Skills ...
Intermediate Level Apprenticeship in Customer Service in the Business Skills ...Intermediate Level Apprenticeship in Customer Service in the Business Skills ...
Intermediate Level Apprenticeship in Customer Service in the Business Skills ...
Anthony Fowler
BFZoo handouts
BFZoo handoutsBFZoo handouts
BFZoo handouts
Brittany Hull
Jay Casey PhD CV Oct 2016
Jay Casey PhD CV Oct 2016Jay Casey PhD CV Oct 2016
Jay Casey PhD CV Oct 2016
Jay Casey
published paper
published paperpublished paper
published paper
Amara CHIKE
Daily agri commodity report by epic research of 17 january 2017
Daily   agri commodity report by epic research of  17   january 2017Daily   agri commodity report by epic research of  17   january 2017
Daily agri commodity report by epic research of 17 january 2017
Epic Research
Mapa mental de autoestimaMapa mental de autoestima
Mapa mental de autoestima
Ana Pacheco
Corona chair campos-torres-velez
Corona chair campos-torres-velezCorona chair campos-torres-velez
Corona chair campos-torres-velez
Hector Torres
Daniela espinoza hardware.pptDaniela espinoza hardware.ppt
Daniela espinoza hardware.ppt
Espinoza0599
Consell Escolar Municipal de Barcelona, consell educatiu de la ciutat
Consell Escolar Municipal de Barcelona, consell educatiu de la ciutatConsell Escolar Municipal de Barcelona, consell educatiu de la ciutat
Consell Escolar Municipal de Barcelona, consell educatiu de la ciutat
Ajuntament de Barcelona
portfolio final
portfolio finalportfolio final
portfolio final
Amy Powell
Levonorgestrel.Levonorgestrel.
Levonorgestrel.
anette paniagua
Custom Filled Aerosol print
Custom Filled Aerosol printCustom Filled Aerosol print
Custom Filled Aerosol print
BEN WATSON
Macam-Macam Fungsi
Macam-Macam FungsiMacam-Macam Fungsi
Macam-Macam Fungsi
Ana Sugiyarti
Entrevista Entrevista
Entrevista
Karla Hern叩n
containerd and what it means for the container ecosystem
containerd and what it means for the container ecosystemcontainerd and what it means for the container ecosystem
containerd and what it means for the container ecosystem
Justin Steele
Intermediate Level Apprenticeship in Customer Service in the Business Skills ...
Intermediate Level Apprenticeship in Customer Service in the Business Skills ...Intermediate Level Apprenticeship in Customer Service in the Business Skills ...
Intermediate Level Apprenticeship in Customer Service in the Business Skills ...
Anthony Fowler
Jay Casey PhD CV Oct 2016
Jay Casey PhD CV Oct 2016Jay Casey PhD CV Oct 2016
Jay Casey PhD CV Oct 2016
Jay Casey

Similar to TestDrivenDeveloment (20)

Testing Experience - Evolution of Test Automation Frameworks
Testing Experience - Evolution of Test Automation FrameworksTesting Experience - Evolution of Test Automation Frameworks
Testing Experience - Evolution of Test Automation Frameworks
ukasz Morawski
TDD Workshop UTN 2012
TDD Workshop UTN 2012TDD Workshop UTN 2012
TDD Workshop UTN 2012
Facundo Farias
Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++
Hong Le Van
Unit Testing Guide. Helps to understand the basics of unit testing .
Unit Testing Guide. Helps to understand the basics of unit testing .Unit Testing Guide. Helps to understand the basics of unit testing .
Unit Testing Guide. Helps to understand the basics of unit testing .
shradha339475334115
Test driven development
Test driven developmentTest driven development
Test driven development
Tony Nguyen
Test driven development
Test driven developmentTest driven development
Test driven development
Luis Goldster
Test driven development
Test driven developmentTest driven development
Test driven development
Fraboni Ec
Test driven development
Test driven developmentTest driven development
Test driven development
Young Alista
Test driven development
Test driven developmentTest driven development
Test driven development
James Wong
Test driven development(tdd)
Test driven development(tdd)Test driven development(tdd)
Test driven development(tdd)
Omar Youssef Shiha
What Is Unit Testing A Complete Guide With Examples.pdf
What Is Unit Testing A Complete Guide With Examples.pdfWhat Is Unit Testing A Complete Guide With Examples.pdf
What Is Unit Testing A Complete Guide With Examples.pdf
Jace Reed
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
Abdelkrim Boujraf
What Is Unit Testing_ A Complete Guide With Examples.pdf
What Is Unit Testing_ A Complete Guide With Examples.pdfWhat Is Unit Testing_ A Complete Guide With Examples.pdf
What Is Unit Testing_ A Complete Guide With Examples.pdf
Steve Wortham
Increasing Quality with DevOps
Increasing Quality with DevOpsIncreasing Quality with DevOps
Increasing Quality with DevOps
Coveros, Inc.
Driven to Tests
Driven to TestsDriven to Tests
Driven to Tests
Kevlin Henney
Testing 101
Testing 101Testing 101
Testing 101
Noam Barkai
Unit Testing Full@
Unit Testing Full@Unit Testing Full@
Unit Testing Full@
Alex Borsuk
SELJE_Database_Unit_Testing.pdf
SELJE_Database_Unit_Testing.pdfSELJE_Database_Unit_Testing.pdf
SELJE_Database_Unit_Testing.pdf
Eric Selje
Testing Hourglass at Jira Frontend - by Alexey Shpakov, Sr. Developer @ Atlas...
Testing Hourglass at Jira Frontend - by Alexey Shpakov, Sr. Developer @ Atlas...Testing Hourglass at Jira Frontend - by Alexey Shpakov, Sr. Developer @ Atlas...
Testing Hourglass at Jira Frontend - by Alexey Shpakov, Sr. Developer @ Atlas...
Applitools
Software Development Standard Operating Procedure
Software Development Standard Operating Procedure Software Development Standard Operating Procedure
Software Development Standard Operating Procedure
rupeshchanchal
Testing Experience - Evolution of Test Automation Frameworks
Testing Experience - Evolution of Test Automation FrameworksTesting Experience - Evolution of Test Automation Frameworks
Testing Experience - Evolution of Test Automation Frameworks
ukasz Morawski
TDD Workshop UTN 2012
TDD Workshop UTN 2012TDD Workshop UTN 2012
TDD Workshop UTN 2012
Facundo Farias
Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++
Hong Le Van
Unit Testing Guide. Helps to understand the basics of unit testing .
Unit Testing Guide. Helps to understand the basics of unit testing .Unit Testing Guide. Helps to understand the basics of unit testing .
Unit Testing Guide. Helps to understand the basics of unit testing .
shradha339475334115
Test driven development
Test driven developmentTest driven development
Test driven development
Tony Nguyen
Test driven development
Test driven developmentTest driven development
Test driven development
Luis Goldster
Test driven development
Test driven developmentTest driven development
Test driven development
Fraboni Ec
Test driven development
Test driven developmentTest driven development
Test driven development
Young Alista
Test driven development
Test driven developmentTest driven development
Test driven development
James Wong
Test driven development(tdd)
Test driven development(tdd)Test driven development(tdd)
Test driven development(tdd)
Omar Youssef Shiha
What Is Unit Testing A Complete Guide With Examples.pdf
What Is Unit Testing A Complete Guide With Examples.pdfWhat Is Unit Testing A Complete Guide With Examples.pdf
What Is Unit Testing A Complete Guide With Examples.pdf
Jace Reed
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
Abdelkrim Boujraf
What Is Unit Testing_ A Complete Guide With Examples.pdf
What Is Unit Testing_ A Complete Guide With Examples.pdfWhat Is Unit Testing_ A Complete Guide With Examples.pdf
What Is Unit Testing_ A Complete Guide With Examples.pdf
Steve Wortham
Increasing Quality with DevOps
Increasing Quality with DevOpsIncreasing Quality with DevOps
Increasing Quality with DevOps
Coveros, Inc.
Unit Testing Full@
Unit Testing Full@Unit Testing Full@
Unit Testing Full@
Alex Borsuk
SELJE_Database_Unit_Testing.pdf
SELJE_Database_Unit_Testing.pdfSELJE_Database_Unit_Testing.pdf
SELJE_Database_Unit_Testing.pdf
Eric Selje
Testing Hourglass at Jira Frontend - by Alexey Shpakov, Sr. Developer @ Atlas...
Testing Hourglass at Jira Frontend - by Alexey Shpakov, Sr. Developer @ Atlas...Testing Hourglass at Jira Frontend - by Alexey Shpakov, Sr. Developer @ Atlas...
Testing Hourglass at Jira Frontend - by Alexey Shpakov, Sr. Developer @ Atlas...
Applitools
Software Development Standard Operating Procedure
Software Development Standard Operating Procedure Software Development Standard Operating Procedure
Software Development Standard Operating Procedure
rupeshchanchal

TestDrivenDeveloment

  • 1. Test Driven Development Objective To realise productivity and quality gains by making extensive use of Test Driven Development Abstract (Abstract and TDD details taken from: http://en.wikipedia.org/wiki/Test-driven_development) TDD relies on the repetition of a very short development cycle: First the developer writes an (initially failing) automated test case that defines a desired improvement or new function, then produces the minimum amount of code to pass that test and finally refactors the new code to acceptable standards. Kent Beck, who is credited with having developed or 'rediscovered' the technique, stated that TDD encourages simple designs and inspires confidence. Proposals Develop tests for functionality of components - rather than just to test one Jira, and keep them up to date. Implement Continuous Integration either during the nightly build or on code check-in to SVN. Automated regression tests should enable us to develop new code and refactor with confidence that we havent broken anything. If any test fails then we will break the whole build! Incorporate in the Continuous Integration, code analysis tools such as 'Emma' (Check % of code covered by the tests) and 'Findbugs' (Static analysis of the java code for bugs inc. concurrency issues) Avoid the problem of tests written by the developer sharing the same blind spots with his code by having another developer, or better yet a tester, write them. This last proposal is probably controversial but, I think, key to improving quality. Whilst not going as far as 'pair programming' it would enable us to implement the 'four eyes' principle - at least two people would be independently involved in the production of every unit of software. Also, there is much less chance of requirements being misunderstood and any lack of clarity or misunderstanding that does occur can be caught earlier. Ideally, before a line of code is written. Finally, it should; help avoid 'scope creep', facilitate knowledge transfers and front-load the testing effort so we can identify problems earlier rather than at the point of delivery. For example, if the requirements change, the tests will have to be re-written and everyone involved (management, testers and developers) will be aware of the issue.
  • 2. TDD Cycle Add a test Write a test which, must inevitably fail as the code implementation has not yet been written. As opposed to writing tests after the code is developed this forces the developer to focus on the requirements before writing the code. Run all tests and see if the new one fails This validates that the test harness is working correctly and that the new test does not mistakenly pass without requiring any new code. This step also tests the test itself ruling out the possibility that the new test will always pass, and therefore be worthless - it should fail for the expected reason! Write some code that will cause the test to pass. This code will not be perfect and may, for example, pass the test in an inelegant way. This is acceptable because later steps will improve and hone it. Important that the code written is only designed to pass the test. No further (and therefore untested) functionality should be predicted and 'allowed for' at any stage. Run the automated tests and see them succeed If all test cases now pass, the programmer can be confident that the code meets all the tested requirements. This is a good point from which to begin the final step of the cycle. Refactor code Improve the code as necessary to attain production quality standards. By re-running the test cases, the developer can be confident that code refactoring is not damaging any existing functionality. Remove any artifacts that were introduced - for example magic numbers or strings - in order to make the test pass in earlier stages Repeat Starting with another new test, the cycle is then repeated to push forward the functionality. The size of the steps should always be small, with as few as 1 to 10 edits between each test run. 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.
  • 3. Continuous integration helps by providing revertible checkpoints. Code Visibility Test suite code clearly has to be able to access the code it is testing. On the other hand, normal design criteria such as information hiding, encapsulation and the separation of concerns should not be compromised. Therefore unit test code for TDD is usually written within the same project or module as the code being tested. There is some debate among practitioners of TDD, as to whether it is wise to test private methods and data. Some argue that private members are a mere implementation detail that may change, and it should be sufficient to test any class through its public interface or through its subclass interface. Others say that crucial aspects of functionality may be implemented in private methods, and that developing this while testing it indirectly via the public interface only obscures the issue. My view is that if the private members have no discernible effect on the public behaviour of a class then of what use are they? Or to paraphrase Danny Blanchflower if theyre not interfering with play, then what are they doing in the codebase? In other words, if invoking all the public methods does not, in turn, invoke all the private methods then when may we expect them to be invoked if ever? Stubs,mocks and integration tests When code under development relies on a database, a web service, or any other external process or service, enforcing a unit-testable separation is also an opportunity and a driving force to design more modular, more testable and more reusable code. Two steps are necessary: An interface should be defined that describes the access that will be available. The interface should be implemented in two ways, one of which really accesses the external process, and the other of which is a Stub or a Mock Stub objects need do little more than add a message such as Person object saved to a trace log, against which a test can be run to verify correct behaviour. Mock objects differ in that they themselves contain assertions that can make the test fail, for example, if the person's name and other data are not as expected.
  • 4. Shortcomings Test-driven development is difficult to use in situations where full functional tests are required to determine success or failure, e.g. user interfaces, programs that work with databases, and some that depend on specific network configurations. Unit tests created in a test-driven development environment are typically created by the developer who will also write the code that is being tested. The tests may therefore share the same blind spots with the code. The high number of passing unit tests may bring a false sense of security, resulting in fewer additional software testing activities, such as integration testing and compliance testing. The tests themselves become part of the maintenance overhead of a project. Badly written tests, for example ones that include hard-coded error strings or which are themselves prone to failure, are expensive to maintain. It is possible to write tests for low and easy maintenance, for example by the reuse of error strings, and this should be a goal during the code refactoring phase described above. There is a risk that tests that regularly generate false failures will be ignored, so that when a real failure occurs it may not be detected. The level of coverage and testing detail achieved during repeated TDD cycles cannot easily be re-created at a later date. Therefore these original tests become increasingly precious as time goes by. If a poor architecture, a poor design or a poor testing strategy leads to a late change that makes dozens of existing tests fail, it is important that they are individually fixed. Merely deleting, disabling or rashly altering them can lead to undetectable holes in the test coverage.
  • 5. FindBugs Abstract 'FindBugs' is an example of a static code analysis tool. It does not run any test cases and in fact knows nothing about the logic of your code. It simply examines it, without actually running it, for what are generally considered to be bug patterns and bad practices. As part of a comprehensive programme of code reviews it can be invaluable to catch hard-to-spot coding errors. (Human code review is still necessary) It is available under an open source licence from 'SourceForge' and takes only a few minutes to install. Once installed you can use either the built-in GUI, command line tools or plugins (e.g. for Eclipse) to run tests. You need to tell 'FindBugs' where your source and byte code are and any external classes or jars required to compile it. Locating the external classes can be tricky if 'FindBugs' reports that it cannot check all your code because a particular class is missing. Probably easiest to just add every jar/class on your classpath, to begin with. Example Bug This check was run against the entire java code base of an application and found 148 possible bugs. These vary in seriousness and some discretion needs to be exercised in determining if any action is required. This example is of synchronization using a 'ConcurrentHashMap' (a member of the java.util.concurrent package) as a lock object. Careful analysis is required to decide if there are going to be a problems with this or not. There is no point in locking using 'concurrent' classes as they are internally guarded against concurrent access in such a way as to allow multiple threads to access them at the same time. E.g. in this case each hash bucket will be guarded by a separate lock. Unless more than one thread tries to access the same bucket concurrently they will be allowed to read/write the map's contents (Except if this code snippet is the only code that can access the map. That is not the case here as 'status' is exposed through a public method 'handleTick()' which employs no synchronization when accessing it - correctly, of course) If the program's correctness does not depend on only one thread at a time being able to access the map then there will probably be no problem with this. For example, if it's just a case of being a bit over-zealous with the synchronization of something that doesn't need synchronizing. If the correctness of the program does depend on exclusive access to the map then this code is broken. At best, this indicates something that should be explained. Why try to lock something that cannot be locked? If you do want exclusive access then why are you using a 'ConcurrentHashMap'? On a wider note, synchronizing access to ANY resource and then allowing public unsynchronized access to it through another method, or by synchronizing on a different lock object, is not threadsafe!
  • 6. Another issue... NOT picked up by 'FindBugs', is in the public method 'handleTick()'. The return values of putIfAbsent() are ignored! status.putIfAbsent(info.tickNum, new TickStatus(info.tickNum, info.instrId)); statusInstruments.putIfAbsent(key, new InstrumentStatus(key)); If a non-null value is returned from putIfAbsent() , then the put operation failed and the value returned is the value already associated with the key!