February 15, 2016
Test-Driven Development
(aka TDD)
Overview
- Some jibber jabber about quality
- Introduction to TDD
- Hands-on TDD exercise
♡1♡♡♡1♡♡♡11♡1111♡11♡111♡♡♡1♡♡111♡111♡1♡♡♡♡1♡♡♡♡♡♡11♡♡♡1♡♡11♡♡1♡1♡♡1♡♡♡♡♡♡11♡11♡♡♡11♡♡♡♡1♡1111♡1♡♡1111♡♡1♡♡1♡11♡♡♡♡1♡♡♡♡♡♡111♡1♡♡♡11♡♡1♡1♡111♡♡11♡111♡1♡♡♡♡1♡♡♡♡♡♡1111♡♡1♡11♡1111♡111♡1♡1♡111♡♡1♡♡♡1♡♡♡♡♡♡11♡♡♡11♡11♡1111♡11♡♡1♡♡♡11♡♡1♡1♡♡1♡♡♡♡1
Back in the 1980s Ford Motor Co. had a marketing slogan: “Quality Is Job Done.”
... all American cars of 1980s and 90s vintage were junk
Japanese auto makers soon took center stage in car quality and thus sales
Have you ever been in the following scenario
finish a task, which you consider is DONE
merge code into dev branch, send build to QA
they come back with a problem
you rejoice: "that an easy fix, just a null check and it's DONE"
- When organisations focus primarily on quality, defined by the following ratio:
Then quality tends to increase and costs fall over time.
- However, when organizations focus primarily on costs, costs tend to rise and quality declines over time
he taught Japan’s top management how to improve design and product quality
- Your individual definition of DONE, has a direct impact on the overall product quality
- The values you code by everyday, have a direct impact on your team and eventually on your company
you might have heard the phrase, "in this company we do things this way"! That's the way of the people, which becomes the way of the company
Could you say "assuring code quality is deeply rooted in my everyday process"?
Traditional cost of change curve
Augmented traditional cost of change curve, IBM
Kent Beck's cost of change curve, with the TDD approach
The social duty of a developer is to build quality products, therefore test your code and make everybody's life better
Young K was working on a high school project
But he made a bit of a mess ...
... by not working incrementally
He could have definitely done better!
... by knowing about a structure which helps to "do right thing" / "build the code right"
TDD is such a structure
Basic TDD rules
- Maintain a set of automated tests
- Only add production code once there is a test that requires that code
- Only refactor code when all of the tests are passing
- Never go more than a few minutes without all of the tests passing again
The TDD Cycle
Write a failing test
Watch the test fail
Write just enough code to make it pass
Watch the test pass
Fix the design (code and test)
Ensure that all tests still pass
A closer look
Minute-by-minute cycles:
Per-task cycles:
- Integrate new code and tests
- Re-run all tests in the codebase to ensure the new code does not break them
- Refactor the implementation or test code (as necessary)
- Re-run all tests in the code base
- Write a small number of new and failing automated unit tests
- Implement the code to make the tests pass
- Re-run the new unit tests to ensure the now pass
TDD Benefits
- Increased confidence in developers working on test-driven code bases
- Increased protection from defects, especially regressions
- Better code quality (in particular, less coupling and higher cohesion)
- Tests as a replacement/supplement to other forms of documentation
- Improved maintainability and changeability of code bases
- Ability to refactor without fear of breaking things
- Earlier detection of misunderstandings/ambiguities in requirements
- Smaller production code bases with more simple designs
- Reduced need for manual testing
- Faster feedback loop for discovering whether an implementation is correct
In other words
- Set up a fast feedback loop (test first)
- Get frequent feedback from the running code
- Stay "check-in-able" at all times
- TDD is an effective discipline for working incrementally at the smallest scale
- Continually deliver small bits of value
(specify, test, code, design)
... I don't like testing old code
... feels like there's not much value in it, now that the code is already built and working
TDD give you quality for "free", while helping you keep focused on what's truly important ... writing code :)
It might feel slower in the beginning, but once you get used to the process, it's proven to reduce costs
String Calculator
The following is a TDD Kata- an exercise in coding, refactoring and test-first, that you should apply daily for at least 15 minutes
Before you start:
- Try not to read ahead
- Do one task at a time. The trick is to learn to work incrementally
- Make sure you only test for correct inputs. there is no need to test for invalid inputs for this kata
1. Create a simple String calculator with a method
int Add(string numbers) :
- The method can take 0, 1 or 2 numbers, and will return their sum (for an empty string it will return 0) for example “” or “1” or “1,2”
- Start with the simplest test case of an empty string and move to 1 and two numbers
- Remember to solve things as simply as possible so that you force yourself to write tests you did not think about
- Remember to refactor after each passing test
2. Allow the add method to handle an unknown amount of numbers
3. Allow the add method to handle new lines between numbers (instead of commas):
- the following input is ok: “1\n2,3” (will equal 6)
- the following input is NOT ok: “1,\n” (not need to prove it - just clarifying)
4. Support different delimiters
-
to change a delimiter, the beginning of the string will contain a separate line that looks like this:
“//[delimiter]\n[numbers…]” for example
“//;\n1;2” should return three where the default delimiter is ‘;’
- the first line is optional; all existing scenarios should still be supported
5. Calling add with a negative number will throw an exception “negatives not allowed” - and the negative that was passed. If there are multiple negatives, show all of them in the exception message
6. Numbers bigger than 1000 should be ignored, so adding 2 + 1001 = 2
7. Delimiters can be of any length with the following format: “//[delimiter]\n” for example: “//[***]\n1***2***3” should return 6
8. Allow multiple delimiters like this: “//[delim1][delim2]\n” for example “//[*][%]\n1*2%3” should return 6.
9. Make sure you can also handle multiple delimiters with length longer than one char
Some might wonder ...
... what's QA gonna do?
Keep in mind that TDD is more of a design process than a test process
... a process once mastered, will help you achieve intrinsic quality in any code you write!
February 10, 2016
Thank You!
TDD for 3Pillar
By Karoly Szanto
TDD for 3Pillar
An introduction to TDD with focus on the importance of unit testing practices
- 511