Skip to content

Commit 6ba67d5

Browse files
committed
edits and tweaks in 27 hot lava
1 parent c566f2f commit 6ba67d5

File tree

1 file changed

+22
-23
lines changed

1 file changed

+22
-23
lines changed

chapter_27_hot_lava.asciidoc

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,14 @@ and at the higher level of "does it all hang together?".
8585
Our tests need to be fast enough to write,
8686
but more importantly, fast to run.
8787
We want to get into a smooth, productive workflow,
88-
and try to enter into that holy credo of programmers, the "flow state".
88+
and that holy credo of programmers, the "flow state".
8989
Beyond that, we want our tests to take some of the stress out of programming,
9090
encouraging us to work in small increments,
9191
with frequent bursts of dopamine from seeing green tests.
9292

9393
==== Driving Better Design
9494

95-
Finally our tests should help us to write better code.
95+
And our tests should help us to write _better_ code.
9696
Firstly, by enabling fearless refactoring.
9797
Secondly, by giving us feedback on the design of our code.
9898
Writing the tests first lets us think about our API from the outside-in,
@@ -103,9 +103,7 @@ As we'll see, designing code to be more testable
103103
often leads to code that has clearly identified dependencies,
104104
and is more modular and more decoupled.
105105

106-
107-
108-
As we continuously think about what kinds of tests to write
106+
As we continuously think about what kinds of tests to write,
109107
we are trying to achieve the optimum balance of these different desiderata.
110108

111109

@@ -143,10 +141,10 @@ But people will often tell you that a "true" unit test should be more isolated.
143141
It's meant to test a single "unit" of software,
144142
and your database "should" be outside of that.
145143
Why do they say that?
146-
Apart from the lovely warm glow of smug that they get from should-ing us?
144+
Apart from the smug from should-ing us?
147145

148146
As you can tell,
149-
I think the argument from definitions is a bit of a red herring.
147+
I think the argument from _definitions_ is a bit of a red herring.
150148
But you might hear instead, "the database is hot lava!"
151149
as Casey Kinsey put it in a memorable DjangoCon talk.
152150
There is real feeling and real experience behind these comments.
@@ -164,17 +162,19 @@ At PythonAnywhere, our functional test suite didn't just rely on the database,
164162
it would spin up a full test cluster of 6 virtual machines.
165163
A full run used to take at least 12 hours,
166164
and we'd have to wait overnight for our results.
165+
That was one of the least productive parts of an otherwise extraordinary workflow.
167166

168167
At Kraken, the full test suite does only take about 45 minutes,
168+
which is not bad for nearly 10 million lines of code,
169169
but that's only thanks to a quite frankly ridiculous level of parallelisation
170170
and associated expenditure on CI.
171171
We're now spending a lot of effort on trying to move more of our unit
172172
tests to being "true" unit tests.
173173

174174
The problem is that these things don't scale linearly.
175175
The more database tables you have,
176-
the more foreign keys between them,
177-
and the relationships can start to increase geometrically.
176+
the more relationships between them,
177+
and that starts to increase geometrically.
178178

179179
So you can see why, over time, these kinds of tests
180180
are going to fail to meet our desiderata because they're too slow
@@ -334,7 +334,6 @@ by Dave Farley.
334334
Well that's all very well Harry, you might say,
335335
but our current test setup is nothing like this!
336336
How do we get there from _here_?
337-
338337
We've seen how to use mocks to isolate ourselves from external dependencies.
339338
Are they the solution then?
340339

@@ -363,15 +362,14 @@ NOTE: I'm glossing over the use of mocks in a "London-school"
363362
=== The Actual Solutions Are Architectural
364363

365364
The actual solution to the problem isn't obvious from where we're standing,
366-
but it actually lies in rethinking the architecture of our application.
365+
but it lies in rethinking the architecture of our application.
367366
In brief, if we can _decouple_ the core business logic of our application
368367
from its dependencies, then we can write true unit tests for it,
369368
that do not depend on those, um, dependencies.
370369

