2. Hitchheikers guide to...
part 1 – testing and tools
what is testing and why to test ?
what we test and how ?
what tools we can use ?
part 2 – TDD
TDD as a development process
why to bother (benefits and drawbacks)
4. What is testing ?
Validation and verification of the current
implementation AND design
Emulation of application state in the very specific
moments
It is a skill, like any other
5. What is testing ? – a little more…
Measurable contribution to “implementation” value
Testing does not equals writing tests
Yes, it is looking for bugs…
6. Why to test ?
Makes us better professionals
Gives us – developers - valuable feedback
Brings quality assurance to our work
Enables us with confidence
7. Why we do not write tests ? (excuses)
It is slow and time consuming
Does not catch real bugs
I do not write buggy code – sure…
Debugging is faster
8. Why we do not write tests ? (excuses)
We have untestable design
Need to be refactored
I am programming GUI
I just do not know how…
9. Kinds of bugs
Logical, aka. classic bug – errors in logical
conditions, loops, etc.
Wiring bugs – wrong data bindings, incorrect
injections
Rendering bugs – application output is messed,
either UI or reports (unfortunately “tested” only by
human)
10. Kinds of bugs
Depending on kind of bag,
difficulty of finding and fixing it varies…
11. Cost of fixing
Logical bugs are hard to find and fix. Also,
they are very common…
Wiring bugs are relatively easy to find and
fix, as their behavior is more verbose than
logical one…
Rendering bugs are usually easy to find and
fix. It is really easy to SEE them…
12. Kinds of tests
Depending on theirs kind, System wide tests
tests have different purpose.
For true quality assurance,
all tests are needed. The Integration tests
smaller the test is – the more
precise answer it brings. Unit tests
The catch is – the smaller the tests the more of them we need !
13. Unit tests
Focus only on logical errors
Are related only to a single class or method
(isolation)
Are very fast (only few ms)
14. Unit tests
Are short and brief, when fail you do not need
debugger to find the bug
Are aimed to help when refactoring
When passed – you are sure correct logical flow in
class or method
They are preferred way of testing !
15. Integration tests
Test parts of application working together
Are aimed to catch bugs related to objects relations
Brief enough to be run before submitting to version
control
16. Integration tests
Can test boundary conditions unavailable in system
wide tests
Verify correctness of system integration with
external systems
practice
physician
patient
17. System wide tests
Test correctness of the system as a whole
Emulate user behavior (real use cases coming from
analysis)
Aimed to prove that system is capable to fulfill user
(customer) requirement
Can run noticeably long
18. What makes testing hard ?
Four main factors of hard-to-test code:
The way object is created (constructor logic),
How classes interact with each other,
Global state,
Violations of OOD rules like LoD or SRP,
LoD – Law of Demeter
SRP – Single Responsibility Principle
19. LoD ? SRP ? – hmm….
Law of Demeter – one of rules of good object
oriented design which says:
“Only talk to your best friends” !
bad:
Car.getEngine().getFuelSystem().getTank().checkFuelLevel();
good:
Car.getFuelLevel(); which calls Engine.getFuelLevel(); etc.
20. LoD ? SRP ? – hmm….
Single Responsibility Principle – usually referred as:
class should have ONE and ONLY ONE
reason to change.
21. Why object construction makes
life harder ?
Intensive logic in constructor denies possibility of unit
testing and prevents testing
If construction of the class depends entirely on
implementation not interface, testing is impossible
Complicated and time consuming constructions
involves equally complicated test setup
22. Does it really matter ?
Look how
dependency on
class
implementation
matters…
We can not test
without the
Engine !
23. How to prevent ?
Do not bind object directly to an implementation,
use interfaces where possible,
Encapsulate object creation into factories, especially
complex one
24. How to prevent ?
Avoid intensive logic in constructors,
Avoid “fake API” when creating objects (like
.setup(), .init() method). Created object should be
ready to use.
25. Class relations
Main types of relations are:
Instanced objects – new
Passed by objects – as method parameters
Dependency to state (global) objects
26. Untestables - class relations
Dependence on specific instance denies testing
(or at least makes it very painful…),
Cyclic dependencies will make code untestable,
Local dependencies (method) are hard to test,
27. How to prevent ?
Favor interfaces over implementations,
Keep away from instanceOf,
Dependency injection makes life easier,
28. Untestables – global state
Can cause most weird and hard to test situations,
Test isolation principle is violated ! (order of tests
matters…)
Multiple executions of tests can cause different
results,
29. Global state – common flaws
Global state in JVM:
System.currentTime();
Math.radom();
Static methods – you cannot change behavior using
polymorphism,
Singletons – root of all evil considering global state,
30. How to prevent ?
Do not use static – it can be usually easily distilled
into particular class or its behavior,
Just avoid global state,
If have to use global state - remember to “reset” it
at the end of test method
31. Untestables – OOD violations
SRP – the more incoherent class is the harder is to
write tests. Highly incoherent class are hard to be
unit tested.
LoD – the deeper we go into object hierarchy the
more difficult test setup is. Also, later refactoring
becomes hard and painful.
32. How to prevent ?
Inability and difficulty of wiring unit test are signs
of bad architecture and/or bad design.
Considering SRP, class responsibilities can be always
distributed among more objects.
33. General flaws
Complicated conditionals (wide ifs or switch),
Depending heavily on Context objects, especially
global flags,
Static initialization blocks,
34. General flaws – a little more
Hard dependency on external systems or modules,
impossible to mock,
Overuse of “utility” classes,
* Final classes and methods
35. Tools for testing
TestNG – successor to JUnit, testing framework
aimed to be powerful and easy to use,
Mockito – quite new mocking framework, simpler
and easier in use than EasyMock,
37. What is TDD ?
Test driven development brings alternative
approach to classical software
development cycle.
38. What is TDD ?
TDD manifests itself in:
Iterational (evolutionary) approach to development,
Process emphasizing design over implementation,
Continuous integration and refactoring,
39. TDD and its Test First Design
The TDD bases on three key steps:
Test
Implementation
Refactoring
40. TDD in snapshot
You write business logic only when test is falling
If all is running – clean implementation
Developer focuses on requirement before
writing actual implementation
Resulting implementation is more cohesive
and lowly coupled code
41. TDD tools that help
Continuous Integration (Hudson, CruiseControl)
Test coverage tools, like Cobertura (EclEMMA),
xUnit / mocking framework (Mocquito, EasyMock),
Static analysis tools like Classcycle (JDepend),
42. TDD tests first - benefits
Starting from tests gives you long-term benefits:
Helps keep your code clean
Brings feedback to design and architecture early,
Gives you constant and reliable feedback about
development progress
43. TDD benefits – a few more
Overall implementation time is shortened
Tests are more through than in traditional approach
44. TDD tests first - drawbacks
However there are some drawbacks:
TDD demands “different” approach to development,
Tests bring maintenance overhead,
TDD is as successful as written tests
45. TDD drawbacks – few more…
Process itself does not excludes wrong implementation
(misinterpreted requirements),
With time, bunch of passing always green tests can
lead to false belief about implementation
46. Key factors of testing
The main drawback of testing and TDD is its
dependence on two specific factors: people and
problem to be resolved. Where people are we, the
one who are supposed to create application for
customer and second factor is…
The customer itself, time, resources and
complexity of the problem…
47. TDD myths
100% test coverage is required,
Unit tests are enough,
http://de.wikipedia.org/wiki/Datei:Wolpertinger-praeparat.jpg
Development effort is greater, and
takes longer,
TDD has long learning curve *
48. A word for end
If it's worth building, it's worth testing.
If it's not worth testing, why are you wasting
your time working on it?