00:00:16.400
you guys feeling good
00:00:18.640
soaking it in i know it's a lot um
00:00:22.320
as i mentioned to some of them some of
00:00:24.400
the people here
00:00:25.519
we had planned about seven modules and
00:00:28.480
we're through one so a lot of it will be
00:00:30.160
available as a markdown document
00:00:32.079
with step-by-step steps on the railsconf
00:00:34.960
tutorials
00:00:35.920
site so fear not and we're around all
00:00:38.320
week to answer
00:00:39.360
fun tdd questions we're both
00:00:42.960
relative newcomers to ruby and rails so
00:00:46.160
we empathize and have a good sense for
00:00:48.800
how
00:00:50.079
beginners get going so why don't i uh
00:00:53.360
throw a test in here
00:00:54.640
sounds good and then i'll let you make a
00:00:57.360
pass
00:00:58.239
so one of the questions we had uh just
00:01:00.399
before the
00:01:01.600
break there was how about kind of the
00:01:03.600
sad path right like how do we
00:01:05.439
how are we going to test that
00:01:08.240
validations occur and things of that
00:01:10.080
nature
00:01:11.040
so instead of doing an integration test
00:01:13.360
we're going to use a
00:01:15.040
library called shoulda matchers which is
00:01:18.080
a dsl
00:01:19.280
that can be used in our spec and dsl be
00:01:21.360
in a domain specific language
00:01:23.840
and that'll allow us to write
00:01:27.280
unit tests on these models to make sure
00:01:30.799
that
00:01:32.479
the validations and whatnot are present
00:01:37.680
so this is in the spirit of letting our
00:01:39.759
tests
00:01:42.159
assert the code we wish we had in our
00:01:43.520
code base so we won't add the
00:01:45.520
validation to the model until we have a
00:01:47.680
failing test that says that we need it
00:01:51.360
yeah and so just to describe what i've
00:01:53.759
done here
00:01:54.799
this file is spec models
00:01:57.840
task underscore spec dot rb so that's
00:02:01.680
some of the convention over
00:02:02.880
configuration so the spec for the
00:02:05.360
model should be in the models directory
00:02:07.520
and should have the same name
00:02:09.599
just with underscore spec appended to it
00:02:13.120
and what i've done here is this is
00:02:14.959
classic r spec
00:02:17.200
syntax i've described the task so we're
00:02:20.000
pointing to
00:02:21.200
this model and i'm using shoulda
00:02:23.200
matchers and saying it should validate
00:02:25.120
the presence
00:02:25.920
of the name does that look right
00:02:29.520
that looks good to me so let's get see
00:02:31.760
if this fails
00:02:32.959
so r spec what was the flag you're using
00:02:35.519
fd
00:02:37.599
uh spec models task spec rb
00:02:48.879
great so this error tells us
00:02:52.879
at the line that we added
00:02:56.400
that should a mattress runs a test where
00:02:59.120
it tries to
00:03:00.159
create this element without um
00:03:04.080
with something that's blank with a blank
00:03:05.920
element so the error says
00:03:08.319
um did not expect errors to include
00:03:10.319
can't be blank when the name is set to
00:03:12.400
nil and got the error
00:03:13.920
so this is what we wanted and what's
00:03:15.599
happening in the background here is
00:03:17.760
we're setting up the the model we're
00:03:20.959
calling
00:03:21.599
valid question mark on it and then
00:03:24.239
checking
00:03:24.879
the errors array for that model and
00:03:27.200
looking for
00:03:28.159
campy blank which is kind of the
00:03:29.360
standard output you'd see on a web form
00:03:31.840
next to that particular field
00:03:34.000
so instead of actually going into our
00:03:35.760
integration tests now
00:03:37.200
and checking the contents of the page
00:03:40.159
we're unit testing the model to make
00:03:41.760
sure that this validation is present
00:03:44.879
and that'll allow us to kind of not test
00:03:47.040
rails
00:03:48.319
yeah when we know
00:03:51.360
you know rails will issue
00:03:54.480
news bulletins when rails is not working
00:03:56.799
so we do our best not to test it
00:04:05.680
so since our test was for validation
00:04:09.680
and failed nicely in the way that we
00:04:11.760
wanted
00:04:12.799
harlow's adding a validation to the
00:04:16.400
model
00:04:18.400
to assert that the name the task name
00:04:22.000
exists and he got the test to pass so
00:04:25.040
could we just see the model again real
00:04:26.560
quick
00:04:27.040
yes so what that looks like is this so
00:04:29.840
within clatt
00:04:30.560
and this again the file here is app
00:04:33.440
models
00:04:34.280
task.rb
00:04:38.160
thanks yeah this is a great split so at
00:04:40.000
the top is the
00:04:41.440
model at the bottom is the test so
00:04:44.320
validates name
00:04:45.440
presence true and that leads for a nice
00:04:49.360
documentation later
00:04:51.360
that if someone's wondering what
00:04:53.680
validations are happening on a model
00:04:56.160
they can look at the unit tests from the
00:04:58.720
spec
00:05:00.080
and it'll show in plain english yeah
00:05:02.560
what's been set up so far
00:05:03.840
do you mind flipping that back to the
00:05:05.120
code absolutely one other point i wanted
00:05:07.440
to make here is
00:05:09.039
a question we get a lot from folks that
00:05:10.960
are new is
00:05:12.479
there are two layers of validation in
00:05:15.280
rails
00:05:16.160
there are what we have here which is
00:05:17.520
model level validations and you can add
00:05:19.680
database level validations as well
00:05:21.919
so when you run your migration you can
00:05:23.680
do something very similar
00:05:25.680
and say it needs to be present or the
00:05:28.000
database will
00:05:28.960
barf all over whatever you're trying to
00:05:30.479
do some ask
00:05:32.800
us if one is better than the other if
00:05:35.039
you prefer one or the other
00:05:37.440
and typically we'll do both so there's a
00:05:40.080
reason for that
00:05:40.880
the when you create
00:05:44.960
so the model level validations are sorry
00:05:47.840
the
00:05:48.160
database level validations are
00:05:50.080
impermeable you can't skip past them in
00:05:52.240
any way
00:05:53.120
there are ways in which you can get past
00:05:55.919
some of the model level
00:05:57.039
validations so we like to have both
00:06:00.080
and make sure that our data is clean
00:06:03.520
um so should a matchers has a bunch of
00:06:05.919
assertions that we can make
00:06:07.600
i just added another one which is
00:06:09.120
validates uniqueness of name
00:06:12.160
and then i run that assertion that fails
00:06:14.560
and then i can add that
00:06:17.680
up into my
00:06:25.120
multiple assertions so the question is
00:06:27.199
can you pass a block with multiple
00:06:28.960
validations and you can so there's two
00:06:31.759
ways to do this
00:06:33.759
let's get this passing and then i'll yep
00:06:36.000
so this passes really nicely
00:06:39.120
so what we did here was we asserted two
00:06:41.520
validations
00:06:42.639
within one line within the model on line
00:06:45.039
two
00:06:45.840
we said validates name presence true
00:06:48.479
uniqueness true
00:06:49.840
the other way that we could do this is
00:06:51.120
to split those out into two lines
00:06:53.440
um and just do that twice do you mind
00:06:56.240
just
00:06:56.560
demonstrating that real quick
00:07:00.400
so sorry what do you want to do here so
00:07:02.319
just uh
00:07:03.520
have two about one validation per line
00:07:06.000
oh okay
00:07:08.319
in the model
00:07:15.199
like two describes oh no i mean in the
00:07:17.360
model
00:07:19.280
oh i see gotcha just split that line to
00:07:23.199
the top pane
00:07:38.639
oops the users may be
00:07:42.400
familiar with the colon w's showing up
00:07:44.400
all over
00:07:51.280
yep and this passes nicely so i actually
00:07:53.360
prefer this syntax just because
00:07:56.240
it's a little easier to read but as our
00:07:58.479
participant asked us yes you can
00:08:00.560
for one element you can add all of the
00:08:02.720
assertions in one line
00:08:04.560
but to me each one is an independent
00:08:06.160
idea and i like how it maps to two
00:08:08.720
different
00:08:09.599
matches in the test file so two things
00:08:12.479
here
00:08:13.360
and two things there this was a quick
00:08:16.639
one
00:08:18.560
validations are pretty simple and we can
00:08:20.400
get more excited with them
00:08:22.720
as we go on but let's stop there and
00:08:25.919
let's have some questions
00:08:38.839
yes
00:08:52.399
every time
00:08:57.120
right so the question was um this can
00:09:00.399
begin to look like we're testing that
00:09:02.080
rails is doing
00:09:03.360
we're testing that rails is doing its
00:09:05.120
job properly
00:09:06.640
which is a great point i think the way
00:09:08.640
that i see this is that
00:09:09.920
is less that the validation is working
00:09:13.279
the way that it should that rails is
00:09:14.959
making it work and to me this asserts
00:09:17.440
that the validation exists
00:09:20.160
so this is a this is a
00:09:23.440
a constraint that i'm putting on the
00:09:24.800
model and as somebody else
00:09:27.120
starts going through and monkeying with
00:09:28.640
validations like let's say if i
00:09:30.800
add validates name
00:09:34.399
length must be minimum 20 characters
00:09:37.760
if in the process of that i'm drinking a
00:09:39.680
lot of coffee because i live in san
00:09:41.120
francisco and i've had pour overs all
00:09:42.560
day
00:09:43.839
i delete one of these and then i run my
00:09:45.839
test suite it's going to fail
00:09:49.040
so that's why we would add assertions
00:09:52.320
for these kinds of validations but it's
00:09:54.800
a great question
00:10:00.399
so the question is do we really test all
00:10:02.000
the validations all the time and the
00:10:03.360
answer is yes
00:10:04.880
and for that reason so if somebody
00:10:06.560
accidentally deletes one or changes it
00:10:08.560
then the test will fail and tell us yes
00:10:14.560
so the question was what about custom
00:10:16.320
validations so
00:10:17.760
custom validations are
00:10:20.800
a slightly more advanced topic what that
00:10:22.959
does essentially
00:10:24.160
is you can pass a method name to a
00:10:26.880
validation
00:10:27.920
so let's say rails gives us a bunch of
00:10:31.040
these canned
00:10:32.000
validations that it exists that it's
00:10:35.120
a number that it's at least this long
00:10:37.279
and so forth
00:10:38.320
if we wanted to make sure that every
00:10:41.360
task had
00:10:42.320
the word kitten in it so we could we
00:10:44.880
would write
00:10:45.839
validates and then we would pass a
00:10:48.240
method name and the method name might be
00:10:50.720
checks it is a kitten oriented task or
00:10:53.519
something
00:10:54.399
and then we would have a method that
00:10:56.800
would be called
00:10:57.760
checks kitten oriented task and that
00:10:59.920
would assert
00:11:01.920
that the task name would contain the
00:11:04.000
word kitten and would
00:11:05.279
return a true false and you would have a
00:11:08.320
test for that as well
00:11:09.519
and there's a there's a convention in
00:11:11.920
rails
00:11:12.640
so if you have validate let's say email
00:11:15.200
as a field for example
00:11:17.680
you could go email true and then
00:11:20.959
this will expect that a file lives in
00:11:24.000
app validators
00:11:27.360
email validator
00:11:30.640
and we would write unit tests unit tests
00:11:33.519
for that validator
00:11:35.680
in spec validators to make sure that we
00:11:38.560
can test the positive and negative cases
00:11:40.399
of what a
00:11:41.440
valid email looks like i wrote one of
00:11:44.480
these recently i can absolutely put an
00:11:46.240
example of that up onto the railsconf
00:11:48.480
tutorial website tonight too i think
00:11:50.000
it's super interesting testing your
00:11:51.519
custom validators
00:11:54.000
so we'll get some example code for that
00:11:55.279
up too yep and the test would live in
00:11:58.240
spec validators email validator spec
00:12:03.040
so convention yes
00:12:13.200
nothing so the question is the reason
00:12:16.560
for this is to
00:12:17.760
alert to have the test fail if some
00:12:19.440
developer accidentally removes the
00:12:21.440
validation
00:12:22.959
but what's to stop another developer
00:12:25.040
from removing both
00:12:26.560
the validation and the test for it and
00:12:28.800
the answer is
00:12:29.839
nothing well the answer is not really
00:12:32.480
nothing
00:12:32.959
the things that prevent you from being
00:12:34.480
able to do that are
00:12:36.000
the fact that you're programming as a
00:12:37.839
pair the fact that you have
00:12:39.920
uh that you give your own code a good
00:12:41.920
once over beforehand
00:12:44.240
and that you do code review as a team
00:12:48.560
of course if anybody wants to make any
00:12:50.000
change you can jam it into master and
00:12:52.320
there's nothing to prevent it but we try
00:12:55.040
and create
00:12:56.399
checks sort of qc level checks along the
00:12:59.200
way before things get merged into master
00:13:01.920
including really rigorous code review
00:13:03.440
and that's i think where we would try
00:13:04.560
and catch that but of course things do
00:13:07.120
sneak past good question
00:13:13.200
other questions
00:13:18.480
so we have five minutes left uh i think
00:13:20.720
that might not be enough time to get
00:13:22.079
going on the next
00:13:23.600
module okay what do you think um i think
00:13:26.959
that's right so why don't we uh when we
00:13:28.240
break a few minutes early
00:13:29.600
um we'll be walking around if we want to
00:13:31.760
answer any more questions
00:13:33.200
anymore
00:13:38.240
i know so we have an announcement one
00:13:41.279
second
00:13:42.560
coupon codes for 20 of everything on
00:13:46.639
learn
00:13:49.600
great so chad informs me that we have a
00:13:52.639
coupon code that
00:13:53.920
we use on our learn portal
00:14:02.320
code um and that's good for 20 off
00:14:05.600
everything in the learn portal including
00:14:09.199
our subscription servers our
00:14:11.839
subscription service learn prime
00:14:13.440
uh it's uh one month for free
00:14:17.920
20 off the first month sorry and with uh
00:14:20.639
with learn prime we have a series of uh
00:14:23.120
ruby on rails workshops that are
00:14:24.959
recorded
00:14:26.160
we've written uh ebooks on backbone.js
00:14:29.920
we have an ebook called ruby science
00:14:31.440
which is under development right now
00:14:33.680
and that really digs into some of these
00:14:35.199
patterns we're talking about in a rails
00:14:36.800
application
00:14:39.120
so we have a great culture around kind
00:14:41.120
of continued
00:14:42.240
growth and development of thoughtbot and
00:14:43.839
this is something that that all of us
00:14:45.600
are putting time into
00:14:47.440
um our regulators harlow's working on
00:14:50.560
ruby science and i'm working on our
00:14:52.240
new version of our playbook online
00:15:06.079
over the course of four weeks so we'll
00:15:09.120
break now
00:15:10.160
and i just wanted to say thanks for
00:15:11.680
everybody coming in here i think it's
00:15:13.600
doing tdd is really difficult and it
00:15:15.360
takes a lot of hard work
00:15:16.959
and pairing and i'm glad to see
00:15:18.480
everybody got together and helped each
00:15:20.399
other out
00:15:20.959
so that was awesome made my day and
00:15:23.839
thanks again for everybody
00:15:25.120
for coming out we're around all week if
00:15:27.279
you have questions pull any of us aside
00:15:29.040
with robots on our shirts
00:15:31.680
and we'll happy to answer questions and
00:15:34.079
thanks for coming
00:16:10.000
you