the rule of three
TRANSCRIPT
three @KevlinHenney
Veni
Vidi
Vici
Sex &
Drugs &
Rock'n'Roll
Liberté · Égalité · Fraternité
There's nothing long-winded about
Maurice Saatchi
Rien n'est plus
dangereux qu'une
idée, quand on n'a
qu'une idée.
Émile-Auguste Chartier
Nothing is more
dangerous than an
idea, when you have
only one idea.
Émile-Auguste Chartier
Nothing is more
dangerous than an
IDE, when you have
only one IDE.
public static String fizzbuzz(int n) { String result = ""; if (n % 3 == 0) { result += "Fizz"; } if (n % 5 == 0) { result += "Buzz"; } if (result.isEmpty()) { result += n; } return result; }
FizzBuzz was invented to avoid the awkwardness of realising that nobody in the room can binary search an array.
https://twitter.com/richardadalton/status/591534529086693376
fizzbuzz = ( lambda n: 'Fizz' * (n % 3 == 0) + 'Buzz' * (n % 5 == 0) + str(n) * (n % 3 != 0 and n % 5 != 0))
fizzes = cycle ["", "", "Fizz"]
buzzes = cycle ["", "", "", "", "Buzz"]
words = zipWith (++) fizzes buzzes
numbers = map show [1..]
fizzbuzz = zipWith max words numbers
Nothing is more
dangerous than an
idea, when you have
only one idea.
Émile-Auguste Chartier
When a design decision
can reasonably go one of
two ways, an architect
needs to take a step back.
Instead of trying to decide
between options A and B,
the question becomes
"How do I design so that
the choice between A and
B is less significant?"
The most interesting thing
is not actually the choice
between A and B, but the
fact that there is a choice
between A and B.
Kevlin Henney
"Use Uncertainty As a Driver"
To have one choice is no choice;
to have two choices is a dilemma;
and to have three choices offers
new possibilities.
Virginia Satir
The Rule of Three
If you can’t think of three things
that might go wrong with your
plans, then there’s something
wrong with your thinking.
Jerry Weinberg
If you want to reduce your test
mass, the number one thing you
should do is look at the tests that
have never failed in a year and
consider throwing them away.
They are producing no information
for you — or at least very little
information.
James O Coplien "Why Most Unit Testing Is Waste"
1. Your tests are not failing because the code they are testing has not changed.
2. Your tests are not failing because they are not running.
3. Your tests are not failing because, yes, you are that good.
The Rule of Three
Here's a guideline Don Roberts
gave me...
The first time you do something,
you just do it.
The second time you do
something similar, you wince at
the duplication, but you do the
duplicate thing anyway.
The third time you do something
similar, you refactor.
Three strikes and you refactor.
Identity
State
Behaviour
Encapsulation
Inheritance
Polymorphism
Encapsulation
Polymorphism
Inheritance
Encapsulation
Polymorphism
Inheritance
Ignorance
Apathy
Selfishness
S-Programs
P-Programs
E-Programs
Meir M Lehman "Programs, Life Cycles, and Laws of Software Evolution"
S-Programs
Programs whose function is
formally defined by and derivable
from a specification.
Meir M Lehman "Programs, Life Cycles, and Laws of Software Evolution"
P-Programs
Despite the fact that the problem
to be solved can be precisely
defined, the acceptability of a
solution is determined by the
environment in which it is
embedded.
Meir M Lehman "Programs, Life Cycles, and Laws of Software Evolution"
E-Programs
Programs that mechanize a
human or societal activity.
The program has become a part
of the world it models, it is
embedded in it.
Meir M Lehman "Programs, Life Cycles, and Laws of Software Evolution"
We know that every pattern is an instruction of the general form:
context conflicting forces configuration
So we say that a pattern is good, whenever we can show that it meets the following two empirical conditions:
1. The problem is real. This means that we can express the problem as a conflict among forces which really do occur within the stated context, and cannot normally be resolved within that context. This is an empirical question.
2. The configuration solves the problem. This means that when the stated arrangement of parts is present in the stated context, the conflict can be resolved, without any side effects. This is an empirical question.
context conflicting forces configuration
context conflicting forces configuration consequences
Write down the problem.
Think real hard.
Write down the solution.
The Feynman Problem-Solving Algorithm
Write down the problem.
Think real hard.
Write down the solution.
Check it.
Plan Establish hypothesis,
goal or work tasks
Do Carry out plan
Study Review what has
been done against
plan (a.k.a. Check)
Act Revise approach
or artefacts based
on study
Deming's PDSA Cycle
Test early.
Test often.
Test automatically.
Andrew Hunt and David Thomas
The Pragmatic Programmer
So who should you be writing the tests for? For the person trying to understand your code.
Good tests act as documentation for the code they are testing. They describe how the code works. For each usage scenario, the test(s):
Describe the context, starting point, or preconditions that must be satisfied
Illustrate how the software is invoked
Describe the expected results or postconditions to be verified
Different usage scenarios will have slightly different versions of each of these.
Gerard Meszaros "Write Tests for People"
So who should you be writing the tests for? For the person trying to understand your code.
Good tests act as documentation for the code they are testing. They describe how the code works. For each usage scenario, the test(s):
Describe the context, starting point, or preconditions that must be satisfied
Illustrate how the software is invoked
Describe the expected results or postconditions to be verified
Different usage scenarios will have slightly different versions of each of these.
Gerard Meszaros "Write Tests for People"
Arrange Act Assert
So who should you be writing the tests for? For the person trying to understand your code.
Good tests act as documentation for the code they are testing. They describe how the code works. For each usage scenario, the test(s):
Describe the context, starting point, or preconditions that must be satisfied
Illustrate how the software is invoked
Describe the expected results or postconditions to be verified
Different usage scenarios will have slightly different versions of each of these.
Gerard Meszaros "Write Tests for People"
Given When Then
{P} S {Q}
assert fizzbuzz(1) == 1 assert fizzbuzz(2) == 2 assert fizzbuzz(3) == 'Fizz' assert fizzbuzz(4) == 4 assert fizzbuzz(5) == 'Buzz' assert fizzbuzz(6) == 'Fizz' assert fizzbuzz(7) == 7 assert fizzbuzz(8) == 8 assert fizzbuzz(9) == 'Fizz' assert fizzbuzz(10) == 'Buzz' assert fizzbuzz(11) == 11 assert fizzbuzz(12) == 'Fizz' assert fizzbuzz(13) == 13 assert fizzbuzz(14) == 14 assert fizzbuzz(15) == 'FizzBuzz' ... assert fizzbuzz(98) == 98 assert fizzbuzz(99) == 'Fizz' assert fizzbuzz(100) == 'Buzz'
def fizzbuzz(n): if n == 1: return 1 if n == 2: return 2 if n == 3: return 'Fizz' if n == 4: return 4 if n == 5: return 'Buzz' if n == 6: return 'Fizz' if n == 7: return 7 if n == 8: return 8 if n == 9: return 'Fizz' if n == 10: return 'Buzz' if n == 11: return 11 if n == 12: return 'Fizz' if n == 13: return 13 if n == 14: return 14 if n == 15: return 'FizzBuzz' ... if n == 98: return 98 if n == 99: return 'Fizz' if n == 100: return 'Buzz'
Red Write a failing test for
a new feature
Green Write enough code to
pass the test
Refactor Refine code and tests
Test-First Cycle
Red Write a failing test for
a new feature
Green Write enough code to
pass the test
Refactor! Refine code and tests
Test-First Cycle
Red Write a failing test for
a new feature
Green Write enough code to
pass the test
Refactor? Refine code and tests
Test-First Cycle
Plan Establish hypothesis,
goal or work tasks
Do Carry out plan
Study Review what has
been done against
plan (a.k.a. Check)
Act Revise approach
or artefacts based
on study
Deming's PDSA Cycle
Write As the behaviour is
new, the test fails
Realise Implement so that
the test passes
Reflect Is there something in
the code or tests that
could be improved?
Refactor Make it so!
Test-First Cycle
The difficulty in being able to
write a test can be boiled down
to the two broad themes of
complexity and ignorance
Kevlin Henney
"A Test of Knowledge" http://www.artima.com/weblogs/viewpost.jsp?thread=340839
The difficulty in being able to
write a test can be boiled down
to the two broad themes of
complexity and ignorance,
each manifested in a couple of
different ways...
The essential complexity of
the problem being solved
The accidental complexity
of the problem being solved
Uncertainty over what the
code should actually do
Lack of testing know-how
Kevlin Henney
"A Test of Knowledge" http://www.artima.com/weblogs/viewpost.jsp?thread=340839
and fours and…
Good things
come in threes
and fours