November 2000
National Cancer Institute Anna Massey
in a series of accidents therapy
planning software created by multi data
systems international an American
company miss calculates the proper
dosage for patients undergoing radiation
therapy the software allows a radiation
therapist to draw on the screen the
placement of metal shields called blocks
designed to protect healthy tissue from
the radiation
however the software only allows doctors
to use for shield knots
and the doctors wish to use five the
doctors realize that they can trick the
software by drawing all five blocks as
one big block with a hole in the middle
but what the doctors don’t realize is
that the software gives different
answers depending on which direction the
hole is strong draw it in one direction
and the correct dose is calculated draw
it in another direction and the software
recommends to wise the necessary
exposure at least eight patients die the
doctors who are legally obligated to
double-check the computers calculations
by hand are indicted for murder so let’s
talk about unit testing like most of you
the software that I write cannot kill
people but also like most of you people
do rely on the software that I write I
rely on the software of others all the
time in my daily life I really screws me
up when the software that I rely on
breaks down sometimes when it breaks
it’s just annoying sometimes it is
really really frustrating and ruins my
entire day and sometimes it has caused
me to loose work and actually made me
fail at things at at school work
your software probably doesn’t control
radiation shield but your software helps
people and helping people is important
therefore as programmers we need to take
the quality of our software series the
team that I work in does a lot of
testing in many different ways and
they’re all good but I would like to
spend this video talking about one
specific kind of testing unit test and
the team I work in today does write unit
tests unit tests is part of how we work
and it has worked out really well for us
however in most teams that I’ve worked
in we haven’t written unit tests and the
funny thing is that in those teams most
of us or at least many of us wanted to
write unit tests but then we didn’t what
did my current unit testing team do that
my former non unit testing teams didn’t
do that is what this video is about this
video is divided into three practical
steps that I think made my team into
unit testers I will spend the entire
video going into detail on each step I
will show no code but there will be
beautiful drawings the three steps are
one the side that commits must be unit
tested we will talk about how important
it is that your team commits to one
simple rule if a commit does not have
unit tests it does not go into the
repository I will also talk about how to
convince your team to commit to that
step to teach with mandatory code review
we’ll talk about how you can use
mandatory code review to teach each
other to unit tests step 3
unbraid your code in the final step I
will talk about how you can
separate your code into units using two
design patterns injection and force arms
let’s dive into step one the side that
commits must be unit tested everybody in
your team needs to agree that from now
on no commit enters the repository
without that commit being covered value
it tests ideally you do this at the
beginning of a project however in
practice that almost never happens
there is simply no incentive to write
unit tests at the beginning of your
project the code is so small and
manageable and cute nobody nobody is
afraid of that code unit testing is a
really hard sell at that point but later
it is much easier when your code has
grown to a million lines and four
hundred weird edge cases and everybody
is overwhelmed by regression bugs that
is the moment when you sell people on
unit testing and when you do the cell
has to be clear and simple no commits
without tests that rule is realistic
it’s easy to remember it’s unambiguous
and it allows you to work in small
chunks which allows you to squeeze it
past any point the hair slowly but
surely adhering to the no commits
without tests rule will get you a system
under test and that is step one the side
that commits must be unit tested
step two teach with mandatory code
review unit testing is hard to do
emotionally hard unit testing is like
flossing your teeth
it just doesn’t provide enough instant
gratification to be natural to us we
have a monkey brain and this brain is
not adapted to build long term computer
architecture this brain is adapted for
the quick acquisition of therefore we
need a structure to hold ourselves
accountable a nut structure my friends
is mandatory code reviews mandatory code
reviews will do wonders for your code
quality the list of benefits of
mandatory code review is really long but
there are many other talks and books and
stuff about that so I’m going to focus
on one of them you can use mandatory
code review to stay committed to unit
testing and that is because mandatory
code review allows you to start using
one simple sneaky or extremely effective
trick when you are reviewing code and
you are a little bit uncertain if the
tests are actually a good
you can simply mess things up a little
bit in the code and see if tests do
break and if they don’t like they should
then you just comment on the commit
saying hey this uh this code looks nice
but I I could delete this entire line
and the tests still pass could you make
sure that that is covered by the test as
well that is very good actionable
feedback and it’s a really good way of
teaching developers unfamiliar with unit
testing how to get into it that’s step
two teach with mandatory code review
step three unbraid your code as soon as
your team starts writing unit tests for
an existing code base you will all run
into a or a huge in breakwall and it’s
going to sound something like this but
this code is too complex to unit tests
do not panic this is normal it happens
to everyone
the
word complex is Latin and it means
braided jumbled together complex is the
opposite of another Latin word called
simplex which means separate or
side-by-side or units do you get it when
you’re saying that your code is too
complex you are actually saying that it
is not in units and not unsurprisingly
your code needs to be in units in order
for you to unit test it fortunately for
us there are well documented and
battle-tested design patterns to help us
break braided code into units we are
going to talk about two of them
injection and facades I’ll begin with
injection I’m going to describe a
problem and then I’m going to show you
how to solve it using injection let’s
imagine that we have a system that does
orders and payments we have discovered
that our system crashes if the bank is
down we want to fix this by displaying a
could not connect to your bank message
so that our customers get annoyed with
their shitty bank instead of with us we
also want to write a unit test so that
this AAG is not rare its ugly head again
so imagine that our system looks like
this it has an order thing let’s say
that we call create order on the order
thing as a result of calling create
order the order thing will inside itself
instantiate a hate thing like this the
order thing will then call pay on the
pay thing instance like this which in
turn sends the payment request to the
back like this now we want to write the
unit test that simulates the bank
returning an error one good way of
solving this would be a fake facing a
mock pay thing which in turn returns a
mock error the problem is that we cannot
do this in this architecture
because painting is created inside the
order thing and unit tests that we would
write would have no way of getting it’s
not passing into the order thing and
this is an example of braided code there
is a unit that we want to test order
thing but it is braided together with
painting and that prevents us from
testing the order things separately we
cannot write unit tests for the order
thing because it is not a unit it’s
actually two units braided together well
instead of instantiating painting inside
of order thing we instantiate it outside
and inject pasting into order thing like
this the order thing is no longer
responsible for creating a payment thing
instead it now expects to be passed up a
thing that has been created outside the
real code we’ll use the real injected
pay thing while the unit tests instead
inject and mock Paisley like this now
when we are writing our unit tests we
can simply tell the mock pay thing you
throw an error when pay is called on
like this are injecting pay thing into
order thing instead of having ordered
thing create a thing in sign of itself
we have unbraided the tool allowing us
to test them as separate units and that
is the injection pattern we are now
going to look at another problem and I
am going to show you how to solve it
using facade now imagine a similar
scenario where you have a pay thing and
you have a order thing but the painting
that’s not your code it’s the third
party component that the painting
company provides and now imagine that
the pay thing API looks like this to
make a payment you start by passing the
Bank API endpoint URI
to the connect method and the API
endpoint that’s the same every time that
will return a new object a connection
which you in turn will call pay off the
pay method wants a protection
eligibility which is you know some
legacy parameter that should always be
set to true and it also wants an amount
that in turn yields a response object
which has a property called is success
this is not the best API it’s not the
worst API it’s pretty easy to call but I
now want you to pause this video and
have you passed yet you should I’m
waiting hot yeah you pause of course you
did
no you didn’t let’s have a look you’d
have to first create the mock response
object here at the bottom then you
create a mock connection object in the
middle with a payment that will return
the democracy on and finally create a
mock painting with a connect method that
returns the mock connection object when
connect this call that is not rocket
surgery but it is very cumbersome and
you would be repeating that code that
mocking dance for every test and that is
very annoying because we’re not testing
the pay thing here we’re testing the
ordered thing and those tests are only
interested in one thing that the correct
amount is passed to the pay thing an
effective way to deal with this is to
simply encapsulate the whole API behind
a facade to simplify and flatten it like
this what we have done here is to wrap
the entire painting inside a payment
facade and the facade has a much simpler
interface just as a single pay method in
this new refactored world instead of
passing in the pay thing directly into
the order thing we just pass in the
facade like this now when writing a test
we just mop payment facade instead of
mocking pay thing like this if we were
mocking the pay thing directly every
test would need to do a bunch of stuff
to mark the payment creating that
connection object and so on but the
payment facade API is flat and stupid so
the only call that the tests need to
mock is the pay call in this video we’ve
talked about how to get your team to
start unit testing we have talked about
three simple things that you can do
design that commits must be unit tested
teach with mandatory code review and
unbraid your code
you see Jackson and the Sox you have
just watched an episode of fun fun
function this is a weekly show where we
try to become more excited and confident
about programming by exploring old
wisdom wild ideas and having fun I’m the
one doing the talking here but the show
is shaped by you please comment down
below and tell me who you are and how
you want to improve as a program finally
and most importantly make sure that you
don’t miss the next episode of fun fun
function subscribe to the channel or
follow me on twitter at MP Jamie until next Monday stay curious