00:00:00.900
foreign
00:00:12.599
hello hello welcome everybody thank you
00:00:14.820
so much for coming out I mean Ahoy
00:00:21.660
shouting into the microphone that's
00:00:22.980
always great my name is Aji that's a
00:00:25.680
hard J uh I've been a professional
00:00:28.019
developer since 2016 but if you count
00:00:30.720
geocities I've been putting code on the
00:00:32.880
web since 1996.
00:00:36.000
uh anyone in the room not yet born in
00:00:38.460
1996 hence
00:00:41.040
a couple of you that's awesome I'm so
00:00:43.079
glad you're here I am regretting that I
00:00:45.480
asked that question a little bit though
00:00:49.020
so I do uh never really know what to say
00:00:51.480
during these intros so
00:00:53.940
um how about in fourth grade I got the
00:00:56.579
lead in the school play of mice and
00:00:58.920
Mozart where we told the life story of
00:01:01.079
Wolfgang Amadeus Mozart Through The Eyes
00:01:03.239
of a family of mice that lived in his
00:01:05.040
walls I played Mozart at nine and I've
00:01:07.680
been trying to relive That Glory ever
00:01:09.299
since
00:01:11.400
so I'm going to take a guess that we're
00:01:13.439
on the same page about something
00:01:15.720
I'm going to assume that everyone here
00:01:18.000
agrees that testing is important
00:01:21.540
and that test driven development can be
00:01:23.580
massively beneficial
00:01:25.560
you're here at a software Conference of
00:01:28.619
a community that overwhelmingly
00:01:30.240
appreciates automated testing and you
00:01:32.700
came to listen to your tdd treasure map
00:01:34.799
which might just imply that tdd is a
00:01:37.560
kind of treasure
00:01:39.540
so I'm going to skip the arguments that
00:01:41.280
try and convince you of the benefits of
00:01:43.140
robust automated tests that verify your
00:01:46.020
code is working properly defend against
00:01:48.479
regressions support refactoring act as
00:01:51.840
living documentation and provide design
00:01:53.939
guidance
00:01:55.799
and all although I didn't really
00:01:57.180
understand the Nuance at the time that
00:01:59.700
was certainly the feeling they tried to
00:02:01.320
instill in us at my coding boot camp
00:02:04.079
but we had so little time I graduated
00:02:06.840
however having never written a test
00:02:08.759
without feeling the benefits of a good
00:02:11.160
test Suite plus it seemed like a paradox
00:02:14.599
right right the thing that verifies the
00:02:17.459
code that I will have written before I
00:02:19.860
am going to have written the code that I
00:02:21.540
will have been about to write
00:02:23.580
yeah sure let me just jump into my time
00:02:25.500
machine and take a look at that PR I'm
00:02:27.120
going to put up tomorrow
00:02:29.459
testing first can be difficult
00:02:31.920
that's true for seasoned Sailors but
00:02:34.080
even more so for those newer to this
00:02:35.940
career when it's a challenge to even
00:02:37.920
reason about what code to write at all
00:02:41.099
how was I going to make it out of this
00:02:42.660
mess
00:02:43.860
like Archimedes in the bathtub or Newton
00:02:46.379
and gravity we need a compelling yet
00:02:48.420
apocryphal story of Discovery to go with
00:02:50.459
it
00:02:51.660
so scratching my head over this problem
00:02:53.640
I wandered over to my bookshelf that has
00:02:55.560
all of my Joby job career type books
00:02:58.319
there's Sandy Metz practical
00:02:59.959
object-oriented design in Ruby there's
00:03:03.000
Atul gawandes the checklist Manifesto
00:03:05.540
wonderful tomes that have set me on the
00:03:07.920
path when I've needed them before
00:03:10.800
wait
00:03:12.800
that's Robert Louis Stevenson's Treasure
00:03:15.540
Island what is how is this on this shelf
00:03:18.180
I'm the child of a librarian this is so
00:03:20.519
embarrassing Miss shelving happening in
00:03:22.920
my own home
00:03:25.319
oh but it dawned on me of course this is
00:03:28.019
here of course because treasure maps
00:03:32.400
okay flowcharts
00:03:36.239
but think about it a treasure map is a
00:03:39.120
flow chart sure one of the core
00:03:41.220
strengths of a flowchart is the
00:03:42.900
branching the logic being able to map
00:03:45.420
out decisions that lead to different
00:03:47.280
outcomes but Stevenson's Captain Flint
00:03:49.860
only wants the happy path that ends into
00:03:52.319
doubloons
00:03:53.519
if we fill out the map we put a decision
00:03:56.640
Branch here at the edge of this dense
00:03:58.440
jungle without the map in our hands we'd
00:04:01.080
be lost in 404 not found
00:04:04.140
One Way lies treasure and the other to
00:04:06.599
an encampment of rival Pirates and 409
00:04:08.940
conflict
00:04:10.159
a decision here an East means treasure
00:04:13.739
but West means eaten by crocodiles and
00:04:16.320
just like that the whole crew is 410
00:04:18.600
gone
00:04:22.199
the rest of you need to brush up on your
00:04:23.639
HTTP status codes
00:04:27.060
not only is a flowchart useful for
00:04:29.040
retracing your steps to your long-buried
00:04:31.080
ill begotten gains but one of the most
00:04:32.880
helpful artifacts for understanding the
00:04:34.919
control flow of a system and invaluable
00:04:37.620
documentation for new team members it's
00:04:40.440
a kind of visual pseudo code think about
00:04:42.900
all of the low code and no code
00:04:44.940
solutions that are built on flowcharts
00:04:47.520
as a UI because they're so simple to
00:04:50.400
understand but potentially powerful
00:04:53.520
we can leverage that same strength as a
00:04:56.100
shared language to build understanding
00:04:57.900
between Technical and non-technical team
00:05:00.000
members and stakeholders and get buy-in
00:05:02.400
from the business in a way that we never
00:05:04.800
could with code
00:05:07.199
but no longer will the usefulness of
00:05:09.479
this tool stop at the code's Edge we're
00:05:12.000
going to learn how to directly apply it
00:05:13.860
to writing tests and eventually code
00:05:17.040
so consider yourselves horn swaggled and
00:05:20.100
snared into being my crew aboard the
00:05:22.139
Good Ship capybara on route to the
00:05:25.320
promised land where testing before you
00:05:27.240
leave Harbor can be smooth sailing
00:05:29.340
before this half hour be over we'll raid
00:05:32.160
the ship a knowledge and you'll have new
00:05:34.020
techniques of your own to boot
00:05:42.240
I do I do want to apologize for that
00:05:44.340
accent for everyone watching who is a
00:05:46.139
17th century Caribbean pirate
00:05:48.960
sorry privateer
00:05:52.380
a chart can relate fairly directly to
00:05:54.600
code serving to mimic the control flow
00:05:57.000
of an app but how it relates to testing
00:05:59.220
might not be as obvious we'll use a
00:06:01.620
pretty common situation of a rails
00:06:03.120
controller action to demonstrate how we
00:06:05.039
can take a handful of acceptance
00:06:06.660
criteria to a flowchart turn that into
00:06:09.300
test rigging test code and application
00:06:11.699
code
00:06:13.020
a couple of quick caveats and
00:06:14.580
definitions to simplify are upcoming
00:06:16.620
parlay
00:06:18.600
when I say feature I mean that to be any
00:06:21.360
unit of work be it a whole feature a bug
00:06:23.759
fix partial implementation whatever I'll
00:06:26.400
stick the same feature for brevity
00:06:28.740
there's also probably an actual term for
00:06:31.319
it but when I'm talking about a test
00:06:32.819
Suites rigging I mean the describe
00:06:35.400
context and it blocks that make up the
00:06:37.740
tests like here these lines with the
00:06:40.380
descriptive strings and the levels of
00:06:42.000
indentation that show how they relate to
00:06:43.680
one another that's what I'm calling the
00:06:45.479
rigging
00:06:46.979
and although this process will work with
00:06:48.840
any testing Library Ruby or not my
00:06:51.419
examples are going to be in our spec
00:06:53.039
because as we all know it is a pirate's
00:06:55.919
favorite testing framework
00:07:00.600
the app our team is building is called
00:07:03.120
Pirate Cove where freelance free booters
00:07:05.699
can list their available skills and
00:07:07.740
rating resume for captains looking to
00:07:09.960
round out a crew for upcoming misdeeds
00:07:13.319
sorry Adventures
00:07:16.139
our app has users we call them pirates
00:07:18.660
pirates have profile Pages it's off the
00:07:21.780
shelf uh rails resource routing with the
00:07:24.960
standard crud actions
00:07:27.960
this afternoon we're pairing all of us
00:07:29.819
don't worry I'll drive
00:07:31.979
and we've picked up a ticket with a new
00:07:33.599
user story
00:07:34.740
and it looks like it's to implement one
00:07:36.660
of those crud actions as a pirate I
00:07:39.360
should be able to fill out the form on
00:07:41.039
my profile page and submit it to change
00:07:43.020
my information
00:07:45.720
the acceptance criteria phrased a
00:07:47.940
different way so user can update a
00:07:49.680
pirate's information from the profile
00:07:51.360
page
00:07:52.319
there are actually two eventual
00:07:54.840
acceptance criteria or requirements on
00:07:57.300
this ticket but we're going to start
00:07:58.620
with just the first and pick up the
00:08:00.060
second as we go
00:08:02.160
so we're going to begin with the action
00:08:03.599
that we know is going to take place
00:08:05.340
that's typically a user acting on the
00:08:07.740
system and here that's our pirate
00:08:09.720
submitting form data
00:08:11.880
standard flowchart symbols have start
00:08:13.919
and end points as rounded shapes so
00:08:16.500
we'll start with that core action at the
00:08:18.120
top center of our workspace
00:08:20.099
when that gets submitted and action
00:08:22.080
occurs on the back end we're going to
00:08:23.759
save that data and how do we resolve
00:08:26.280
well we show the updated information
00:08:27.900
with a redirect to show
00:08:30.840
this alone right there that could be the
00:08:32.399
happy path of our feature we know it's
00:08:34.500
going to get a little more complex but
00:08:35.940
at least it's enough to write the
00:08:37.800
matching rigging
00:08:39.419
begins with a user action
00:08:42.899
some back end work
00:08:45.000
and feedback for the user beginning
00:08:47.100
middle end
00:08:50.220
now at the top of an R spec file we get
00:08:52.200
something like this to start but
00:08:54.000
everything we're doing is going to be
00:08:55.200
under patch update so this is the last
00:08:57.540
time we'll see this to say the save the
00:08:59.399
slides getting a little bit too
00:09:00.360
cluttered
00:09:02.040
right away I can see two outcomes that
00:09:04.500
we expect will happen after form data is
00:09:06.779
submitted by rails convention
00:09:08.760
redirecting to the pirate show page and
00:09:11.279
the only way that the pirate show page
00:09:12.660
is going to have the proper information
00:09:13.800
is if we also update the database to
00:09:16.500
reflect change data
00:09:18.480
this doesn't mean that every bubble in
00:09:19.920
the flowchart needs to be tested and
00:09:21.540
we'll see that coming up but in this
00:09:23.399
case we're testing more than just the
00:09:25.260
very end but also any action that
00:09:27.600
changes something outside of our current
00:09:29.640
test subject a side effect
00:09:32.339
our test subject is the Pirates
00:09:34.080
controller this makes a change in the
00:09:35.940
database way outside the controller
00:09:38.100
that's a result that we want to
00:09:39.720
guarantee will happen to the best of our
00:09:41.519
ability so we'll protect it with a test
00:09:45.480
that way if anyone ever comes along and
00:09:47.339
makes a change that affects that outcome
00:09:49.200
even if the redirect still happens we'll
00:09:52.140
have feedback then an expected result
00:09:54.360
has been affected that's our tests
00:09:56.940
preventing regressions
00:09:59.600
now the other piece to our test rigging
00:10:02.040
are contacts blocks the it blocks are
00:10:05.100
going to match up to the end results the
00:10:07.320
effects of the action the context will
00:10:09.480
correlate to the setups that exist those
00:10:12.060
are found by following each individual
00:10:14.040
path through the chart
00:10:15.899
pretty easy at the moment right now
00:10:17.399
we've only got one path through the
00:10:18.600
flowchart
00:10:20.399
it might make sense to wrap those two it
00:10:22.320
blocks in a context block
00:10:24.839
I don't think we actually gain anything
00:10:26.220
by doing that it's the only context that
00:10:28.620
exists and it's already Ratched wrapped
00:10:30.839
in that patch update describe block so
00:10:33.420
personal preference but I'd leave it off
00:10:35.339
for now
00:10:36.839
what else this indicates by being only
00:10:38.700
one context is that our setup for these
00:10:41.040
two tests will be the same
00:10:43.140
each individual path through the chart
00:10:45.000
will have a different state when the
00:10:46.860
action is performed we're focused on to
00:10:49.019
a level where there is only one action
00:10:51.720
and most of the time that you're
00:10:53.279
building out tests that's how it's going
00:10:55.260
to be maybe different granularities
00:10:57.360
sometimes different params or callers
00:10:59.279
but one single inciting action
00:11:02.459
in the ideal State when you're focused
00:11:04.200
on testing just one action the only way
00:11:06.540
to take different paths through the
00:11:07.920
chart is with a different beginning
00:11:09.180
state or different params to that action
00:11:14.040
so we're still here we kind of know that
00:11:17.160
it's not going to stay this simple and
00:11:18.720
this is a position you might find
00:11:20.040
yourself in pretty often you know that
00:11:22.200
there's more looming but it hasn't
00:11:23.880
actually shown up quite yet
00:11:26.279
so that's not complicated I'd rather
00:11:28.200
start moving forward on something that
00:11:29.579
I'm sure of naive or not rather than
00:11:32.100
speculate and end up down in irrelevant
00:11:34.320
rabbit hole
00:11:35.940
as I said irrelevant Rabbit Hole okay
00:11:38.760
we've got some ambiguity but we've also
00:11:40.860
got something concrete so let's move
00:11:42.779
forward on that I'm confident enough
00:11:44.579
that what comes next will reveal itself
00:11:46.560
as we go through this exercise or if it
00:11:49.500
doesn't it could be outside the scope of
00:11:51.959
what we're trying to accomplish right
00:11:53.339
now plus I want to err on the side of
00:11:55.620
shipping software rather than analysis
00:11:57.959
paralysis
00:11:59.519
and really this is the whole happy path
00:12:01.980
right if nothing goes wrong this is
00:12:04.380
essentially what needs to happen so if
00:12:06.779
we write these tests we'll have a North
00:12:09.000
star to guide us as we sail along and
00:12:11.700
seas get choppier if we ever make
00:12:13.740
changes and these tests fail we should
00:12:17.160
probably do some rethinking
00:12:19.200
our new tests will be preventing our own
00:12:21.959
regressions that's just another reminder
00:12:24.240
that the next developer to work with
00:12:26.339
your code can be ourselves even just an
00:12:30.000
hour later
00:12:32.040
so should we write some tests
00:12:34.500
okay before that
00:12:36.779
um I'm also not here to introduce or
00:12:38.339
debate the different methodologies for
00:12:39.959
writing individual tests that's another
00:12:41.459
talk or workshop and they mostly all
00:12:44.160
boil down to some variation of given
00:12:46.200
when then
00:12:48.720
what might test code for this portion of
00:12:50.579
our rigging look like
00:12:52.079
let's start with the setup we know we
00:12:54.180
need a pirate whose information is going
00:12:55.620
to be updated and whose ID will be part
00:12:57.720
of the URL based on Rails restful
00:12:59.760
conventions
00:13:01.260
and now the action we already said
00:13:03.180
that's going to be when the user submits
00:13:05.339
the form data so if we use rspec's
00:13:07.680
request syntax it might look something
00:13:09.660
like this
00:13:10.920
and eventually our expectation that
00:13:13.500
should redirect
00:13:15.899
here we are with test code for both it
00:13:17.820
blocks from before redirects to the
00:13:19.860
user's show page and updates the
00:13:21.839
database
00:13:23.399
now we've got some wind in our sails
00:13:25.380
we've understood our flowchart as a
00:13:27.360
context and still at Just One path our
00:13:30.060
given is the matching setup
00:13:32.940
the action that begins our flowchart has
00:13:34.980
become the when that's the action taken
00:13:37.320
in our test cases
00:13:39.660
and we've identified the two end States
00:13:41.639
one for the hdb response and one for the
00:13:44.820
database
00:13:46.560
and we've captured them as then in the
00:13:49.500
expectations
00:13:52.200
so as I'm building out a system I'm
00:13:54.240
trying to uncover moments where we might
00:13:56.100
be taking something for granted an
00:13:58.380
assumption that we've built on top of
00:13:59.940
that isn't as guaranteed as we're
00:14:01.680
treating it so I'm asking myself what
00:14:04.320
here is built on a lie
00:14:06.839
what here could go wrong and my eye is
00:14:09.420
drawn to this
00:14:11.579
these params are sent in by a user
00:14:14.519
you know users so do I no I don't trust
00:14:18.300
them
00:14:19.740
they always find
00:14:21.839
interesting ways to stress the system
00:14:24.240
brand new ways to use our software that
00:14:26.399
we never even dreamed of
00:14:29.220
in reality though that's a gift it
00:14:31.320
really is and I believe that but right
00:14:33.120
now it's a problem
00:14:35.279
so far our tests are assuming that
00:14:37.200
everything is going to go smoothly we
00:14:39.360
need to handle what happens when the
00:14:40.920
params don't pass validation
00:14:43.320
so let's fold up the test code like
00:14:44.880
we're in our editor and add this params
00:14:46.740
protection what would params that don't
00:14:49.079
pass validation change about the flow of
00:14:51.660
this chart
00:14:54.139
right that change will never make it to
00:14:56.880
the database and because that can fail
00:14:58.980
we need to add to the flowchart before
00:15:00.720
the persistence a check for validity
00:15:03.360
we'll notate this fork in the road with
00:15:05.519
a diamond because in flowchartland which
00:15:07.500
is a province of diagramopolis a diamond
00:15:09.720
represents a decision
00:15:11.639
something in the setup or the action
00:15:13.800
that is affecting the outcome
00:15:16.199
the value of which decides the branch of
00:15:18.600
the flow to continue down and now we
00:15:21.240
truly have more than one path through
00:15:22.800
the feature and with it another context
00:15:25.380
that needs testing
00:15:27.180
let's trace the two paths so we can see
00:15:29.100
what we're dealing with
00:15:31.680
if a path is a context we're able to
00:15:34.680
tell that one context is separate from
00:15:36.720
the other the nodes in the flow chart
00:15:38.699
that are reflected in the rigging as
00:15:40.560
existing specs can't be reached by that
00:15:43.260
New Path they're an entirely different
00:15:45.240
context
00:15:49.740
let's reflect that in the rigging
00:15:52.500
but how can we know what that context
00:15:54.120
involves it's not as simple as an
00:15:56.160
endpoint there isn't one node in the
00:15:58.199
flowchart that equates to context but
00:16:00.420
many along a path
00:16:02.279
so let's ask ourselves a question what
00:16:04.560
given what setup or initial input will
00:16:07.980
cause the decision to go to the right
00:16:09.660
where we see the two it blocks that we
00:16:11.699
already have
00:16:13.620
valid params right
00:16:16.800
and then the opposite invalid params
00:16:19.380
causes the flow to go to the left
00:16:21.959
and the it block based on Rails
00:16:23.639
conventions will render that render the
00:16:25.620
edit page again and send the object over
00:16:27.360
to The View with those validation errors
00:16:29.160
attached
00:16:30.660
so let's act on these tests in the
00:16:32.579
flowchart as we have it currently what
00:16:34.680
do we want to do next personally I'm not
00:16:37.139
going to feel good about these tests
00:16:38.339
until I see them fail we haven't written
00:16:40.440
any code for them yet so if they pass
00:16:42.420
there is definitely something fishy
00:16:44.339
going on
00:16:45.839
great news the test failed
00:16:48.240
that means we can write some code to
00:16:49.680
make them pass
00:16:51.779
we're going to keep this as simple as
00:16:53.100
possible but let's think about the code
00:16:54.480
that we'll need in order to follow the
00:16:56.100
flowchart and satisfy the tests
00:16:58.440
we'll need to know which pirate
00:17:01.019
if the update works we'll redirect
00:17:05.220
and if not we'll render edit nothing
00:17:07.439
fancy here this is direct from rails
00:17:09.360
generators maybe condensed a little for
00:17:11.459
slides but how did our tests fare
00:17:15.299
nice good work everybody
00:17:19.020
let's just take a moment to reflect on
00:17:21.120
how we got here we use the ticket
00:17:22.980
requirements to make a simple flowchart
00:17:25.260
that met the user story The Happy path
00:17:28.559
and from that flowchart came our test
00:17:30.419
rigging
00:17:31.500
we wrote some tests and uncovered a
00:17:33.480
failure state
00:17:34.620
which led us to expand on our flowchart
00:17:37.320
and rigging
00:17:39.240
and from there we used our understanding
00:17:40.980
of the system at play to write the
00:17:42.720
application code
00:17:44.760
chart rigging test
00:17:48.179
chart rigging code
00:17:51.840
all that is to say that this process
00:17:53.460
isn't going to be linear most of the
00:17:55.260
time usually we won't have written the
00:17:57.600
whole entire flowchart with everything
00:17:59.280
in scope then move on to the entire
00:18:01.320
rigging then the test code then the app
00:18:03.840
code will bounce around acting on the
00:18:06.240
next bit of information that we're
00:18:07.559
confident about uncovering assumptions
00:18:09.720
as we go and adding to our framework in
00:18:12.240
the process
00:18:14.120
well we don't really have everything
00:18:16.679
that's in scope do we remember that
00:18:18.960
there is a second acceptance criteria
00:18:22.080
number one we already have we can update
00:18:24.840
a pirate's profile info but two here
00:18:27.720
says that only authorized Pirates can
00:18:29.640
perform updates
00:18:31.559
so before I check for validity in the
00:18:33.600
same way that we added the valid step
00:18:35.700
before persistence
00:18:37.620
we have a new Step that can interrupt
00:18:39.539
the process before reaching the end
00:18:41.039
states that we had charted before
00:18:43.799
which leads to another path through the
00:18:46.260
chart
00:18:47.280
now ignore for now the implementation of
00:18:49.679
even having a logged in user I've only
00:18:51.419
got actually got 11 and a half more
00:18:53.100
minutes with you but no
00:18:55.820
another path should make us think what
00:18:59.039
another context
00:19:01.440
using the same technique that we did
00:19:03.240
before we can wrap the expectations
00:19:05.100
based on when their paths diverge the
00:19:08.280
first time any paths diverged they go in
00:19:10.320
two different directions
00:19:11.940
green to the left
00:19:13.740
blue and orange to the right
00:19:16.320
so that tells us that there will be two
00:19:18.000
contexts and it's the decision where
00:19:20.280
they branch that tells us what that
00:19:22.260
context is
00:19:23.880
authorize no that's green
00:19:27.539
and because the other paths share the
00:19:29.400
state of a pirate that has permissions
00:19:31.620
to change this data
00:19:33.480
the context about being authorized will
00:19:36.539
wrap them both
00:19:39.960
but we've done this kind of exercise
00:19:41.400
before earlier I bring it up again
00:19:44.100
because I want to throw a metaphorical
00:19:46.080
match in our powder keg
00:19:48.480
turns out what makes someone authorized
00:19:51.480
isn't so cut and dry authorized yes no
00:19:54.720
it's perfectly fine for the flow chart
00:19:56.400
here because at the controller level
00:19:58.440
that's the flow of this action
00:20:01.500
but to be authorized while the logged in
00:20:04.140
Pirate is either the pirate being
00:20:05.880
changed or a pirate with the admin role
00:20:10.200
what was once three paths through the
00:20:12.360
chart is now five and if we reflect that
00:20:14.640
in the test cases we go from four to
00:20:17.520
seven that's 57 more tests and I like
00:20:21.240
tests and all but conceptually this
00:20:23.520
doesn't feel too much different from
00:20:25.020
what we already had
00:20:27.840
we added this section but it makes the
00:20:30.720
same decision authorized yes no it's
00:20:34.020
just a more complicated process
00:20:36.179
maybe you're already standing where I'm
00:20:38.640
leading you or maybe you're on the way
00:20:40.020
but if this box was opaque
00:20:43.679
and all we saw was authorized yes no
00:20:47.460
then the rest of the paths would have
00:20:49.200
the same information in the same flow
00:20:51.780
right
00:20:54.240
does the pirate controller really need
00:20:56.280
to know how to tell if a pirate can make
00:20:58.559
the change or does it just need to know
00:21:00.660
whether to make them walk the plank or
00:21:02.280
not
00:21:03.600
it's the latter right
00:21:05.580
so let's encapsulate that logic in an
00:21:08.100
object look at this Robert Louis
00:21:10.320
Stevenson Sandy Metz back together after
00:21:12.660
all this time
00:21:15.120
and because we can test the
00:21:16.620
authorization logic over in this
00:21:18.720
object's tests some might even call it a
00:21:21.059
service object it doesn't have to be
00:21:23.100
part of our controller test at all we
00:21:25.500
can mock the call to the service object
00:21:27.299
within the test force it to say yes or
00:21:29.520
no all a part of our setup and suddenly
00:21:31.980
we're back with just authorized yes no
00:21:34.860
and the next time that you're looking to
00:21:37.080
encapsulate some logic away in a service
00:21:39.480
object look for parts of your flow chart
00:21:41.880
where those paths go apart do something
00:21:44.059
self-contained but then converge back
00:21:46.559
together like we did here
00:21:48.539
but if we think about it
00:21:50.340
we already have similar nodes in this
00:21:52.980
flowchart don't we
00:21:55.580
right there
00:21:57.539
this isn't a single thing this is active
00:22:00.480
record taking our params hash doing
00:22:02.400
something with ARL spitting out SQL
00:22:04.980
traversing to a database which is a
00:22:06.840
whole different program updating a
00:22:08.460
resource can you imagine the flowchart
00:22:10.260
on that
00:22:11.820
an active record just handles it so we
00:22:14.280
can put a single box in our flowchart
00:22:17.220
in the same way that we zoomed in to get
00:22:19.740
to an authorization service class and we
00:22:22.260
understand the zooming we could do
00:22:23.940
behind the persist node we can also zoom
00:22:26.520
out from our controller
00:22:28.860
up until this point we've been looking
00:22:30.539
at a single action and everything else
00:22:32.460
happens like dominoes without our
00:22:34.620
influence
00:22:35.820
this is a flow chart for ordering a book
00:22:37.980
from Amazon
00:22:40.020
uses very high level it's really zoomed
00:22:42.120
out it's all the way to the user
00:22:43.320
everything is abstracted away they're
00:22:45.480
not thinking about HTML servers
00:22:47.580
databases none of it and yet this is an
00:22:50.760
incredibly useful diagram even for
00:22:53.340
testing even for writing code
00:22:56.220
in the same way that our happy path
00:22:58.320
tests were our North Star while building
00:23:01.140
and refactoring something like this can
00:23:03.240
be the North Star for an entire business
00:23:05.220
or development team able to ask
00:23:07.500
themselves can a user still order a book
00:23:09.799
or does this help a user order a book
00:23:14.340
probably not Amazon anymore because
00:23:16.440
nowhere on here do I see shoot founder
00:23:18.299
into space
00:23:20.880
I also don't see let him come back
00:23:22.559
either but we did that
00:23:26.460
each of these purple blocks is an action
00:23:28.440
by a user sign in add to cart each and
00:23:31.980
every one of them probably could be its
00:23:34.260
own controller action if it was rails
00:23:36.120
each with its own flowchart as intricate
00:23:38.640
but probably more so than the one that
00:23:40.799
we just built but at this level this can
00:23:43.559
a user order a book level
00:23:46.080
those aren't important for the same
00:23:48.240
reason that it wasn't important to our
00:23:49.919
controller if the user was an admin or a
00:23:52.620
specific pirate
00:23:54.179
still each branch or each flow is going
00:23:56.820
to need a test maybe at this level a
00:23:59.220
context maybe not again personal
00:24:00.900
preference but I see five six tests here
00:24:05.419
eventually every purple box reached by
00:24:08.159
the path of a test from start to end
00:24:12.299
so I I hope that helps you see that
00:24:14.940
there aren't rules on how to do a
00:24:17.280
treasure map technique but some ideas
00:24:19.860
and advice on how you might be able to
00:24:21.900
apply it in your own work I literally do
00:24:24.840
this in my work this is a commit message
00:24:27.840
I wrote last week
00:24:30.840
that's right I know
00:24:34.200
I put the flow chart in the commit
00:24:36.840
message
00:24:38.700
and if you two want your commit messages
00:24:40.559
to bring all the boys to the yard
00:24:45.480
the tool I use to make this plane checks
00:24:47.940
plain text flowchart is ASCII flow
00:24:50.400
that's askiflo.com so yeah take these
00:24:54.000
ideas use them throw away what isn't
00:24:56.760
working add on where it falls short
00:25:01.020
oh okay and if you do add on or do
00:25:03.600
something cool with it please please
00:25:05.039
tell me on the twits the gram GitHub any
00:25:07.860
of these things I'm around
00:25:09.659
I would love to know how you remix this
00:25:12.240
or adapt it to other Frameworks and
00:25:14.220
languages it's open source this thing
00:25:16.140
right
00:25:17.100
because
00:25:19.500
our we might be here under the auspices
00:25:22.140
of land Lovin rails rather than ocean
00:25:24.960
waves I can without objective see
00:25:28.320
whether your features be crafted a ruby
00:25:31.020
Emerald carved of elm adorned with Jade
00:25:34.799
and pearl are crested in Rust are this
00:25:38.940
Elixir flies truthy as a dart for all
00:25:42.059
those who sail the sea from java to
00:25:44.400
Ceylon
00:25:46.140
in lieu a more formal ER language
00:25:51.179
and you might consider it basic but even
00:25:53.520
through a common lisp I won't be here in
00:25:55.679
any small talk because this ship to be
00:25:58.200
Swift as an O camel traveling the mighty
00:26:00.960
go B desert
00:26:08.760
but to give
00:26:13.260
I am particularly proud of that one but
00:26:15.480
to give this here groovy assembly some
00:26:17.880
unity and closure let me be crystal
00:26:20.460
clear with the AL gold to Davey Jones's
00:26:23.279
locker and Bash a hundred foot python
00:26:25.500
before I give up me test driven
00:26:26.940
development
00:26:28.140
and now that you've seen the ample
00:26:30.240
scholar this technique
00:26:32.100
I hope your acceptance criteria ever be
00:26:34.740
clear your test Suite not Scuttle your
00:26:37.500
deployment and the cloud never take the
00:26:40.020
wind out here sails so that the Good
00:26:42.179
Ship capybara can see you home
00:26:45.900
thank you