What we talk aboutWhen we talk about
TestingNoel Rappin, Table XI
Or... Beyond
RedGreen
Refactor
Do you feel
guiltyabout not testing
more
There arespecific skills
But...Red, green, refactor is a better
slogan than an instruction manual
What do I test next?How do I split my
problem into testable components?
If you TDD in blocks that are too big TDD is
a real pain
Find all the unique sequences of digits 1 to 9, such as [1, 1, 2, 3, 8]
• The sum is 15
• At least one digit appears exactly twice
• No digit appears more than twice
• Order is irrelevant
• There are 38 such sequences
How do you test this?
Probably a bad idea:it "solves the problem" do expect(sequence.solutions.length).to eq(38)end
This is a little betterit "knows a valid sequence" do expect(Sequence.new(1, 1, 2, 3, 8)).to be_validend
And then we would make that test pass...
Wait,How would we make
that test pass?
class Sequence def init(*items) @items = items end
def valid? true endend
Because it is
notpermanent
One option: break the testit "knows a valid sequence" do expect(Sequence.new(1, 1, 2, 3, 9)).not_to be_validend
Normally a good option, but
problematic here
Option 2, go smallerit "can tell if the sum is 15" do expect(Sequence.new(7, 8).to be_correct_sum)end
Why is that better?
Because it's small enough that I can write it without
thinking too hard
Also, I can negate it easilyit "can tell if the sum is not 15" do expect(Sequence.new(7, 8, 1).not_to be_correct_sum)end
TDD should reduce cognitive load
So from here, I can do• has a digit pair
• does not have a digit trio
• is unique
Start with anend-to-end test
Find an piece that can be encapsulated
Test a happy-path solution
Back to the problem
There's one more piece
I need to loop over some universe of
possible sequences.
This is hard to TDD
What is the code supposed to accomplish?
What testable assertions can I make?
We could test all 9^15 combinations, I
guess(205 trillion)
But, for example[1, 1, 1]
eliminates all longer sequences
Testable assertion: what sequence
should we test next
• () => (1)• (1) => (1, 1)• (1, 1) => (1, 1, 1)• (1, 1, 1) => (1, 1, 2)• (1, 1, 2, 2, 3, 3, 4) => (1, 1, 2, 2, 3, 4)• (1, 9, 5) => (2)• (9, 6) => nil
If you do it that way, it only checks 9825
sequencs
Where did design come in?
I design my functionality as I
write the end-to-end test
I design my internal API as I write the happy-path test
I refactor to keep my design clean
Noel RappinTable XI@noelrap
http://www.noelrappin.com/trddhttp://pragprog.com/book/nrtest2/rails-4-test-
prescriptions