SlideShare une entreprise Scribd logo
1  sur  6
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 haven’t 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 they’re 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!

Contenu connexe

Tendances

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 trainingThierry 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 2010guest5639fa9
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven DevelopmentMireia Sangalo
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Developmentguestc8093a6
 
Understanding Unit Testing
Understanding Unit TestingUnderstanding Unit Testing
Understanding Unit Testingikhwanhayat
 
TDD - Test Driven Development
TDD - Test Driven DevelopmentTDD - Test Driven Development
TDD - Test Driven DevelopmentTung Nguyen Thanh
 
Test driven development
Test driven developmentTest driven development
Test driven developmentHarry 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 codePascal 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 ProjectsRavi Kumar
 
iOS Test-Driven Development
iOS Test-Driven DevelopmentiOS Test-Driven Development
iOS Test-Driven DevelopmentPablo Villar
 
Test-Driven Development (TDD)
Test-Driven Development (TDD)Test-Driven Development (TDD)
Test-Driven Development (TDD)Brian Rasmussen
 

Tendances (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)
 
Unit Testing
Unit TestingUnit Testing
Unit Testing
 
Google test training
Google test trainingGoogle test training
Google test training
 
Unit testing
Unit testing Unit testing
Unit testing
 
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
 
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
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
Understanding Unit Testing
Understanding Unit TestingUnderstanding Unit Testing
Understanding Unit Testing
 
TDD - Test Driven Development
TDD - Test Driven DevelopmentTDD - Test Driven Development
TDD - Test Driven Development
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
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
 
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
 
iOS Test-Driven Development
iOS Test-Driven DevelopmentiOS Test-Driven Development
iOS Test-Driven Development
 
Test-Driven Development (TDD)
Test-Driven Development (TDD)Test-Driven Development (TDD)
Test-Driven Development (TDD)
 

En vedette

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 2017Epic Research
 
Mapa mental de autoestima
Mapa mental de autoestimaMapa mental de autoestima
Mapa mental de autoestimaAna Pacheco
 
Corona chair campos-torres-velez
Corona chair campos-torres-velezCorona chair campos-torres-velez
Corona chair campos-torres-velezHector Torres
 
Daniela espinoza hardware.ppt
Daniela espinoza hardware.pptDaniela espinoza hardware.ppt
Daniela espinoza hardware.pptEspinoza0599
 
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 ciutatAjuntament de Barcelona
 
portfolio final
portfolio finalportfolio final
portfolio finalAmy Powell
 
Custom Filled Aerosol print
Custom Filled Aerosol printCustom Filled Aerosol print
Custom Filled Aerosol printBEN WATSON
 
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 ecosystemJustin 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 2016Jay Casey
 

En vedette (17)

published paper
published paperpublished paper
published paper
 
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
 
Mapa mental de autoestima
Mapa mental de autoestimaMapa mental de autoestima
Mapa mental de autoestima
 
Corona chair campos-torres-velez
Corona chair campos-torres-velezCorona chair campos-torres-velez
Corona chair campos-torres-velez
 
Daniela espinoza hardware.ppt
Daniela espinoza hardware.pptDaniela espinoza hardware.ppt
Daniela espinoza hardware.ppt
 
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
 
Covariance vs Correlation
Covariance vs CorrelationCovariance vs Correlation
Covariance vs Correlation
 
portfolio final
portfolio finalportfolio final
portfolio final
 
Levonorgestrel.
Levonorgestrel.Levonorgestrel.
Levonorgestrel.
 
Diapograma
DiapogramaDiapograma
Diapograma
 
Custom Filled Aerosol print
Custom Filled Aerosol printCustom Filled Aerosol print
Custom Filled Aerosol print
 
Macam-Macam Fungsi
Macam-Macam FungsiMacam-Macam Fungsi
Macam-Macam Fungsi
 
Entrevista
Entrevista Entrevista
Entrevista
 
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
 
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 ...
 
BFZoo handouts
BFZoo handoutsBFZoo handouts
BFZoo handouts
 
Jay Casey PhD CV Oct 2016
Jay Casey PhD CV Oct 2016Jay Casey PhD CV Oct 2016
Jay Casey PhD CV Oct 2016
 

Similaire à TestDrivenDeveloment

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
 
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
 
Test driven development
Test driven developmentTest driven development
Test driven developmentLuis Goldster
 
Test driven development
Test driven developmentTest driven development
Test driven developmentTony Nguyen
 
Test driven development
Test driven developmentTest driven development
Test driven developmentYoung Alista
 
Test driven development
Test driven developmentTest driven development
Test driven developmentJames Wong
 
Test driven development
Test driven developmentTest driven development
Test driven developmentFraboni Ec
 
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
 
Increasing Quality with DevOps
Increasing Quality with DevOpsIncreasing Quality with DevOps
Increasing Quality with DevOpsCoveros, 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.pdfEric 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
 
Test Driven Development:Unit Testing, Dependency Injection, Mocking
Test Driven Development:Unit Testing, Dependency Injection, MockingTest Driven Development:Unit Testing, Dependency Injection, Mocking
Test Driven Development:Unit Testing, Dependency Injection, Mockingmrjawright
 
Test driven development
Test driven developmentTest driven development
Test driven developmentnamkha87
 
Unit testing (Exploring the other side as a tester)
Unit testing (Exploring the other side as a tester)Unit testing (Exploring the other side as a tester)
Unit testing (Exploring the other side as a tester)Abhijeet Vaikar
 

Similaire à 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
 
TDD Workshop UTN 2012
TDD Workshop UTN 2012TDD Workshop UTN 2012
TDD Workshop UTN 2012
 
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++
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Test driven development(tdd)
Test driven development(tdd)Test driven development(tdd)
Test driven development(tdd)
 
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 ...
 
Increasing Quality with DevOps
Increasing Quality with DevOpsIncreasing Quality with DevOps
Increasing Quality with DevOps
 
Driven to Tests
Driven to TestsDriven to Tests
Driven to Tests
 
Testing 101
Testing 101Testing 101
Testing 101
 
Unit Testing Full@
Unit Testing Full@Unit Testing Full@
Unit Testing Full@
 
SELJE_Database_Unit_Testing.pdf
SELJE_Database_Unit_Testing.pdfSELJE_Database_Unit_Testing.pdf
SELJE_Database_Unit_Testing.pdf
 
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...
 
Software Development Standard Operating Procedure
Software Development Standard Operating Procedure Software Development Standard Operating Procedure
Software Development Standard Operating Procedure
 
Test Driven Development:Unit Testing, Dependency Injection, Mocking
Test Driven Development:Unit Testing, Dependency Injection, MockingTest Driven Development:Unit Testing, Dependency Injection, Mocking
Test Driven Development:Unit Testing, Dependency Injection, Mocking
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Unit testing (Exploring the other side as a tester)
Unit testing (Exploring the other side as a tester)Unit testing (Exploring the other side as a tester)
Unit testing (Exploring the other side as a tester)
 

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 haven’t 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 they’re 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!