My presentation at http://www.agiletourlondon.co.uk/
Code examples at https://github.com/uberto/tdd-awry
A voyage into today Java enterprise worse practices.
Have you ever seen 10 mocks used to tests a couple of lines of code? Beans with tons of getters/setters? The same code repeated all over again with little differences? The three pasta antipattern: spaghetti, ravioli and lasagna.
From my personal experience, some examples of terrible code, written trying to follow industry best practices and TDD. Understanding the design and the goals, will help to find the way to improve it.
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
When Tdd Goes Awry
1. When TDD Goes Awry
Clueless tests, infesting
mocks and other horrors...
A voyage into today Java
Enterprise worse practices.
Uberto
Barbini
@ramtop
h0ps://github.com/uberto
Friday, November 1, 13
2. About
me
My
first
program
SHO
to
start
SHIN
Heart,
mind
In the beginner's mind there are many possibilities,
in the expert's mind there are few.
Friday, November 1, 13
3. a·wry (-r)
adv.
1. In a position that is turned or twisted toward one
side; askew.
2. Away from the correct course; amiss.
Friday, November 1, 13
4. a·wry (-r)
adv.
1. In a position that is turned or twisted toward one
side; askew.
2. Away from the correct course; amiss.
@Test
public void testGetSwapType_SPOTFWD()
{
when(mockTrade.getField(FXSubmitFields.SWAP_TYPE)).thenReturn("SPOTFWD");
setUpTrade("SWAP");
assertEquals(FXSwapType.SPOTFWD, trade.getSwapType());
}
{
}
Friday, November 1, 13
when(mockTrade.getField(FXSubmitFields.SWAP_TYPE)).thenReturn("SPOTFWD");
setUpTrade("FWDFWDSWAP");
assertEquals(FXSwapType.SPOTFWD, trade.getSwapType());
private void setUpTrade(final String tradingType)
when(mockTrade.getField(ACCOUNT)).thenReturn(ACCOUNT_VAL);
when(mockTrade.getField(CURRENCY_PAIR)).thenReturn(CURRENCY_PAIR_VAL);
when(mockTrade.getField(TRADING_TYPE)).thenReturn(tradingType);
trade = new FXTrade(mockTrade, USER, mockNearLeg, mockFarLeg);
5. Test Stories
Each test should tell a story
Scenario tests illustrate the design
Friday, November 1, 13
6. Test Stories
Each test should tell a story
Scenario tests illustrate the design
When you are thinking big thoughts, write big tests.
When you are thinking little thoughts, write little tests.
Kent Beck, Quora
Friday, November 1, 13
7. Test Stories
Each test should tell a story
Scenario tests illustrate the design
When you are thinking big thoughts, write big tests.
When you are thinking little thoughts, write little tests.
Kent Beck, Quora
Objects are nouns. Good design is a good story.
Do you remember XP Metaphor?
Friday, November 1, 13
11. Test Driven Design
It’s a kind of design technique, not a way to test.
When TDD is not useful:
when your don’t care about design
ie. technical spikes, learning exercises
Friday, November 1, 13
12. I get paid for code that works, not for tests, so
my philosophy is to test as little as possible to
reach a given level of confidence.
Kent Beck Stackoverflow
Test Driven Design
It’s a kind of design technique, not a way to test.
When TDD is not useful:
when your don’t care about design
ie. technical spikes, learning exercises
Friday, November 1, 13
13. Question:
Why designing for testability result
in good design?
The caveman house design
Carlo Pescio
Friday, November 1, 13
14. Question:
Why designing for testability result
in good design?
The caveman house design
Carlo Pescio
Global state
Hidden dependencies
Inflexible behavior
Friday, November 1, 13
Things that work together
are kept close
15. Let’s start from Assertions
One of the least followed TTD rule says: “There must be
one assertion for test”. Why?
The point behind testing one thing at time is the we want to
run all the state checks, every time independently.
No IF in the tests.
No logic in the tests, much less duplication with tested logic.
Friday, November 1, 13
16. Let’s start from Assertions
One of the least followed TTD rule says: “There must be
one assertion for test”. Why?
The point behind testing one thing at time is the we want to
run all the state checks, every time independently.
No IF in the tests.
No logic in the tests, much less duplication with tested logic.
3 typical reasons for many assertions in a test...
Friday, November 1, 13
18. Mocking rules
At most a single mock and many stubs.
Use stubs for internals and close friends, mocks
for collaborators (i.e. listeners)
Stubs can be prepared in setup or with builder
helpers. Mocks in the actual test.
Try to verify mocks with actual params or matcher,
not any (or maybe you wanted a stub instead?).
Friday, November 1, 13
20. Mock-o-meter
012345
If to test 3 lines of simple code, we have
10 lines of complicated test with mocks.
Which is more likely to have a bug? the
code or the test?
Friday, November 1, 13
22. High Coupling
In software engineering, coupling or dependency is the degree to which
each program module relies on each one of the other modules.
antipattern of high coupling:
cohesion refers to the degree to which the elements of a module belong
together.[1] Thus, it is a measure of how strongly-related each piece of
functionality expressed by the source code of a software module is.
Wikipedia
Friday, November 1, 13
23. A little digression:
Dependency Injection frameworks
The best classes in any application are the ones that do stuff: the
BarcodeDecoder, the KoopaPhysicsEngine, and theAudioStreamer. These
classes have dependencies; perhaps a BarcodeCameraFinder,
DefaultPhysicsEngine, and anHttpStreamer.
To contrast, the worst classes in any application are the ones that take up space
without doing much at all: theBarcodeDecoderFactory, the
CameraServiceLoader, and the MutableContextWrapper. These classes are
the clumsy duct tape that wires the interesting stuff together.
Dagger is a replacement for these FactoryFactory classes. It allows you to focus
on the interesting classes. Declare dependencies, specify how to satisfy them, and
ship your app.
from Dagger introduction
http://square.github.io/dagger/
Friday, November 1, 13
Good things about Dagger:
good and invisible duct tape
25. Duct Tape is important!
That is, it’s important to
wiring up our objects
in the best possible way.
Write tests to show how
your wiring is done
Replace Duct Tape with
Demeter
Friday, November 1, 13
27. Lasagna Code
Lasagna code, coined in 1982 by Joe Celko, is a type of
program structure characterized by several well-defined
and separable layers, where each layer of code accesses
services in the layers below through well-defined interfaces.
[...] A quote usually attributed either to David Wheeler or
Butler Lampson reads, "There is no problem in computer
science that cannot be solved by adding another layer of
indirection, except having too many layers of indirection".
Friday, November 1, 13
30. We have a problem,
Our code is too difficult to test
Friday, November 1, 13
31. We have a problem,
Our code is too difficult to test
Let's write a framework to test it!
Friday, November 1, 13
32. We have a problem,
Our code is too difficult to test
Let's write a framework to test it!
Ok, now we have 2 problems...
Friday, November 1, 13
33. We have a problem,
Our code is too difficult to test
Let's write a framework to test it!
Ok, now we have 2 problems...
Dedicated test stub must be simple and transparent.
They should explain the model, not hide it.
Friday, November 1, 13
34. We have a problem,
Our code is too difficult to test
Let's write a framework to test it!
Ok, now we have 2 problems...
Same problem for who has to develop against a
big framework: even if I have the framework tests,
how can I be sure of not losing pieces around?
Let's model domain simply as whole and then split
it up for the framework.
Dedicated test stub must be simple and transparent.
They should explain the model, not hide it.
Friday, November 1, 13
36. How to improve
If your tests give you pain don't ignore it.
Localize the cause.
Friday, November 1, 13
37. How to improve
If your tests give you pain don't ignore it.
Localize the cause.
Friday, November 1, 13
38. How to improve
If your tests give you pain don't ignore it.
Localize the cause.
Ask to new team members or dev from other
teams their impressions.
Friday, November 1, 13
39. How to improve
If your tests give you pain don't ignore it.
Localize the cause.
Ask to new team members or dev from other
teams their impressions.
Friday, November 1, 13
40. How to improve
If your tests give you pain don't ignore it.
Localize the cause.
Ask to new team members or dev from other
teams their impressions.
Experiment and share.
Friday, November 1, 13
41. How to improve
If your tests give you pain don't ignore it.
Localize the cause.
Ask to new team members or dev from other
teams their impressions.
Experiment and share.
Friday, November 1, 13
42. How to improve
If your tests give you pain don't ignore it.
Localize the cause.
Ask to new team members or dev from other
teams their impressions.
Experiment and share.
Rule 0: TDD is supposed to be fun and simple.
Friday, November 1, 13