take pride in your code - test-driven development
TRANSCRIPT
Take pride in your codeTest-Driven Development
Credits
Ahmed HammadAmeer Gaafar
Disclaimer: The content and structure of this slides is based on the presentation Ameer and Ahmed authored.
Introductions first!
● I am⚪ Ahmed Moawad⚪ CSD 2009⚪ Software Engineer⚪ Chief Operating Officer at BADR⚪ @ [email protected]⚪ in /ahmedmoawadibraheem
● Who are you?!
Expectations?What do you think this, considerably long, session is
about?!
So, it’s not about:
● Test first.● Unit testing.● Testing!
Surprisingly, it’s about design :D
Logistics
● 50 minutes sprints, 10 minutes break.● Be on time.● Cell phones SILENT.● Feel free to:
⚪ Speak up.⚪ Discuss.⚪ Sit in groups, form teams.⚪ Mingle, move around, go out and come back (but QUIETLY)
Why even bother?
Self-Testing Code
Traditionally
● How much do you code before your test?● How do you test?● How do you find bugs?
Code Compile Test
Fix bugs
The debugger curve (uncle Bob’s* claim!)
Debugging Skills
Prod
ucti
vity
* Robert Martin
Testing Code, with code!
Move coding into an emotional state!
Take pride!
Love what you do!
Have fun!
A typical example
public class TestCalculator {
public static void main(String[] args) {
Calculator c = new Calculator();
double result = c.add(5, 6);
if(result != 11) {
System.out.println(“wrong result”);
}
// rest of the class omitted
}
}
public class Calculator {
public double add(double a, double b) {
return a + b;
}
public double sub(double a, double b) {
return a - b;
}
public double mul(double a, double b) {
return a * b;
}
public double div(double a, double b) {
return a / b;
}
}
Production Code (System Under
Test)Test Code
Self-Testing Code
Write Code Compile Write Test Code
Make tests pass
Run TestsCompile Test Code
Self-Testing Code
By the programmers, for the programmers
Programmers take responsibility of quality
Impact on Code
● Smaller pieces● Separation of concerns● Easier to test● Easier to modify
Regression testing becomes almost free!
Loose coupling
Iff you use good names
Solid system (not fragile)
More benefits of tests
● Documentation of code.⚪ Living, executable documentation.
● Catch future defects.⚪ You have a safety net.
● Long-term time saving.⚪ You know when something is broken before deployment.
But testing is merely a tool, it not the process.
Now what?
What do you think will/should happen to the test code?
xUnit Family
● Frameworks for writing programmer tests● Integrated with IDEs and build environments● Exist for virtually all programming languages and
environments
It’s not about units, it’s about self-testing code
How everything started
Writing tests with JUnit
import . . . // imports omitted
public class TestCalculator {
public static void main(String[] args) {
Calculator c = new Calculator();
double result = c.add(5, 6);
if(result != 11) {
System.out.println(“wrong result”);
}
// rest of the class if omitted
}
}
import . . . // different imports, omitted
public class TestCalculator {
@Test
public void addTwoNumbers_ReturnsSum() {
Calculator c = new Calculator();
double result = c.add(5, 6);
assertEquals(21, result);
}
}
What it looks like in real life :)
Test cases Coverage
Success
Production code
Test code
Environment Setup ExerciseEnough talking, let’s power up those machines
Temperature conversion
℃ × 9/5 + 32 = ℉
(℉ - 32) × 5/9 = ℃
Tennis Score Exercise
Tennis Scoring SystemPlayer 1 Player 2 Score
⬤ Fifteen - Love
⬤ ⬤ Fifteen - Fifteen
⬤⬤ ⬤ Thirty - Fifteen
⬤⬤⬤ ⬤ Forty - Fifteen
⬤⬤⬤⬤ ⬤ Game, Player 1
⬤⬤ ⬤⬤⬤ Thirty - Forty
⬤⬤⬤ ⬤⬤⬤ Deuce
⬤⬤⬤⬤ ⬤⬤⬤ Advantage, Player 1
⬤⬤⬤⬤ ⬤⬤⬤⬤ Deuce
⬤⬤⬤⬤ ⬤⬤⬤⬤⬤ Advantage, Player 2
⬤⬤⬤⬤ ⬤⬤⬤⬤⬤⬤ Game, Player 2
Benefits of self-testing code?
● Executable proof of quality● Free regression test● Inspires confidence● Reduces cost of change
Bonus :D
A formal proof! It doesn’t get more formal than that!!
Added cost to development time is about 50%, BUT, it’s worth the investment
“Never in the field of software development have so many owed so much to so few lines of code.”
Martin Fowler
Discussion
● So, what is the ‘unit’ in xunit?⚪ Class?⚪ Method?⚪ Component?
Interesting behavior
There ought to be some boring stuff here about SUT, DOC and Isolation!
System Under Test Depended-on Object
Leap Year Exercise
boolean leapYear(int year)
A leap year is defined as one that is divisible by 4, unless it’s divisible by a 100, in which case, it should also be divisible by 400.
Lear Years: 1996, 2000Common Year: 2001, 1900
Test-Driven DevelopmentYes, up to this point, we didn’t speak off TDD yet :D
Traditionally
Code Compile Test
Fix bugs
Write Code Compile Write Test Code
Make tests pass
Run TestsCompile Test Code
TDD
Write a test See it fail Make it
passMake it better
Establish expectations
Single test
Failure is progress
Using the simplest solution, even if ugly
Now improve the design guarded with tests and better understanding
Refactor
Now, to the 1st live TDD session
The Bowling Kata
... but before we dig in
Red (test)
Green (make it pass)
Refactor
The Bowling Kata
● 10 frames per game, up to 2 attempts per frame● All pins down from 1st attempt (strike)
⚪ Frame is over, Score is 10 + score the next two balls● All pins down in the two balls of the frame (spare)
⚪ Score is 10 + score if the next ball● Less than 10 down in two balls of the frame
⚪ Score is number of pins down● Spare in the 10th frame?
⚪ One bonus ball● Strike in the 10th frame?
⚪ Two bonus balls
Bowling score calculator design
+ rolls(pins : int)
+ score(): int
Game
+ score(): int
Frame
- pins: int
Roll
Tenth Frame
10 1..2
1
Next frameINITIAL DESIGN
The Bowling Kata
So, how did you find it?
TDD Benefits
All testing benefits
+ ● Consumer focused, simple design● Just enough code to meet expectations (lean)● No untested code
Now, it’s your turnYour first TDD program
Standard deviation
Write a program that prints the standard deviation of the a series of a population of numbers.
... but before you dig in!
Remember
● You’re learning a technique, not solving a problem● Baby steps● Failing tests first● Just enough code to pass the test● Keep it clean
FizzBuzz Kata
Write a program that prints the numbers from 1 to 100, BUT:● For multiples of three, print “Fizz”● For multiples of five, print “Buzz”● For multiples of both, print “FizzBuzz”
Roman Numerals Kata
Convert Arabic numbers to Roman:1 -> I2 -> II3 -> III4 -> IV5 -> V6 -> VI7 -> VII8 -> VIII9 -> IX
10 -> X20 -> XX30 -> XXX40 -> XL50 -> L60 -> LX70 -> LXX80 -> LXXX90 -> XC
1000 -> M2000 -> MM3000 -> MMM
100 -> C200 -> CC300 -> CCC400 -> CD500 -> D600 -> DC700 -> DCC800 -> DCCC900 -> CM
1990 = MCMXC 99 = XCIX2008 = MMVIII 47 = XLVII
Prime Factors Kata
Print the prime factors of an arbitrary number1 -> { }2 -> { 2 }6 -> { 2, 3 }12 -> { 2, 2, 3 }14 -> { 2, 7 }286 -> { 2, 11, 13 }
Test smells
● Obscure test● Conditional test● Hard-to-test code● Test code duplication● Test logic in production
● Assertion roulette● Erratic test● Fragile test● Frequent debugging● Manual intervention● Slow test
Code Smells Behavior Smells
Unit testing Sweet Spot
● Fast executing.● Independent.● Large number.● Narrow in focus.● Simple in structure.● Easy to setup and teardown.
Further considerations
● Different test runners (Jasmine default, Karma, ...)⚪ Why?
● Impact on development time.⚪ Usually, people would tell you it’s a 50% tax.⚪ Usually, it’s not true :D.
● Code coverage.● Data providers.● Mocks and stubs.
Conclusion
● Simple != Easy.● You have to master
the craft to reap the fruit.
● The art of fearless programming.
● Programming, enjoyable again.
● The dream of executable requirements.
● Towards a better design for software.
● A hope for the lost souls.
Other possible titles!
All code is guilty until proven innocent
All code is legacy unless it has tests
Thank you!I hope you enjoyed this class