371370
Integration tests are most necessary at the _boundaries_ of a system--at
372371
the points where our code integrates with external systems,
373372
like the database, filesystem, network, or a UI.
374-
375373
Similarly, it's at the boundaries that the downsides of test isolation and
376374
mocks are at their worst, because it's at the boundaries that you're most
377375
likely to be annoyed if your tests are tightly coupled to an implementation,
@@ -460,7 +458,7 @@ Martin Fowler and Kent Beck,
460458
which you can follow https://martinfowler.com/articles/is-tdd-dead/[here].
461459

462460
Like any technique, these patterns can be misused,
463-
but I wanted to make the case for the upside of these patterns:
461+
but I wanted to make the case for their upside:
464462
by making our software more testable,
465463
we also make it more modular and maintainable.
466464
We are forced to clearly separate our concerns,
@@ -501,7 +499,6 @@ image::images/frog-in-a-pan-placeholder.png["An illustration of a frog being slo
501499

502500
For small to medium-sized applications, as we've seen, the Django test runner
503501
and the integration tests it encourages us to write are just fine.
504-
505502
The problem is knowing when it's time to make the change
506503
to a more decoupled architecture, and start striving explicitly for the Test Pyramid.
507504

@@ -510,29 +507,26 @@ since I've only experienced environments where either someone else made the deci
510507
before I joined, or the company is already struggling with a point where it's
511508
(at least arguably) too late.
512509

513-
Another is, the longer you leave it, the harder it is.
514-
515-
Yet another is, because the pain is only going to set in gradually,
510+
One thing to bear in mind, though, is that the longer you leave it, the harder it is.
511+
Another is that because the pain is only going to set in gradually,
516512
like the apocryphal boiled frogs, you're unlikely to notice
517513
until you're past the "perfect" moment to switch.
518-
519-
One more suspicion: it's never going to be a convenient _time_ to switch.
514+
And on top of that, it's _never_ going to be a convenient time to switch.
520515
This is one of those things, like tech debt,
521516
that are always going to struggle to justify themselves in the face of more
522517
immediate priorities.
523518

524519
So perhaps one strategy would be an Odysseus pact,
525520
tie yourself to the mast, and make a commitment--while the tests are still fast--to
526521
set a "red line" for when to switch.
527-
"if the tests ever take more than 10 seconds to run locally,
522+
For example: "if the tests ever take more than 10 seconds to run locally,
528523
then it's time to rethink the architecture".
529524

530525

531526
I'm not saying 10 seconds is the right number by the way.
532527
I know plenty of people who are perfectly happy to wait 30 seconds.
533528
And I know Gary Bernhardt, for one, would get very nervous
534529
at a test suite that takes more than 100ms.
535-
536530
But I think the idea of drawing that line in the sand, wherever it is,
537531
_before_ you get there, might be a good way to fight the "boiled frog" problem.
538532

@@ -551,16 +545,18 @@ and spot the problems before they get too large.
551545
In this book, I've been able to show you how to use TDD,
552546
and talk a bit about why we do it, and what makes a good test,
553547
but we're inevitably limited by the scope of the project.
554-
555548
What that's meant is that some of the more advanced uses of TDD,
556549
particularly the interplay between testing and architecture,
557550
have been beyond the scope of this book.
558-
But I hope that this chapter has given you enough of a guide to find your way
551+
552+
But I hope that this chapter has been a bit a guide to find your way
559553
around that topic as your career progresses.
560554

561555

562556
==== Further Reading
563557

558+
A few places to go for more inspiration:
559+
564560
Fast Test, Slow Test and Boundaries::
565561
Gary Bernhardt's talks from Pycon
566562
https://www.youtube.com/watch?v=RAxiiRPHS9k[2012] and
@@ -613,3 +609,6 @@ A Take From the World of Functional Programming::
613609
explores the idea of "Functional Core, Imperative Shell".
614610
Don't worry, you don't need a crazy FP language like Haskell or Clojure to understand it,
615611
it's written in perfectly sensible JavaScript.
612+
613+
614+
Happy testing!

0 commit comments

Comments
 (0)