Upload
marcus-gray
View
216
Download
0
Embed Size (px)
Citation preview
Description Test Driven Development:
A development methodology that promotes rapid feedback of changes to the source code in order to help manage risk.
TDD helps a developer focus on solving the problem at hand, and avoid adding unnecessary code to the final product.
The result should be a piece of valid logic that is minimal and complete.
Write a test that
fails
Add the code that will pass the test
Evaluate and repeat
until complete
This process is most effective if performed in a unit test harness
TDD Mantra “Red. Green. Refactor.” is the mantra of a developer working by TDD.
If this mantra is not mentioned by someone attempting to instruct TDD, then they are most likely not describing it accurately. Simply put:
Red
Green
Refactor
A test is written for a small non-existent feature, then it is run and fails.
The feature is implemented – Rerun the tests and it passes.
Inspect the code, can it be improved?• Is all of the functionality implemented?• Can the implementation be simplified?If not, add the next test.
Learn by Example
1. double celcius_to_farenheit(double temperature) 2. { 3. return 0;4. }
Start with the simplest skeleton of your target class or function that will compiler.
Celsius to Fahrenheit: Test 1 Write the test:
Fail
Initiate the test:
TestCelsiusAtZero();
1. void TestCelciusAtZero() 2. { 3. ASSERT_EQUAL(32, celcius_to_fahreheit(0));4. }
Celsius to Fahrenheit: Feature 1 Add an implementation to the function that will allow Test 1 to pass:
Pass
1. double celcius_to_farenheit(double temperature) 2. { 3. return 32;4. }
Initiate the test:
TestCelsiusAtZero();
Celsius to Fahrenheit: Refactor Analyze the solution. Did we add all of the functionality that is required to create the correct solution?
Obviously not, Fahrenheit has other temperatures than 32°.
Refactor
Celsius to Fahrenheit: Test 2
Fail
The next test will verify a conversion of the boiling point of water, 100° C.
1. void TestCelciusAt100() 2. { 3. ASSERT_EQUAL(212, celcius_to_fahreheit(100));4. }
Initiate the tests:
TestCelsiusAtZero();
TestCelsiusAt100();Pass
Celsius to Fahrenheit: Feature 2
Pass
1. double celcius_to_farenheit(double temperature) 2. { 3. return (temperature == 0) ? 32 : 212;4. }
Initiate the tests:
TestCelsiusAtZero();
TestCelsiusAt100();
Add an implementation to the function that will allow both tests to pass:
Pass
Celsius to Fahrenheit: Test 3
Fail
Let’s select one more temperature, the average temperature of the human body, 37° C.
1. void TestCelciusAtHumanBodyTemp() 2. { 3. ASSERT_EQUAL(98.6f, celcius_to_fahreheit(37.0f));4. }
Initiate the tests:
TestCelsiusAtZero();
TestCelsiusAt100();
TestCelsiusAtHumanBodyTemp();
Pass
Refactor
Pass
Celsius to Fahrenheit: Feature 3
PassPass
1. double celcius_to_farenheit(double temperature) 2. { 3. return (temperature * 5.0f / 9.0f) + 32.0f;4. }
Add an implementation to the function that will allow all of the tests to pass:
Pass
Initiate the tests:
TestCelsiusAtZero();
TestCelsiusAt100();
TestCelsiusAtHumanBodyTemp();
Celsius to Fahrenheit: Refactor Upon inspection this time, it appears that we have all of the functionality to complete the implementation of this function and meet the requirements.
Can this function be further simplified?
Possibly, by reducing 5.0 / 9.0 into a decimal.
However, I believe that the fraction 5/9 is clearer.
Therefore I will choose to leave it as it is, and declare done for this function.
Refactor
Qualities and Benefits The code is written to be testable and more maintainable by default.
This will help reduce the undefined amount of time required to debug at the end of the project.
Creating tests helps focus on steps of development for each new feature:◦ Increased focus can improve developer productivity ◦ Exceptional and error cases can be handled in a verifiable and useful manner.◦ No more code than is necessary is developed
The test harness becomes a sandbox and playground for learning the code:◦ Experiment and make a change, see how it affects the component◦ Test hypothesis to determine of a change is a good choice or not
Resources Code of the Damned
◦ Test Driven Development◦ The Purpose of a Unit Test◦ Unit Test Frameworks
Books◦ xUnit Test Patterns: Refactoring Test Code
by Gerard Meszaros◦ Working Effectively with Legacy Code
by Michael C. Feathers, Author of CppUnit(Lite)◦ Test Driven Development: By Example
by Kent Beck, Author of first xUnit framework