Red TDD Refactor Green OVERVIEW OF TEST DRIVEN

  • Slides: 14
Download presentation
Red TDD Refactor Green OVERVIEW OF TEST DRIVEN DEVELOPMENT by Paul M. Watt @

Red TDD Refactor Green OVERVIEW OF TEST DRIVEN DEVELOPMENT by Paul M. Watt @ code of the damned. com

Description Test Driven Development: Write a test that fails A development methodology that promotes

Description Test Driven Development: Write a test that fails 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. Evaluate and repeat until complete This process is most effective if performed in a unit test harness Add the code that will pass the test

TDD Mantra “Red. Green. Refactor. ” is the mantra of a developer working by

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: A test is written for a small non-existent feature, then it is run and fails. Red The feature is implemented – Rerun the tests and it passes. Green Inspect the code, can it be improved? Refactor • Is all of the functionality implemented? • Can the implementation be simplified? If not, add the next test.

Learn by Example Start with the simplest skeleton of your target class or function

Learn by Example Start with the simplest skeleton of your target class or function that will compiler. 1. double celcius_to_farenheit(double temperature) 2. { 3. return 0; 4. }

Celsius to Fahrenheit: Test 1 Write the test: 1. void Test. Celcius. At. Zero()

Celsius to Fahrenheit: Test 1 Write the test: 1. void Test. Celcius. At. Zero() 2. { 3. ASSERT_EQUAL(32, celcius_to_fahreheit(0)); 4. } Initiate the test: Test. Celsius. At. Zero(); Fail

Celsius to Fahrenheit: Feature 1 Add an implementation to the function that will allow

Celsius to Fahrenheit: Feature 1 Add an implementation to the function that will allow Test 1 to pass: 1. double celcius_to_farenheit(double temperature) 2. { 3. return 32; 4. } Initiate the test: Test. Celsius. At. Zero(); Pass

Celsius to Fahrenheit: Refactor Analyze the solution. Did we add all of the functionality

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°.

Celsius to Fahrenheit: Test 2 The next test will verify a conversion of the

Celsius to Fahrenheit: Test 2 The next test will verify a conversion of the boiling point of water, 100° C. 1. void Test. Celcius. At 100() 2. { 3. ASSERT_EQUAL(212, celcius_to_fahreheit(100)); 4. } Initiate the tests: Test. Celsius. At. Zero(); Test. Celsius. At 100(); Pass Fail

Celsius to Fahrenheit: Feature 2 Add an implementation to the function that will allow

Celsius to Fahrenheit: Feature 2 Add an implementation to the function that will allow both tests to pass: 1. double celcius_to_farenheit(double temperature) 2. { 3. return (temperature == 0) ? 32 : 212; 4. } Initiate the tests: Test. Celsius. At. Zero(); Test. Celsius. At 100(); Pass

Refactor Celsius to Fahrenheit: Test 3 Let’s select one more temperature, the average temperature

Refactor Celsius to Fahrenheit: Test 3 Let’s select one more temperature, the average temperature of the human body, 37° C. 1. void Test. Celcius. At. Human. Body. Temp() 2. { 3. ASSERT_EQUAL(98. 6 f, celcius_to_fahreheit(37. 0 f)); 4. } Initiate the tests: Test. Celsius. At. Zero(); Test. Celsius. At 100(); Test. Celsius. At. Human. Body. Temp(); Pass Fail

Celsius to Fahrenheit: Feature 3 Add an implementation to the function that will allow

Celsius to Fahrenheit: Feature 3 Add an implementation to the function that will allow all of the tests to pass: 1. double celcius_to_farenheit(double temperature) 2. { 3. return (temperature * 5. 0 f / 9. 0 f) + 32. 0 f; 4. } Initiate the tests: Test. Celsius. At. Zero(); Test. Celsius. At 100(); Test. Celsius. At. Human. Body. Temp(); Pass

Celsius to Fahrenheit: Refactor Upon inspection this time, it appears that we have all

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.

Qualities and Benefits The code is written to be testable and more maintainable by

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

Resources Code of the Damned ◦ Test Driven Development ◦ The Purpose of a Unit Test ◦ Unit Test Frameworks Books ◦ x. Unit Test Patterns: Refactoring Test Code by Gerard Meszaros ◦ Working Effectively with Legacy Code by Michael C. Feathers, Author of Cpp. Unit(Lite) ◦ Test Driven Development: By Example by Kent Beck, Author of first x. Unit framework