2. Additional note:
This presentation has been slightly adjusted after
the conference. Some images have been removed
and some notes have been added to provide
context.
3. Ongoing project
alexander.tarnowski@crisp.se
alexander_tar
Blog blog.crisp.se/author/alexandertarnowski
www www.techbookreader.com
http://leanpub.com/developer_testing
4. My system’s dependencies are like spaghetti
My system is ruled by a database
It’s a ritual to deploy my system
My system doesn’t have a business layer
My system has few and poor unit tests
My system’s end-to-end tests don’t work
5. Frontend Legend
EWC = Enterprise-wide componment
Front
= Depends on
end = Packaged into
WS developer pack from 2004
”Enterprise-wide” component Backend
EWC Back
core end
core
EWC Back
shared end
shared
Enterprise message bus library
Joker: flickr: GoShows
6. A number of
data sources
Alternative message queue
implementation Application’s
config files
?
Parts of the
application
Message bus
library
flickr: Andrew Coulter Enright
7. One Database to rule them all, One Database to find them,
One Database to bring them all and in the darkness bind them
8. Additional note:
A lengthy manual deployment
script that’s not up-to-date has a
striking resemblance to
hieroglyphs.
flickr: rfzappala
9. Good idea Bad idea
Database
Additional note:
Some frameworks try really hard
to provide persistence as close to
the view as possible. When is that
a good idea?
10.
11. Είχαν τεςςαρϊν μεταγλωτίςει ασ ςαν, αλφα εκτελείται δεν τι. Από κα χρόνου χαμθλόσ ποςοςτό. Γειτονιάσ εργαηόμενων να πεσ
επενδυτισ το. Χάοσ προςεκτικά δε ςτθ. Όρο πάρα ιδιαίτερα αν, όςο το πετοφν γνωρίηει.
Το όςο γραφικά δθμιουργίεσ χαρακτθριςτικό, όλα μθ ζργων περίπου. Διακοπι οζλεγχοσ χαρακτθριςτικϊν να όχι, μθ Ήδθ ζτςι
Thread.sleep(3000);
χρόνου κα. Στο με όταν λοιπόν ςθμαντικόσ, ζρκει ςχεδιαςτισ ιδθ τι. Ασ τθν γειτονιάσ αγοράηοντασ. Ασ πετοφν αποτελζςει κα μπουν
προςλάμβανεσ, πιο ωσ ςτθν προςπακοφν.
Thread.sleep(3000);
Πω δουλζψει προςεκτικά χαρακτθριςτικϊν ςου, ζςτελνε φακζλουσ ανακλφψεισ τι νζα. Ατόμου αποφάςιςε που τι, προςλάμβανεσ
των, ποςοςτό επιτίκενται το ναι. Πω ερωτιςεισ χρειάηονται λεσ, βιμα πάρεισ κρατάει να κλπ. Τθν ξεχειλίηει. Τθν πετάνε χαμθλόσ
χαρακτθριςτικϊν να, δε κρατιςουν προβλθματικι μθν. Τθ κφκλο κανείσ απίςτευτα ϊρα, αλγόρικμου προβλιματα αντιλιφκθκαν.
Υόρκθ καρζκλα λιγότερο να ότι, τότε μπουν κρατάει πιο οι. Τι ςου γραφικά αρπάηεισ δουλεφουν. Ώσ βακμό δθμιουργίεσ, μια μα κζματα
διοικθτικό, δε πελάτεσ δυςτυχϊσ ςυγχρόνωσ ςασ. Κι τουσ δίνοντασ λεσ. Νζεσ εξαρτάται οι όχι, ϊσ ξζχαςε προϊόντα ότι.
Thread.sleep(1000);
Με μάλλον κακόκεφουσ χρθςιμοποιοφνταν που, μετριςεισ εργοςταςίου παρατθροφμενθ τθ λεσ. Λοιπόν ναί να. Αν ιδθ νζων εκτόσ,
Thread.sleep(2000);
ςασ άρκρων χριματα χρθςιμοποιιςει μθ. Εδϊ άμεςθ ατόμου αναγκάηονται μα, μζςθσ τελικϊν ςφαλμάτων εταιρείεσ τα.
Thread.sleep(3000);
Δοφλευε μθχανισ ροι κι, ϊσ τζτοιο διακοπι αναηιτθςθσ τον, τισ ορίςτε ατόμου εργαηόμενων ϊσ. Όχι λοιπόν κρατάει κα. Μάκε όχι
Additional note:
Long record/playback tests with
incorrect handling of
asynchronicity tend to look like
Greek after a while.
flickr: bunky’s pickle
12. Dependency spaghetti
Few and poor Unknown app server
unit tests configuration
Data
base Where do we start
No business layer Record/playback
(with timing issues)
Manual deployment One database
13. What Why
New code unit-tested We’re in a hole and we
don’t want to dig deeper
Create a business layer Quality in the long run
Automated end-to-end • Initiate change
tests for happy paths • ”Quick” wins
14. @Test
public void aUserCanLogIn() {
application.login(”testuser”, ”secret”);
}
Additional note:
Yes, this test has no assertion.
Fundamental checks, such as
verifying navigation, are built into
the test infrastructure.
15. Additional note:
Sequence of steps to reach a state
where a fundamental login test
(smoke test) could be executed.
Fixing the dependency mess, the unit
tests, and adding a business layer
became an ongoing activity
Creating new (= outside the scope of this talk).
databases
with classified
data is easy
Application
deployed to a Deployment
server with automated
known config
Start Login test runs
GOAL
16. Work the system
Import all objects See where it crashes
Drop all objects Add the missing object
Add data to object Classify data
Document
flickr: Klearchos Kapoutsis
17. Additional note:
At the time of the conference, the
system had been automatically
deployed 181 times. In ½ year, that’s
roughly once a day. Given that manual
deployment took between 5-60
minutes, the time saved was 2 weeks.
19. Our take aways and advice – Big picture
• Don’t be overwhelmed
• Black boxes in your environment make
you feel uneasy and waste time
• Achieving testability proved to
be a good guide
• After a while, the approach
became second nature
20. Take aways – Details
• Using simple tools helped us save time
• End-to-end tests without controlling the
database shouldn’t and didn’t work
• Record/playback didn’t work this time either
• Nobody asked about ”acceptance tests
readable by the stakeholders”
21. However...
2012-10-22 16:16:31,528 ERROR [http-127.0.0.1-8989-2]
(SynchronizationRegistry.java:46) - Exception processing transaction
Synchronization after completion
java.lang.NullPointerException
at com.organization.system.TreeObject.isEquipment(TreeObject.java:34)
Additional note:
It doesn’t matter if you can get your
test infrastructure right. Quality
cannot be tested in. Spaghetti
dependencies, poor unit test coverage
and lack of business layer still were a
problem.
Notas do Editor
161/6 months =~ once a day161 * (5-60 minutes/deployment) =~ 2 weeks
DonkeyHotey
You Can’t test quality in2012-10-22 16:16:31,528 ERROR [http-127.0.0.1-8989-2] (SynchronizationRegistry.java:46) - Exception processing transaction Synchronization after completionjava.lang.NullPointerExceptionat com.organization.system.TreeObject.isEquipment(TreeObject.java:34)