testing: ¿what, how, why?
TRANSCRIPT
Testing: ¿what, how, why?David Ródenas — @drpicox
@drpicox
What?describe(‘calculator’, () => { it(‘should do sums’, () => { let calculator = new Calculator(); calculator.input(2); calculator.plus(); calculator.input(4); calculator.equal(); let result = calculator.get(); expect(result).toBe(6); }); });
2
@drpicox
How?• NUnit, MSTest, … — C#
• FUnit, FRUIT, FortUnit, … — Fortran
• JUnit, FitNesse, Mockito, … — Java
• Jasmine, Mocha, QUnit, … — Javascript
• Unittest, py.test, Nose, … — Python
• MiniTest, Test::Unit, RSpec, … — Ruby
• …
• Cucumber, Selenium, SpecFlow, … — Scenario
3
• What? • How? • Why?
why?
@drpicox
Weight cost
6
+- +-
Think Write Debug+-
@drpicox
Weight cost
7
Think+-
• Surrounding code
• API for the new code
• Understand new features
@drpicox
Weight cost
8
Write+-
• Faster typist speed is: 150 wpm
• Moderate typist speed is: 35 wpm
• 400 line code may contain 1000 words ~ 30 minutes
@drpicox
Weight cost
9
Debug+-
• Even if everything works well, we have to verify that it is true
• Navigate to affected point
• Make sure that everything works as expected, each time
• If it fails, stop and start looking for problems…
@drpicox
Weight cost
10
+- +-
Think Write Debug+-
@drpicox
Weight cost
11
+- +-
Think Write Debug+-
@drpicox
Weight cost
12
+- +-
Think Write Debug+-
@drpicox
Debug• How many debug cases have you thrown away?
13
@drpicox
Think• Would not it be great for thinking to give us the debug?
• All cases • All features with all semantics • Everything debugged • Do not throw away debug cases • New features does not break old one • Safe refactors to accommodate new changes
14
what?
@drpicox
Types of bugs
16
Logic Wiring Visual
@drpicox
Types of bugs
17
Logic Wiring VisualDetection
Diagnose
Correction
@drpicox
Types of bugs
18
Logic Wiring VisualDetection HARD EASY TRIVIAL
Diagnose HARD MEDIUM EASY
Correction HARD MEDIUM EASY
@drpicox
Detection HARD MEDIUM EASY
Diagnose HARD MEDIUM EASY
Correction HARD MEDIUM EASY
Types of bugs
19
Logic Wiring VisualIt is hard!
Is it?
@drpicox
Types of testing
20
Logic
Wiring
Visualeach takes there are
whole system
subsystems
just classes
@drpicox
Types of testing
21
Logic
Wiring
Visual > 10s
< 1s
~1ms
each takes
few
many
lots
there are
end-to-end
functional
unit
known as
whole system
subsystems
just classes
@drpicox
Types of testing
22
Logic
Wiring
Visual > 10s
< 1s
~1ms
each takes
few
many
lots
there are
end-to-end
functional
unit
known as
whole system
subsystems
just classes
acceptance testing
bdd
tdd
@drpicox
Types of testing
23
Logic
Wiring
Visual > 10s
< 1s
~1ms
each takes
few
many
lots
there are
end-to-end
functional
unit
known as
whole system
subsystems
just classes
acceptance testing
bdd
tdd
@drpicox
Types of testing
24
Logic
Wiring
Visualwhole system
subsystems
just classesUnit
End- -to-End
Functional
Soft
war
e En
gine
ers
QA
Engi
neer
s
@drpicox
Unit Testing• It test the most dangerous kind of bugs
• It is easy to write
• It is fast to execute
• It is from engineers to engineers
• It focus into features details
25
@drpicox
Unit Testing• It test the most dangerous kind of bugs → Solves them
• It is easy to write → Write tens in few minutes
• It is fast to execute → Development cycle of seconds
• It is from engineers to engineers → It is the doc
• It focus into features details → Solve fast ambiguity
• IT IS THE MOST POWERFUL TYPE OF TESTING
26
@drpicox
Unit Test Everything!
27
2,4,8 Rule Gamehttp://embed.plnkr.co/N0eGMg
@drpicox
Unit Test Everything!• Test coverage?
28
@drpicox
Unit Test Everything!• Test coverage?
29
¿Are you sure that you want to write a line of code that cannot be
justified with a test?
¿Do you want to write useless code?
¿Do you want to maintain more code
than necessary?
¿Do you want to relay in your ability to manual testing
all cases?
@drpicox
Unit Test Everything!
30
Serious Bankinghttp://embed.plnkr.co/veOMnl
🃏
@drpicox
Unit Test Everything?
31
Serious Bankinghttp://embed.plnkr.co/veOMnl
🃏
Sorry, not everything, we have frame problem. (we can imagine infinite stupid things that can go wrong)
how?
@drpicox
TDD
33
• Has anyone tried to write tests after write the code?
@drpicox 34
1. You are not allowed to write any production code unless it is to make a failing unit test pass.
2. You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
3. You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
Rules
http://embed.plnkr.co/x4yKnp
TDD
@drpicox
TDD
35
• You can see it in the following Kata:
• The Bowling Game Kata
@drpicox
it(‘should…’)
36
• No side effects: for each test instantiate the whole system
• Fast execution: you should instantiate only what you need
• Repeatable: test must always give same results
@drpicox
new
37
Carnew
Engine
BrakesWheels
Doors
…newnew
• In this schema, each time that we need a car, it makes a new instance of all its parts, even if we do not need them.
~tens of instances
@drpicox
new
38
Workshopnew
Garage
Cars
Staff
…newnew
• What if we are working with a higher level?
…
~thousands of instances
@drpicox
new
39
newGarages
…
newnew
• Or even higher?
~zillions of instances
Franchises
Holding
@drpicox
new
40
• Dependency injection to the rescue (I)
describe(‘car’, () => { it(‘lock should lock doors’, () => { let doors = new Doors(); let car = new Car(null, null, doors); car.lock(); expect(car.canOpenDoors()).toBe(false); }); });
@drpicox
new
41
• Dependency injection to the rescue (II)
describe(‘hello world’, () => { it(‘it should say hi there!’, () => { let helloWorld = new HelloWorld(); helloWorld.sayHello(); expect(???).toBe(‘hi there!’); }); });
http://embed.plnkr.co/JxAOX7
@drpicox
new
42
• Dependency injection to the rescue (II)
describe(‘hello world’, () => { it(‘it should say hi there!’, () => { let console = jasmine.createSpyObj(‘console’, [‘log’]); let helloWorld = new HelloWorld(console); helloWorld.sayHello(); expect(console.log).toHaveBeenCalledWith(‘hi there!’); }); });
http://embed.plnkr.co/vZyo7u
@drpicox 43
Summary
@drpicox
Sumary• Testing helps you to understand better what you want to
encode
• Testing saves you from throwing tests away and from precious debug time
• Focus in Unit Test (acceptance testing is also amazing)
• Do not try to test every case that you can imagine
• Make sure that all tests explains your code
44
@drpicox
Sumary• and of course:
45
Write tests First!
@drpicox
Bibliography
46
• https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882
• https://www.amazon.com/Clean-Coder-Conduct-Professional-Programmers/dp/0137081073
• http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd
• http://butunclebob.com/ArticleS.UncleBob.SingletonVsJustCreateOne
• http://misko.hevery.com/2008/11/17/unified-theory-of-bugs/
• http://misko.hevery.com/2008/08/25/root-cause-of-singletons/
• http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/
• http://misko.hevery.com/code-reviewers-guide/
• http://misko.hevery.com/2008/10/21/dependency-injection-myth-reference-passing
• http://misko.hevery.com/2008/11/11/clean-code-talks-dependency-injection/
• http://butunclebob.com/
• http://misko.hevery.com/
• plnkr.co/users/drpicox
@drpicox
Bibliography
47
@drpicox
Thanks!
48
David Ródenas — @drpicox
Testing: ¿what, how, why?