📺 Develpreneur YouTube Episode

Video + transcript

Python Unit Testing With Flask

2021-05-20 •Youtube

Detailed Notes

Our series on Python and Django moves into a focus on testing.  Fortunately, unit testing is very easy to incorporate into your solution.  We can provide some basic unit tests within minutes and improve the overall quality of our applications

A Built-In Solution

Quality assurance is an important facet of software development and unit testing in Python is an example of how pervasive it has become.  The designers of the language have given us tools to follow these practices.  This tutorial walks through the basic setup and configuration of our application whether it is Python or Django.  We then create a few unit tests that can be a basis for your own needs.

Transcript Text
[Music]
okay so diving in
um we we have talked in some prior
mentor sessions about we did some django
we did some python
and there's there are definitely some
uh very powerful tools that django
provides to us to do
uh really it's to do software right you
know in quotes it's to it's to
follow the things that we know need to
be done to create
good software and one of those things is
you know for better for worse you got to
test it you know i don't i don't know
anybody that writes code perfect the
first time or
even probably the hundredth or
thousandth time there's always things
that show up
and one of the best ways to start with a
foundation good firm foundation
is to unit test the code that you put
together
and it's also a way to it also i found
is a great way to provide sort of a
regression test
in a way when you're building
particularly when you're building a lot
of software that's either
that's a lot of working parts a lot of
blocks like maybe an api
microservices things like that we've got
all these little working pieces
and you may do a bunch of coding in a
short period of time and if there's any
relation between those various items
those blocks
then you do have the situation where
making a code change can
change you can have a downstream effect
so actually
i've found a lot of times where really
good unit testing is almost a formal
regression test it's not
quite to that level but it does allow us
to
at least get some sort of warm and fuzzy
feeling that we made these changes and
things
uh things work we didn't make any
assumptions that that were false that
would cause bugs
so that's unit testing in general just
trying to sell it a little bit i guess
and we're going to we're going to focus
this this will really be much of a
a lot of a working session kind of thing
to show some of the power of
of django and now it's got some of its
its built-in
unit test framework so we're going to
look at that
and then we're going to look at the talk
about how there's some setup and cleanup
stuff that's
available with this that it is a
framework it's not just
you know writing some code it actually
provides us a nice framework
to work with them and one of the things
that does
is it leverages the django models so
your your database
and the tables and structures there
that are so really essential to our
application really
allows us to uh to take advantage of
that
and then there's also because django is
a it's really it's a web application
there is a browser client that's a sort
of built-in browser client it provides
we're going to look at that
and then um may talk a little bit about
multiple scripts and inheritance and
how we can move some stuff around
so the built-in unit test framework for
django
um it's included with django
uh the the things we're going to talk
about today is a
there's the client and the test case
classes
and then with those we're able to in our
as we see
saw in our django applications we can
import our models
we can import forms we can import views
uh it's gonna allow us to do some setup
so that for each test we can do some
setup as needed whether it's
you know maybe there's some data we need
to create or a specific
uh environmental situation we want to
create we can we can do a setup within
that
there's also we're going to talk about
the web simulation side that it provides
so it gives us a way to without
having to spin up a you know actual even
development web server
the test system will does it all
internally so we don't have to worry
about that piece we don't have to have
it running anywhere
they won't have to worry about it
conflicting with an existing web server
running somewhere and uh it also
provides us a test
database so we don't have to worry about
you know messing up our even our
development or
our test databases we have the ability
to create
essentially a pristine environment and
then one that is very
tightly defined by what we do within our
tests
and so within that we can actually do
some very we can get very complicated in
the unit tests
with regards to data it's not just
functionality now we can actually go in
and have a provide a lot of uh data
related
pieces so that we can actually validate
it on that sense
uh actually hitting the database as
opposed to having to somehow
mock it up i mean it is a a full-blown
test database
and it's a really simple script which
we're going to see it's very easy to get
started there's there's not a whole lot
of work you have to do there's almost
nothing you have to do to get started
and based on that let's you know dive
right in and take a look at this thing
whoop
so um this is a full script so i'm going
to focus on some pieces of it
and actually let me do it this way i'm
going to
uh i'm going to switch this real quick
and then
oh it's not in that foamer it's uh
cpu mentor
so now i'm going to do
oh that's right so let's do this let's
go back to that script
and i'm going to close a bunch of this
stuff out
oops it's a page down that's not a
delete let's get rid of that
so uh we have back from our
uh application that we worked in uh let
me go ahead and open
that models
so we can go just to refresh our our
memory a little bit
um back in the back when we talked about
models as
a couple of classes or sessions back we
created
this very simple database to track
uh this actually was to track rss feeds
and
and articles that have come in with it
and so we didn't have a whole lot we
just had uh we have feeds
and then with feeds we have articles
which is a feed item
we have targets that are
i remember if we implemented that at all
we did not which is going to be targets
for where we post
articles we have types
which had to do with which is also
something we had not been that was just
to throw something in there as a test
sort of a test
model and then we have a status so this
would be a status whether it was red or
or
not red and actually a status can be
whatever but in that case
it was whether you basically is this new
have we read it
have we posted it what's the status of
this
article essentially
and so you know we have this very simple
set of models and we can import
so for this for today uh we're going to
import
just i'm going to stop popping up we're
gonna do the feed item
the feed and look up target we're gonna
be playing around with those
in order to set up a unit test and
actually let me do this
[Music]
do this um simply to get started
in order to get started with a test you
import in this case you really just need
test case
uh client is what we're going to be
using when we do the web version of it
so i'll go ahead and import that right
now we pull in models in case we need
those
which we will we're not right away but
we'll use the
django's model so we can actually do
some some work with models and
add values saved to the database things
of that nature
and i'm pulling in our app related
models
now in order to get started all you need
to do
is create a class and you can call it
whatever you want
and inherit from test case
and this is going to be this is what the
django system is going to look for it's
going to look for that test case
and because of that because it's based
off of that there's certain methods that
are available
that either it's going to you know use
the default one which is the base test
case or
you can override them and then
the most simplest one you can do is you
just create tests and they have to start
with
the name test it knows that that's what
i'm going to that's what i'm looking for
that's what i'm executing within my test
case
class so if i do test one it's going to
execute test one if i the next one i can
call it test two
as long as it starts with the word test
then
it's going to go through and execute it
now for the simplest one this is a
regular class so we're going to create a
property test name
and let's uh
we'll come back to that a little bit and
clean that one up and so
what we can do is keep that
is it uses assertions like just about
every other unit test tool i don't know
any unit test
tool actually that doesn't um it has a
and it has a couple different assertions
that it works with but for now
we're just gonna we're gonna stick to
the simple ones of asserting something
is equal
and basically if we if the assertion is
true
then it passes if it doesn't then it's
false
and then it's and then it's going to
fail so
let's say right now we're just going to
come in we're going to set this test
name and then we just want to do a cert
equal
just to make sure that our and actually
let's change this to
we're going to change this to not
defined
and then we want self.testing we're just
going to assert that when we come in
here
that this should be equal to not defined
so that would mean that in this case
this test will pass if when i get to
test one
test name is equal to not defined so
let's flip over and actually run that
and it's actually very simple to do
we use the uh the manage which we've
used before
before we use manage.py to actually
start our server
so if we do a um
[Music]
if we do a run server i don't even know
if this will run
uh okay good then it will we could run
our server and i could go
to this address
you remember and let me just pick this
up
and i can see some oh but i don't have
anything allowed here right now oh i've
probably
yeah i didn't have this set up so i
could go in and run this
but i have it in sort of a broken state
right now
so that manage oops
provides us a lot of different tools and
we can see here
you can see where i got a bad request so
we ran that in the past so we're not
going to worry about that too much
another thing we can do is we can
actually run tests
and it's as difficult as saying manage
and then test so we run this
this is you know let's flip back to our
script so our script right now is just
this one test
and we're just doing a very simple
assertion but notice here
hopefully this is big enough to blow
this up a little bit more
if you notice when i run the test the
first thing it does is it says create
test database for alias default
what that does is that's actually going
back to that models
it's going back into my models and it's
creating a test database with these
models and these attributes
so i've got a full database that it's
creating for
my unit tests and then it's going to do
sort of a it does a
sort of sanity check to make sure things
going and then it starts running tests
and i believe that it's going to give it
gives you a little period i think for
each test rant
um the the interface there's a couple of
different ways there's like a verbose
and some other ways that you can do
stuff
so let me just verify that real quick so
if i create a second test
and i'm going to fail at this time
so in this case we see that it ended
with an okay is that it ran through it
ran one test
it got okay it passed and then it got
rid of that test database so i don't
have to worry about it
sitting around now with my two tests
again it recreates my uh let's see it
comes up here
creates my database oops wait here i'm
sorry here's where it's at so it creates
my database
uh it comes in and we get a dot for a
pass and then we get an f for a fail
so now it actually gives me some pretty
good information here
it says that test two is the one that
failed
and the assertion area of not defined
equals not defined period
it failed that and i can see where on
here i was looking for not defined but
not defined
period is what i found and so i thought
that i was i wanted both values to be
equal
but it's not because the second one's
here so it actually shows me it gives me
a pretty good way to
see what the issue is at least what i
was checking
and i can go in and fix that so i could
i can come back in here
and actually well let's actually leave
it that way so now i can come in
and i'm going to do self.test name
equals to
undefined so if i change it here
that's one way to fix it and i'm going
to run it
and so now it's okay again i ran my two
tests i see my two periods so i've got
two
successes there and
again you can see where it builds the
database
runs through everything and then gets
rid of the test database that's the same
thing that it did here is this going to
run through everything
it's going to bail out and or it's going
to get to the end and then it's going to
clean everything up
and so that provides us a nice little
environment to continue to get started
so let's get a little more complicated
here
um let me open the prior so i can sort
of
work our way into this uh where did i
put that
let's see there we go i'm sorry let me
move
test prior mentor
just steal some code so i'm not having
to
type quite as much
so let's pull this one over
so we've got those two tests let's
create a third test this one we're going
to actually
work with our model a little bit so we
pulled in
our feed and now what i'm going to do in
this third test is i'm going to and
let me go back and look at
i look at models feed has a little
function built into it that returns the
name
for a given feed so all i need to do in
that case to test it is set the name
so i'm going to go in in this case i'm
just going to now i'm working with the
model itself i'm not actually even in
the database yet so i'm going to create
a feed
i'm going to set the name equals my test
and then
i'm going to verify that when i get the
string version i call this whole
function
this better be what i get back because i
just sent it now i just set that
and so if i jump over and do it
and i actually run the tests
and actually let me do this let me clear
this up a little bit
then we're gonna see here that it runs
through runs my three tests i get okay
so it is setting that now this is a
model so what i can do
is i can do um
i remember what all i needed for that so
let me go look at my feed real quick
so if i look over here oh do i have that
in test prior did i set up a feed oh
here we go
i'm going to take this
and so now i can come in i'm going to
create a
feed object well this is i mean
a couple ways we can do this i haven't
actually looked at this in the past
this because feed is a model one of the
things that allows us to do
is we can do a create and we can set
values right away
or we can um
let me do the same thing with the feed
object i did
i can also do feed.name
and we're going to call it test feed 2.
whoops mistake because i'm setting the
name and then i'm going to do feed
description
it's going to be a test
record and then i need the image link
and this is going to be http
my link
and did i need something else oh i need
an actual link i'm just gonna do another
one of those
so we're starting to dig into even
though we're within a test
here we're digging into
having we have the full strength of
the models available so we can either do
it
by creating an object a model object and
using the save or we can actually get
into the feed
objects some of the stuff that models
give us which
we've got up here and we can do things
like we can create or we can even get so
we can do
a feed dot
objects dot all
and then i can actually see so now i
should have
based on what i have done
i should have actually two objects that
i've created in my database
and so i've got this test feed one that
i created this
directly through this create and i've
got test feed two that i did by saving
feed one so i should be able to take the
length of results
it's going to tell me how many records
do i have i better have
two records and actually just to sort of
show what we've got
i should start with zero records so
test three is now becoming all more
complicated but let's go
run through that and what we're gonna
see is
that everything ran through so i have
no objects i
add a few objects and then
i've got those objects in my test
database
if i run it again
it's still successful because even
though i i inserted those objects
that got closed uh here where it does
destroy the test damage it got rid of
all that stuff so
i can rerun this a thousand times i can
add records in i can do what i need to
for that
um and i think i want to do
yeah okay that'll do for now so i'm
going to flip back over before we go in
a couple more things presentation side
so we looked at here we're really we're
looking at just the most basic
tests and starting into the models
so now i want to talk a little bit more
about those models
as we've seen we have the full django
environment actually
in this unit test script already so the
models as we see we just import them and
we're off and running we can import the
views we can import forms
if we've got other classes that we've
built that we're using for
maybe like utility functions and things
like that we can pull those things over
and the models and forms give us
all sorts of power in doing a full-blown
test we can
build out an entire if we want to an
entire database
do a lot of work within it and then it's
all clean and it's cleaned up when we're
done
so we have a very easy creation of
records and database interactions as
we've already seen
we can add records we can uh pull
records back out
and we're gonna in the next working
session we're gonna go a little deeper
into that
and the big change for all of this
that i wanna look at is the setup is
that we can
come in and copy this guy in
is and this goes back because this is a
test case one of the things it looks for
is something called
setup
and what setup does is that is going to
be run
before every single test
so where in test three i had a whole lot
of code i had a bunch of stuff that i
was setting up
what i could do instead
is i could take that information
essentially and do it in the setup which
is what i've done here so i can come in
and instead of creating these two
records here
i can just say you know what i want
those two records to exist everywhere
for every single test so here
where you see where this it start out
with an empty record
if i set this up in the setup
actually let's do it this way and so
we're going to see
that for each of these tests the first
thing it's going to do
is i'm going to it's going to actually
import these two records
and so we're going to see here it's
going to fail because it's not an empty
database anymore
and so we come through
and we see that somewhere up here it
failed and it's failed
and so it failed on test one
oh because it's uh this is interesting
is it comes back here
and in the setup i changed the object
level variable
whoops to round one
well now it's failing here because it's
not that not defined anymore it's been
redefined
by the setup
and so now this is like this will be a
fun one to do because now what i do if i
call if i look for it to be equal to
round one it will pass
but let's go set
if i come here and i set the test name
equals to define and guess what i'm
gonna find is that when i come back in
even though i did i set it here it's
gonna get reset
in the setup before i come into step two
so test two so i'm gonna find that it's
actually been reset
to round one
and so now i can see it passed the first
two and we come to the
third one and this is where we it says
hey i've already got records in my
database
so you can say well that's pretty cool i
can i can slide some values
and you know be off and running well the
thing here is
it's also doing it to the database so i
come in and this is a pristine database
so i create these two objects and note
that it's not adding each time so i'm
getting two records
at the start of each test and
if i come in let's see
let's just sort of clean this test up
real quick let's say that i come
in and in test two
i'm gonna add two more records a test
three
and a test four
and i'm just adding two more records but
i'm gonna come into test three and find
out those two records
have now disappeared and i'm back to
what i do within my setup
and so we can see here that bam and
walked through each of our three tests
successfully
ran all three of them and we get an okay
so this is not again
this stuff should not be
new and you know jaw dropping
kinds of features because this is stuff
you will normally see in
a good unit test system you know if
you're using like a j
unit or n unit or stuff like that is
that you have the idea of setups and
breakdowns and cleanups and things like
that but this is
all from basically just
right out of the box you don't have to
you don't have to go pull another
library in you don't have to do anything
special
is that you because you are running
this uh wherever that is at
because you're running this with the
django
infrastructure it pulls all that stuff
in
and makes it very quickly available to
you so you can actually start doing some
pretty
you know complicated things you could
try to uh you can test things like
your referential integrity within your
database is i could i could create some
objects
and i can create some that are you know
that have some foreign
key relationships and make sure that
those uh those exist
it's going to be consistent so i can
if i need to i can actually base these
on
primary key ids yeah it's normally not
recommended with your testing but i
could because i would know that this is
a pristine database so i can know
that the id for these is always going to
be the same so if i come in
and do a get
uh let's do let's do it here so if i
come in
and i do from feed objects
get and i'm gonna do where name is equal
to
uh test feed one
and then i just print
uh oops that's gonna be my object
and object.id i'm gonna see where that
this is always gonna be
the same id so if i can run this let's
do it like this
clear the screen real quick if i run it
so here my id is seven if i run it again
my id is seven i run it again
my id is seven so i'm getting this every
time and doing that little things
printing out it's
it is very consistent now why that thing
is an idea seven is actually pretty
interesting in itself
um not sure why it generated
that number uh let's see what is test v2
that must be seven and eight
yep so it's always eight there
but what i do know is that i now have a
i have a consistency within
my objects oh and actually right here oh
this is going to be a neat one because i
bet if i print my object id here
permanently while i'm playing around a
little bit because this is but i think
this is sort of useful is what i think
what we're going to see is because it is
i bet it didn't blow away the whole
database
um i don't need these cert equals
i don't need the assert equals
so probably what we're going to see is
we're going to actually see this crawl
up because it's going to
delete the records and not drop the
database let's see what that does there
just because
yep so we can see here it's not actually
so it is it's cleaning out the data it's
because this is an auto-generated uh
primary key
then we will see that it's uh it's
actually not just
like recreating the database from
scratch
it is uh cleaning up the objects and
recreating them the next time around so
and so it's kind of saying which again
goes back to id
the idea that you don't want to actually
look for ids you don't want to
look for those because those technically
should have nothing to do with your
records you should instead be
doing things like here you know
searching by name or description
something along those lines
so that's the
the back end the middle tier side of it
now
django we have a you know this is a a
web application
so we also want to have the ability to
test that out
is to be able to look at our our urls
our views and see how those things work
now we can we could within our
oh good okay it's right here so if i
wanted to look at my views
i could go in and try to mock these
things up i mean these are all built
within my views
these are functions that require a
request
now what i could do is uh basically find
a way to abstract each of these out to
just a straight
function one that's you know behind a
middle tier function
and then the request would just pass
things into it that seems like a lot of
extra work
when one of the things i want to do is
is really validate
my my urls which are over here i want to
be able to validate that these things
are doing something
you know functional and so we
we talked about client is something
we're going to take a look at next
that's that other piece we had test case
and then we have client and so what
client gives
us this is for our test purposes it
gives us sort of a
it gives us a test server this up that's
not
going to interfere with other existing
servers we have
and while we can extract stuff into
others functions and methods this gives
us the
the ability to test that web side of it
so even if we abstract them we still
want to make sure that our urls
go and do as we design them
and so you have to have some way to test
it from a
browser point of view and since it's a
unit test you don't really
care to you don't have to actually see
it it's not like
selenium or something where you need to
actually go in
and record stuff uh for this point part
where really we're gonna do things like
say hey i want to just be able to see
what you know can i get what i need from
these
uh these paths and so in that case
uh where's my test so in this case we're
gonna actually start creating some stuff
related to client
so let's go pull
and go pull a bunch of these real quick
well two of these
and
let's see did i get it oh there we go so
it's gonna be test four and five
and with a client all you have to do
is you're going to create we need to
actually create an instance of it so i'm
just going to do client actually i'm
going to call it c
because i did call it c yeah
and so i'm going to just create that as
at the the class level i could
recreate it at each time but i'm just
going to create at the class level and
let it sit there
and so now all i need to do
is i'm going to refer to that
i'm going to look at my property called
c and all i need to do as a post
is and that's that's it i'm going to
post and i can do a post i can do a get
i can do a put but i can post to
and all i have to do is just give it the
url so if i want to test my urls
i could actually walk through this i
could take this list
just to make you know sort of do a
sanity check on my urls is i could
actually
do for each of these so here
now i am going to put in some potential
uh some cases i'm going to do like a
post or something like that
but i can do here i've got a list
i'm looking at feeds if i want to do
an article and go to try to grab one
it'll probably give me an
issue because i don't have any articles
in this test database but
whoops let's go ahead and throw that in
there just to throw one more
so article and i can just give it an id
oops
that one yeah article id
and that'll be test six so as far as
as testing from a um
a web point of view it's actually again
very simple as i just
come in and say here's where i'm going
and so what i'm going to do here is i'm
not going to actually do my assertions
yet i'm going to actually print out the
response in each of these
so we can see those and actually um
let me put a little more around that
so this is test four
and
i think this will give me something
that's a little bit more
[Music]
reader friendly
so let's go take a look at what that
does
uh let's clear this out
and so we're going to run through uh
let's see it's complaining oops
i'm sorry i did that the wrong way
i did it in java style
okay whoops that needs to be an equals
so i'm going to come in and i'm going to
assign it to client so now if i come
over here
um let me clear this out real quick
i'm going to get a different error
apparently
so it's going to print out that it's the
same thing i had before now it comes in
here
and i'm getting a status code
here i can do test four which
is uh let me get rid of some of these
other prints
just to clean that up a little next time
we go through it
so test four i went to
slash list and
um actually for this purpose let's go
back to
let me go to my settings i think this
needs to be
set up here
let's see if i can get my server running
real quick
so if i do a run server and do this
whoops okay
so
over here i was going to
um let's go back to my test so if i go
to list
let's flip back over if i actually go to
list what should i be seeing
so here it's actually it's going to try
to log in because list forces
that authentication now if i'm logged
in
oh i don't remember what the password
was for this i want to say it was like
maybe now i'll have to go check what
that was i may not have that database
set up
but normally what's going to happen now
is because it's it's ringing here it's
actually redirecting me and so we're
going to see that
here um
[Music]
let me get rid of this back to that
and we're going to see that is that when
it comes darn it
wrong test wrong app
from the test and so when it comes
through it
actually gets the response where it's
doing the redirect to accounts login
and it's going to pass here did i do it
i guess i did have a
issue at the end of six so we'll take a
look at that
uh but here we're gonna see because this
was protected it's gonna go over
and try to force a log in here for the
next one i did where i did just the
feeds
apparently that is not because it comes
back
and it just gives me a straight response
of 200 and there's no other
records in it so i don't have to i'm not
going to see
anything um although i should
oh because that's actually the response
there's not any kind of result or
anything like that that i'm working with
and then if i come into this one where i
post it against article
um oh it's actually giving me so when i
try to call
this i'm going to see that in
the view somewhere probably where does
it show it's not showing me oh
no that's the test
and it should tell me where it was in
the view but i'm not seeing that one but
i the issue here
is that query does not exist and so
i don't have an article one so i'm
actually this is actually showing up in
my code i'm seeing where my code does
not handle
the case where i don't have this article
so i would have to do
is probably create
oh this is based off of an id so what i
really would want to do
because article is a feed i'd have to
actually come in and do the
uh i want to get
to do this correctly i'm going to get
that test feed 1
that i've built out and then i'm going
to want to add
the object id so now if i were to view
it
then it comes in
oh it's i'm sorry it's looking for
uh that treats that as an integer and
not a string so let's clean that up real
quick
and
uh it doesn't like that anyway so i'd
have to there's probably something
broken in the code itself but what i'm
seeing
is that that is actually broken uh even
though there's not an assertion
i'm getting i'm getting an actual
exception so i'm not even
you know my code's not even running so
this is something where i would have to
actually
fix this um
so somewhere here where it says
oh my mistake is that right
oh it is but for so it's not picking
that item that id
up so that may not be the feed itself so
i'm
i'm here and i'm getting exactly what i
should
out of my unit test as i'm seeing that
i'm getting some successes in here
but i'm also getting failures and i get
to see exactly
from a development point of view or even
a qa point of view
i can see exactly that it's this is a
test that it's blowing up on
and i get to see you know the trace
uh the stack trace of that issue so i
could actually if i'm
if i'm a qa person i could send this off
to the developer and say hey when i run
this
you know when i run this thing
this is you know or here this is what i
get over here so you need to fix it or
as a developer as you're running through
your unit test which is
really at the point you should be seeing
this
is i'm going to see that this thing is
blowing up i'm not getting the
the pieces back the way i want it to
something's not
working right here so something about
this article which i could go look if i
want to look at that
real quick if i look at the views well
let's see i got to see what is article
called so article
calls display article if i go here
and go up there was display article if i
take a look
at well let's do this
if i do display article oh it's a feed
item
that it's looking for not a feed and i
was sending a feed in so i'd have to
actually create a feed item
in order to do that
and a feed item is probably yeah so
there's a there's a fair amount of stuff
i'd have to do to create my feed item so
i'm not going to
go into that uh mostly because
this is really the the meat of one that
i wanted to cover
in looking at the the testing here is
that we've got
uh looking at our test actually i can
look at well i'll go with this one
is that we've got within the matter of a
couple of things that we import
and we don't have to we didn't have to
do any additional uh
library downloads or anything like that
it's this is all within
the django environment that we can
create a test case
and then it does allow for setup we can
do so we can
set stuff up for each of our tests and
then we're going to name them just
as long as the name starts with test
then it's ready to go so if i wanted to
shut one of these down so like right now
well really test 4 5 and 6 don't do
anything
so i could just come in and i could just
call these
x
and i'm going to get a success because
it's only running three tests
because the name does not start with
test anymore then i've i've basically
blocked those out and there are
situations where i've done that where
i've made some changes and i've got
maybe a huge script
and i want to see what's working then i
don't i may just say that this is yeah i
could do like
i could name it fail as i know this
failed so i'm going to have to come
through
i can say those failed whoops
and i can see here where okay i've got
success well i could come in and say
well i want to try to fix this one
so i can fix this one
and let me get rid of those prints i can
fix this one
um then run it not worry about those
failures
and say okay did i fix it yes i ran four
tests
okay so i fixed it so now i can move on
to my next one so there's some easy ways
that we can
you know work within the system they
have it's not the most you know
complicated thing but
i think from a unit test point of view
that may be what we're looking for
something nice and simple it's easy to
add our tests
it's easy to do some validations
and move forward knowing that we have
some level of comfort
in our code working correctly
so what have we learned uh hopefully
we've learned that unit testing in
django is built in and very simple
and honestly as sort of a side note unit
testing in most
modern environments is actually pretty
easy and should be
it is it should not be an obstacle to
most development
teams groups methodologies whatever
you're doing unit testing has gotten so
it's a
it's it's an accepted and expected
part of so much development that i
even in your your personal side projects
i think it's very useful to make sure
that that's just one of the habits you
have is building out unit tests
it's a great way to see how your
application works or doesn't work
and to really validate uh in a lot of
cases you can i think you can almost
code faster because you can just you can
crank through some codes you can do some
quick validations through unit tests
make sure it works right and if you're
you're right you move on if not then you
fix it
and then then you move on but with this
in the in the django world we're able to
leverage all of the other pieces that we
looked at you know through the client or
even through or through the
unit test class we can we can look at
urls we can look at views we can
go if we're building out forms we're
building out models if we're building
out utility functions all of that stuff
we can just pile it into our unit tests
and
uh that that client is actually very
powerful so we've got a client provided
so we can test our browser interaction
very quickly we can look at responses
and i could build assertions based on
those you know through the
um again looking at like the uh
where a response is is i could actually
go through and
do some work with this is i could i
could start parsing and try to see what
my you know what my status code is make
sure it's correct
in this case for example i would expect
in everything that is protected that
this is essentially what i should get i
should see
the redirect should come there so i
could easily build out unit tests to
validate what's
what requires authentication and what
does not
so at this point like no questions
comments
it's a comment that may lead to a
question
oh go ahead michael unless that was an
echo no go ahead
okay um yeah uh i just find it so easy i
as you've mentioned it just it's so cool
how easy it is
to um set up these tests uh
you almost would find yourself uh
wanting to set up your testing framework
um
[Music]
and in django and then just you know
having it
uh you know your code written in a
different language that's just how easy
it looks to
to do and i think we mentioned that even
for for instance like a
your your crud operations for your uh
your
app setting that up in django and then
the
application written in a different
language i wanted to ask though was
there a
uh particular and probably too nuanced
uh but is there a particular
testing design pattern you found useful
or might be useful
uh with this uh language django python
that probably wouldn't be as easily
implemented
in any other language
um
[Applause]
i'll answer that i guess with the com
with a very big caveat is it
uh no there isn't but there's also i
haven't spent a lot of time
digging into testing patterns i sort of
particularly from a unit test point of
view i i sort of have
i've developed my own
methodology or process of of how i i
build out unit tests related to
code i'm working on um and it works very
well for that it's it's rather
it's it's actually rather i guess in
ways simplistic it's it's basically
the idea of of testing uh within bounds
edge conditions and then out of bounds
and and then you know like nulls and
things like that
um back to your your other point too
though
is yeah it's i could easily
see situations where i would build out
especially the data side the database
side of stuff where i could build that
out
using django and really use django
almost as like a data
almost like a data management testing
tool so that i could just
i could focus on back end stuff with
that and whatever the front end doesn't
matter it could be a java app it could
be a
you know angular app it could be
whatever
but i would be able to use this to
actually test
things like you know adding records and
referential integrity and foreign key
relationships
and all of those kinds of data related
testing items uh very quickly i mean
it's you say there's there's not a whole
lot you have any and really the
python itself that's i think one of its
strengths
is it's such a simple language there's
not a whole lot you have to do you don't
have to
you know build you know it's not like c
plus plus where you have like your
header file and your you know your
source file and all this kind of other
stuff you have to worry about
compilation
it's really quick so you know even here
i was cranking through tests and and
looking at results and making changes
in a matter of seconds really and so to
me it is it is very valuable for that
is to use it as a way to you know really
sort of
i guess a data centric way to do some
testing of your of your back end and
potentially even your middle tier
because you could turn around and point
that to urls they don't have to be
django urls per se and just
validate the responses are coming back
another other tools that do that kind of
stuff you know you may
like if you're going to test an api or
something you may want to use like a i
don't know postman or something like
that there's
there's other tools out there but if you
want sort of a
sort of like a one size fits all
solution that i think it does fit that
absolutely yeah
uh michael you had a question or comment
yeah i had a question so
uh you have the setup method is it
similar to like the other unit test
where you can have a tear down
and also have one that runs in front of
each individual uh like
you could have a set up and tear down
for each of those tests within your test
or is it basically just whatever's in
that
test file is what's going to get uh
handled by the setup and teardown
it does have a teardown i didn't get
into that as mostly
it was mostly just time constraints and
stuff um
i'd i've got to go back i would have to
go back and verify it the way i've done
it in the past
is actually have multiple test scripts
and so i end up importing a script
you know within that so i would have um
[Music]
you know for example i don't know like a
certain like if i have just like a
normal customer relation
type app i would maybe have uh customer
related tests and then would have maybe
organization related tests uh security
related tests
and do separate uh setup and tear downs
for those
uh i use it and that's that's also that
sort of goes back to my style a little
bit i usually do not do stuff where i'm
gonna do a
setup and tear down at a test level but
i will do it for
a group of tests and the way that you do
that in python is you would have a class
that has that so if i flip back over to
the code
so i would maybe have this would be um
like here this would be maybe feed tests
and then i could create i would maybe
have a separate one
uh which i could actually do in this
this file or in another one and i could
maybe have like feed
item tests which would actually make
sure you know
in this case would be a good example
where i want to do that is so i would
come in with feed tests and i would have
stuff based on these feed
objects and have tests related to that
separately i would have this feed item
and i'd probably maybe i create one feed
because feed items have a foreign key
relationship but then i would have a
bunch of feed items that i would create
so i'm able to rebuild
um my database you know as as needed
and also keep it um
sort of focus on the data that i need
and i could do and i can do inherited
tests as well so i could have i can
actually
you can get sort of complicated so i
could have
like an all tests
um yeah that's what happens because
yeah go ahead because there's cases
where
you want to basically do a setup
and then run multiple test uh files
um because you you're using test files
to get very big if you try to put
all your test cases in one file so
sometimes it makes sense to
split them out into multiple files but
apply one
uh setup and tear down and then
essentially kick
all those other files with that
essentially the test utility the
the master test so that's where i was
asking about that so
it looks like it has it like you said
you just didn't have time to cover it
yeah it's got there's it has some other
functionality i kept it sort of simple
and there's ways and there are ways that
you can change around sort of how it
looks for a tests and
and things like that um but it's
yeah it does allow for that idea of
you could have you know sort of like a
foundation of
data and then within specific areas
where you would want to have
you know maybe add on top of that data
but you don't really need that for the
other
pieces um so it does have that it's just
we didn't you know we just really didn't
get into it
and i haven't pushed it i haven't built
very
big huge applications that way
the largest one that i built using uh
unit tests within python i actually we
it was actually sort of interesting
because the guy that i inherited from
actually built his own um infrastructure
that was essentially it's
actually it's sort of funny because he
it was very cool it's very complicated
he'd
tear down and rebuild the database and
everything but django
all the stuff django provides would have
eliminated
you know hundreds or thousands of lines
of code that he had to go through
um and it allows you to do it but the
way
the way i i focused it was that it was
um it was a series of files and they
were very
functional so for any given set of
functions
i would basically build up an entire
database that i wanted for that
and then add on top of it and do my
tests and then i ended up doing sort of
basically it was a copy paste method
instead of doing inheritance i would
just copy and paste the script to the
other one
so i don't know how uh
how well it handles deep relationships
and inheritance
i do know it's there but that would be
something that would be sort of a you
know
unit test two or advanced unit testing
or something like that
true one approach even though you're
copying your scripts over which is fine
and that's actually a pretty standard
way of doing testing with databases and
stuff like that
but what you really want to do if you're
doing something like this
is you want to essentially test all your
inserts deletes and all that correctly
so you build all that
first and make sure that that gets run
at the start of your test
so you're testing all your uh you know
all the correct inputs and outputs of
the database and then run all your tests
against the data after you actually do
all the transactions at the beginning
yeah yeah usually that's what you would
that's where what you'd normally want to
do is that's why you'd want to have
essentially some sort of a setup
is that you have a you know or a a
prerequisite test or something like that
so you go run
all your inserts and updates and deletes
and
all the crud related functions build all
your tests related to that
and then i you know ideally that you
would build on top of that so you would
go run
you would lay out your foundational data
you would test all that make sure it's
good
and then you would run your tests on top
of that so that if the
um the foundational tests fail
then you know theoretically you wouldn't
even you know just go address those
first
and you wouldn't even worry about the
other pieces because they
probably are poisoned by those you know
those bugs
upstream um and that was roughly how it
worked it was just uh
again it was because this was built off
of somebody else's stuff and
and just shortcuts as opposed to doing
it the right way so exactly the way i
said you should do it i did it
differently
just out of the shortcut method
and it did end up running you know what
you'd end up doing is you'd have
because of the way it worked um the
foundational stuff got run along with
your unit test so you had
with each of those tests probably
i don't know dozens you know maybe 100
tests that were run
over and over and over and over again it
really didn't need to be you know it
could have just been run once
and and move on which is where you would
want to do it in this case where you'd
want to have some sort of a
if you do an inheritance or some
inclusions or things like that
then you have some opportunities so that
you can you can go build out some of
those pieces
um and test them once and test them in
uh the most specific way you need to
good points you know good
good ideas through all of that
other questions or con comments
hearing none or everybody that's doing
so is you did
um i'll wrap this one up so just want as
always uh thank you always appreciate
your time
you know listening inputs uh as always
we're
we're open to uh suggestions and
uh other you know directions that we can
take some of this stuff if you have
questions comments or additional stuff
you can always reach us at info
developer.com developernoor.com we've
got a contact us forum that you can jump
on there
you can check us out on youtube we've
got videos going up there on a regular
basis or we've got
a lot of those thing out there in vimeo
as well
as always and thanks for spending your
time investing in your future because
uh you know your goal is our goal we
will make every developer better and
that includes you
so go out there and get better and we
will talk to you next
[Music]
you
Transcript Segments
0.68

[Music]

18.88

okay so diving in

20.56

um we we have talked in some prior

24.4

mentor sessions about we did some django

26.64

we did some python

28.64

and there's there are definitely some

32.32

uh very powerful tools that django

35.12

provides to us to do

37.28

uh really it's to do software right you

40.239

know in quotes it's to it's to

41.92

follow the things that we know need to

44.32

be done to create

46.16

good software and one of those things is

50.32

you know for better for worse you got to

52.079

test it you know i don't i don't know

53.68

anybody that writes code perfect the

55.28

first time or

56.64

even probably the hundredth or

57.84

thousandth time there's always things

60

that show up

61.6

and one of the best ways to start with a

64

foundation good firm foundation

65.76

is to unit test the code that you put

68.08

together

69.119

and it's also a way to it also i found

72.88

is a great way to provide sort of a

74.159

regression test

75.36

in a way when you're building

77.28

particularly when you're building a lot

78.64

of software that's either

80.799

that's a lot of working parts a lot of

83.28

blocks like maybe an api

85.68

microservices things like that we've got

88.32

all these little working pieces

90.64

and you may do a bunch of coding in a

93.68

short period of time and if there's any

98.24

relation between those various items

101.68

those blocks

102.799

then you do have the situation where

104.479

making a code change can

106.159

change you can have a downstream effect

108.64

so actually

109.36

i've found a lot of times where really

110.72

good unit testing is almost a formal

113.04

regression test it's not

115.28

quite to that level but it does allow us

118.079

to

119.28

at least get some sort of warm and fuzzy

121.52

feeling that we made these changes and

123.28

things

124.159

uh things work we didn't make any

125.759

assumptions that that were false that

127.52

would cause bugs

130

so that's unit testing in general just

133.28

trying to sell it a little bit i guess

135.52

and we're going to we're going to focus

138.239

this this will really be much of a

139.76

a lot of a working session kind of thing

141.52

to show some of the power of

143.84

of django and now it's got some of its

145.76

its built-in

147.12

unit test framework so we're going to

148.959

look at that

150.319

and then we're going to look at the talk

152

about how there's some setup and cleanup

153.599

stuff that's

154.48

available with this that it is a

156.4

framework it's not just

157.76

you know writing some code it actually

159.28

provides us a nice framework

161.2

to work with them and one of the things

163.84

that does

165.12

is it leverages the django models so

167.599

your your database

169.04

and the tables and structures there

172.319

that are so really essential to our

175.68

application really

177.76

allows us to uh to take advantage of

180

that

181.04

and then there's also because django is

183.12

a it's really it's a web application

185.599

there is a browser client that's a sort

187.519

of built-in browser client it provides

189.04

we're going to look at that

190.48

and then um may talk a little bit about

193.36

multiple scripts and inheritance and

195.28

how we can move some stuff around

199.92

so the built-in unit test framework for

202.319

django

203.599

um it's included with django

207.12

uh the the things we're going to talk

208.64

about today is a

210.319

there's the client and the test case

212.799

classes

214.319

and then with those we're able to in our

216.879

as we see

217.92

saw in our django applications we can

220.159

import our models

221.12

we can import forms we can import views

225.12

uh it's gonna allow us to do some setup

227.599

so that for each test we can do some

229.68

setup as needed whether it's

231.2

you know maybe there's some data we need

232.4

to create or a specific

234.72

uh environmental situation we want to

236.56

create we can we can do a setup within

238.84

that

240.159

there's also we're going to talk about

241.439

the web simulation side that it provides

244.319

so it gives us a way to without

247.439

having to spin up a you know actual even

250.56

development web server

252.56

the test system will does it all

255.04

internally so we don't have to worry

256.4

about that piece we don't have to have

257.759

it running anywhere

259.04

they won't have to worry about it

260.16

conflicting with an existing web server

262.4

running somewhere and uh it also

265.36

provides us a test

266.479

database so we don't have to worry about

269.6

you know messing up our even our

271.84

development or

272.88

our test databases we have the ability

275.28

to create

277.04

essentially a pristine environment and

279.28

then one that is very

280.479

tightly defined by what we do within our

284

tests

285.12

and so within that we can actually do

286.56

some very we can get very complicated in

288.479

the unit tests

289.919

with regards to data it's not just

291.919

functionality now we can actually go in

294.479

and have a provide a lot of uh data

297.52

related

298.32

pieces so that we can actually validate

300.08

it on that sense

301.36

uh actually hitting the database as

303.039

opposed to having to somehow

305.12

mock it up i mean it is a a full-blown

307.759

test database

309.84

and it's a really simple script which

311.919

we're going to see it's very easy to get

314.08

started there's there's not a whole lot

315.6

of work you have to do there's almost

316.72

nothing you have to do to get started

320.32

and based on that let's you know dive

322.32

right in and take a look at this thing

324.24

whoop

328.639

so um this is a full script so i'm going

332.24

to focus on some pieces of it

334

and actually let me do it this way i'm

336.4

going to

340

uh i'm going to switch this real quick

342.16

and then

345.52

oh it's not in that foamer it's uh

348.639

cpu mentor

360

so now i'm going to do

371.199

oh that's right so let's do this let's

373.84

go back to that script

379.12

and i'm going to close a bunch of this

381.28

stuff out

388.4

oops it's a page down that's not a

390

delete let's get rid of that

398

so uh we have back from our

401.84

uh application that we worked in uh let

404.56

me go ahead and open

405.84

that models

409.12

so we can go just to refresh our our

411.28

memory a little bit

414.8

um back in the back when we talked about

418.16

models as

418.96

a couple of classes or sessions back we

421.919

created

422.8

this very simple database to track

425.919

uh this actually was to track rss feeds

428.8

and

429.12

and articles that have come in with it

431.68

and so we didn't have a whole lot we

433.039

just had uh we have feeds

434.8

and then with feeds we have articles

436.4

which is a feed item

438.16

we have targets that are

441.759

i remember if we implemented that at all

445.12

we did not which is going to be targets

447.52

for where we post

448.4

articles we have types

451.759

which had to do with which is also

454.56

something we had not been that was just

456.4

to throw something in there as a test

458.319

sort of a test

459.84

model and then we have a status so this

462.16

would be a status whether it was red or

463.52

or

464.08

not red and actually a status can be

466.639

whatever but in that case

468

it was whether you basically is this new

470.479

have we read it

471.28

have we posted it what's the status of

473.52

this

474.4

article essentially

478.319

and so you know we have this very simple

481.599

set of models and we can import

484.8

so for this for today uh we're going to

488

import

488.8

just i'm going to stop popping up we're

490.96

gonna do the feed item

492.319

the feed and look up target we're gonna

495.199

be playing around with those

497.199

in order to set up a unit test and

500.08

actually let me do this

501.79

[Music]

505.36

do this um simply to get started

509.599

in order to get started with a test you

511.68

import in this case you really just need

513.599

test case

514.8

uh client is what we're going to be

516.24

using when we do the web version of it

518.8

so i'll go ahead and import that right

520.24

now we pull in models in case we need

522.959

those

523.919

which we will we're not right away but

526.56

we'll use the

527.279

django's model so we can actually do

529.04

some some work with models and

532.24

add values saved to the database things

534.08

of that nature

536.08

and i'm pulling in our app related

537.839

models

539.279

now in order to get started all you need

542.16

to do

542.72

is create a class and you can call it

545.04

whatever you want

545.839

and inherit from test case

548.88

and this is going to be this is what the

551.36

django system is going to look for it's

553.279

going to look for that test case

554.88

and because of that because it's based

557.76

off of that there's certain methods that

559.6

are available

560.72

that either it's going to you know use

563.12

the default one which is the base test

565.2

case or

566.399

you can override them and then

570.64

the most simplest one you can do is you

572.32

just create tests and they have to start

574.64

with

575.519

the name test it knows that that's what

578.48

i'm going to that's what i'm looking for

580.16

that's what i'm executing within my test

582.56

case

583.04

class so if i do test one it's going to

586.16

execute test one if i the next one i can

588.16

call it test two

589.839

as long as it starts with the word test

592.8

then

593.68

it's going to go through and execute it

596.959

now for the simplest one this is a

599.76

regular class so we're going to create a

601.44

property test name

604.079

and let's uh

607.76

we'll come back to that a little bit and

609.04

clean that one up and so

611.36

what we can do is keep that

615.92

is it uses assertions like just about

618.56

every other unit test tool i don't know

620.079

any unit test

620.88

tool actually that doesn't um it has a

623.519

and it has a couple different assertions

625.68

that it works with but for now

627.519

we're just gonna we're gonna stick to

629.04

the simple ones of asserting something

630.8

is equal

632.399

and basically if we if the assertion is

635.839

true

636.959

then it passes if it doesn't then it's

639.519

false

640.079

and then it's and then it's going to

641.44

fail so

643.279

let's say right now we're just going to

644.64

come in we're going to set this test

646.079

name and then we just want to do a cert

647.92

equal

648.88

just to make sure that our and actually

651.2

let's change this to

652.48

we're going to change this to not

653.519

defined

656.399

and then we want self.testing we're just

658.399

going to assert that when we come in

659.68

here

660.079

that this should be equal to not defined

664.56

so that would mean that in this case

668.16

this test will pass if when i get to

670.88

test one

672.24

test name is equal to not defined so

675.12

let's flip over and actually run that

677.279

and it's actually very simple to do

681.839

we use the uh the manage which we've

684.48

used before

686.16

before we use manage.py to actually

688.24

start our server

689.519

so if we do a um

691.44

[Music]

692.72

if we do a run server i don't even know

695.68

if this will run

696.72

uh okay good then it will we could run

698.8

our server and i could go

700.839

to this address

704.56

you remember and let me just pick this

707.519

up

710

and i can see some oh but i don't have

712

anything allowed here right now oh i've

714.839

probably

716.079

yeah i didn't have this set up so i

719.04

could go in and run this

720.8

but i have it in sort of a broken state

722.88

right now

724.56

so that manage oops

727.839

provides us a lot of different tools and

730.72

we can see here

731.6

you can see where i got a bad request so

735.36

we ran that in the past so we're not

736.56

going to worry about that too much

738

another thing we can do is we can

739.36

actually run tests

740.48

and it's as difficult as saying manage

743.6

and then test so we run this

749.04

this is you know let's flip back to our

750.88

script so our script right now is just

752.399

this one test

754.24

and we're just doing a very simple

756

assertion but notice here

760.88

hopefully this is big enough to blow

762.48

this up a little bit more

764.32

if you notice when i run the test the

766.079

first thing it does is it says create

767.6

test database for alias default

769.68

what that does is that's actually going

771.279

back to that models

773.839

it's going back into my models and it's

775.279

creating a test database with these

777.04

models and these attributes

779.519

so i've got a full database that it's

781.519

creating for

782.88

my unit tests and then it's going to do

785.36

sort of a it does a

786.639

sort of sanity check to make sure things

788.48

going and then it starts running tests

791.519

and i believe that it's going to give it

793.92

gives you a little period i think for

795.2

each test rant

797.279

um the the interface there's a couple of

799.6

different ways there's like a verbose

801.279

and some other ways that you can do

802.639

stuff

803.12

so let me just verify that real quick so

805.36

if i create a second test

810.72

and i'm going to fail at this time

816.8

so in this case we see that it ended

818.24

with an okay is that it ran through it

820.639

ran one test

822.079

it got okay it passed and then it got

824.639

rid of that test database so i don't

826

have to worry about it

826.959

sitting around now with my two tests

830.8

again it recreates my uh let's see it

833.199

comes up here

833.839

creates my database oops wait here i'm

837.12

sorry here's where it's at so it creates

838.48

my database

840

uh it comes in and we get a dot for a

842.079

pass and then we get an f for a fail

844.32

so now it actually gives me some pretty

846.32

good information here

847.76

it says that test two is the one that

850.8

failed

852.24

and the assertion area of not defined

854.56

equals not defined period

856.639

it failed that and i can see where on

861.04

here i was looking for not defined but

863.68

not defined

864.56

period is what i found and so i thought

867.839

that i was i wanted both values to be

870.72

equal

871.199

but it's not because the second one's

872.72

here so it actually shows me it gives me

874.48

a pretty good way to

876

see what the issue is at least what i

877.92

was checking

879.44

and i can go in and fix that so i could

881.6

i can come back in here

885.519

and actually well let's actually leave

887.04

it that way so now i can come in

889.36

and i'm going to do self.test name

895.839

equals to

899.88

undefined so if i change it here

904

that's one way to fix it and i'm going

905.44

to run it

908

and so now it's okay again i ran my two

910.24

tests i see my two periods so i've got

912.16

two

912.8

successes there and

916.639

again you can see where it builds the

918.959

database

919.68

runs through everything and then gets

921.04

rid of the test database that's the same

923.04

thing that it did here is this going to

926.32

run through everything

927.44

it's going to bail out and or it's going

929.199

to get to the end and then it's going to

930.56

clean everything up

932.639

and so that provides us a nice little

935.6

environment to continue to get started

937.519

so let's get a little more complicated

940.399

here

941.36

um let me open the prior so i can sort

944.72

of

946.8

work our way into this uh where did i

950

put that

956.959

let's see there we go i'm sorry let me

960.24

move

960.639

test prior mentor

968.48

just steal some code so i'm not having

970.48

to

972.88

type quite as much

978.24

so let's pull this one over

982.959

so we've got those two tests let's

984.32

create a third test this one we're going

986.48

to actually

987.36

work with our model a little bit so we

988.959

pulled in

991.759

our feed and now what i'm going to do in

994.8

this third test is i'm going to and

997.44

let me go back and look at

1000.959

i look at models feed has a little

1003.839

function built into it that returns the

1006.079

name

1006.959

for a given feed so all i need to do in

1009.68

that case to test it is set the name

1012.16

so i'm going to go in in this case i'm

1013.519

just going to now i'm working with the

1014.639

model itself i'm not actually even in

1016.16

the database yet so i'm going to create

1017.68

a feed

1018.56

i'm going to set the name equals my test

1021.279

and then

1021.839

i'm going to verify that when i get the

1024.16

string version i call this whole

1025.6

function

1026.4

this better be what i get back because i

1028.16

just sent it now i just set that

1030.4

and so if i jump over and do it

1034.079

and i actually run the tests

1037.439

and actually let me do this let me clear

1038.72

this up a little bit

1040.799

then we're gonna see here that it runs

1042.4

through runs my three tests i get okay

1044.88

so it is setting that now this is a

1048.079

model so what i can do

1050.16

is i can do um

1055.28

i remember what all i needed for that so

1056.88

let me go look at my feed real quick

1060.4

so if i look over here oh do i have that

1062.64

in test prior did i set up a feed oh

1064.48

here we go

1069.2

i'm going to take this

1073.76

and so now i can come in i'm going to

1075.52

create a

1077.039

feed object well this is i mean

1080.96

a couple ways we can do this i haven't

1082.88

actually looked at this in the past

1084.559

this because feed is a model one of the

1087.28

things that allows us to do

1088.96

is we can do a create and we can set

1091.039

values right away

1092.84

or we can um

1096.24

let me do the same thing with the feed

1098.799

object i did

1099.679

i can also do feed.name

1105.28

and we're going to call it test feed 2.

1112.559

whoops mistake because i'm setting the

1115.36

name and then i'm going to do feed

1120.84

description

1123.6

it's going to be a test

1126.799

record and then i need the image link

1133.12

and this is going to be http

1137.44

my link

1142.72

and did i need something else oh i need

1144.72

an actual link i'm just gonna do another

1146.16

one of those

1152.4

so we're starting to dig into even

1154.32

though we're within a test

1155.52

here we're digging into

1159.12

having we have the full strength of

1162.96

the models available so we can either do

1166.08

it

1167.28

by creating an object a model object and

1169.76

using the save or we can actually get

1171.6

into the feed

1172.96

objects some of the stuff that models

1174.64

give us which

1176.4

we've got up here and we can do things

1178.24

like we can create or we can even get so

1180.64

we can do

1181.36

a feed dot

1187.039

objects dot all

1194.88

and then i can actually see so now i

1198

should have

1200

based on what i have done

1204.159

i should have actually two objects that

1205.919

i've created in my database

1208.159

and so i've got this test feed one that

1210.48

i created this

1211.44

directly through this create and i've

1213.36

got test feed two that i did by saving

1215.919

feed one so i should be able to take the

1218.72

length of results

1220.4

it's going to tell me how many records

1221.52

do i have i better have

1223.6

two records and actually just to sort of

1226.4

show what we've got

1229.039

i should start with zero records so

1232.08

test three is now becoming all more

1234.08

complicated but let's go

1235.44

run through that and what we're gonna

1236.799

see is

1238.88

that everything ran through so i have

1241.919

no objects i

1245.12

add a few objects and then

1248.88

i've got those objects in my test

1251.36

database

1252.24

if i run it again

1255.36

it's still successful because even

1257.039

though i i inserted those objects

1260

that got closed uh here where it does

1262.48

destroy the test damage it got rid of

1264

all that stuff so

1265.28

i can rerun this a thousand times i can

1267.28

add records in i can do what i need to

1269.44

for that

1270.96

um and i think i want to do

1278.799

yeah okay that'll do for now so i'm

1280.88

going to flip back over before we go in

1282.72

a couple more things presentation side

1286.72

so we looked at here we're really we're

1288.559

looking at just the most basic

1290.32

tests and starting into the models

1294.64

so now i want to talk a little bit more

1296.72

about those models

1298.64

as we've seen we have the full django

1302.08

environment actually

1303.2

in this unit test script already so the

1306.159

models as we see we just import them and

1307.84

we're off and running we can import the

1309.36

views we can import forms

1311.919

if we've got other classes that we've

1313.44

built that we're using for

1315.2

maybe like utility functions and things

1316.96

like that we can pull those things over

1320.88

and the models and forms give us

1324.24

all sorts of power in doing a full-blown

1327.52

test we can

1329.679

build out an entire if we want to an

1331.76

entire database

1333.6

do a lot of work within it and then it's

1335.36

all clean and it's cleaned up when we're

1336.96

done

1337.76

so we have a very easy creation of

1340.559

records and database interactions as

1342.72

we've already seen

1344.24

we can add records we can uh pull

1346.799

records back out

1348.48

and we're gonna in the next working

1350.08

session we're gonna go a little deeper

1351.28

into that

1352.96

and the big change for all of this

1356.559

that i wanna look at is the setup is

1359.44

that we can

1360

come in and copy this guy in

1366.88

is and this goes back because this is a

1368.799

test case one of the things it looks for

1370.559

is something called

1372.84

setup

1374.799

and what setup does is that is going to

1377.44

be run

1378.32

before every single test

1381.6

so where in test three i had a whole lot

1384.88

of code i had a bunch of stuff that i

1386.159

was setting up

1387.28

what i could do instead

1390.32

is i could take that information

1391.919

essentially and do it in the setup which

1394.559

is what i've done here so i can come in

1396.24

and instead of creating these two

1397.44

records here

1398.48

i can just say you know what i want

1399.679

those two records to exist everywhere

1402.08

for every single test so here

1405.6

where you see where this it start out

1407.6

with an empty record

1409.6

if i set this up in the setup

1413.6

actually let's do it this way and so

1415.44

we're going to see

1420.159

that for each of these tests the first

1422

thing it's going to do

1423.76

is i'm going to it's going to actually

1425.2

import these two records

1427.279

and so we're going to see here it's

1428.4

going to fail because it's not an empty

1430.08

database anymore

1431.679

and so we come through

1435.679

and we see that somewhere up here it

1438

failed and it's failed

1439.039

and so it failed on test one

1442.08

oh because it's uh this is interesting

1444.4

is it comes back here

1447.279

and in the setup i changed the object

1450.799

level variable

1452.72

whoops to round one

1455.84

well now it's failing here because it's

1458.4

not that not defined anymore it's been

1460.08

redefined

1462

by the setup

1465.279

and so now this is like this will be a

1468.32

fun one to do because now what i do if i

1470.24

call if i look for it to be equal to

1472

round one it will pass

1475.36

but let's go set

1480.96

if i come here and i set the test name

1484.48

equals to define and guess what i'm

1487.52

gonna find is that when i come back in

1489.279

even though i did i set it here it's

1492.32

gonna get reset

1493.36

in the setup before i come into step two

1495.52

so test two so i'm gonna find that it's

1497.279

actually been reset

1498.24

to round one

1502.64

and so now i can see it passed the first

1504.4

two and we come to the

1505.76

third one and this is where we it says

1509.36

hey i've already got records in my

1510.72

database

1512.799

so you can say well that's pretty cool i

1514.48

can i can slide some values

1517.44

and you know be off and running well the

1519.12

thing here is

1521.36

it's also doing it to the database so i

1523.52

come in and this is a pristine database

1525.919

so i create these two objects and note

1528.799

that it's not adding each time so i'm

1531.2

getting two records

1533.279

at the start of each test and

1536.88

if i come in let's see

1540.64

let's just sort of clean this test up

1542.24

real quick let's say that i come

1544.4

in and in test two

1549.36

i'm gonna add two more records a test

1552

three

1552.64

and a test four

1556.96

and i'm just adding two more records but

1560

i'm gonna come into test three and find

1561.279

out those two records

1562.799

have now disappeared and i'm back to

1565.52

what i do within my setup

1570.48

and so we can see here that bam and

1572.32

walked through each of our three tests

1573.679

successfully

1574.88

ran all three of them and we get an okay

1578.64

so this is not again

1581.76

this stuff should not be

1584.799

new and you know jaw dropping

1587.84

kinds of features because this is stuff

1589.279

you will normally see in

1591.12

a good unit test system you know if

1594

you're using like a j

1595.12

unit or n unit or stuff like that is

1596.72

that you have the idea of setups and

1598.64

breakdowns and cleanups and things like

1600.24

that but this is

1602.08

all from basically just

1605.2

right out of the box you don't have to

1607.279

you don't have to go pull another

1608.48

library in you don't have to do anything

1609.919

special

1611.2

is that you because you are running

1614.88

this uh wherever that is at

1617.919

because you're running this with the

1619.6

django

1621.12

infrastructure it pulls all that stuff

1623.52

in

1624.24

and makes it very quickly available to

1626.72

you so you can actually start doing some

1628.24

pretty

1628.72

you know complicated things you could

1630.159

try to uh you can test things like

1633.039

your referential integrity within your

1634.72

database is i could i could create some

1637.039

objects

1637.919

and i can create some that are you know

1640.24

that have some foreign

1641.279

key relationships and make sure that

1642.799

those uh those exist

1646.32

it's going to be consistent so i can

1649.84

if i need to i can actually base these

1651.919

on

1652.88

primary key ids yeah it's normally not

1656.399

recommended with your testing but i

1658.24

could because i would know that this is

1659.76

a pristine database so i can know

1662.88

that the id for these is always going to

1665.84

be the same so if i come in

1669.44

and do a get

1672.96

uh let's do let's do it here so if i

1675.12

come in

1676.559

and i do from feed objects

1680.84

get and i'm gonna do where name is equal

1684.64

to

1685.44

uh test feed one

1691.6

and then i just print

1694.799

uh oops that's gonna be my object

1699.679

and object.id i'm gonna see where that

1703.039

this is always gonna be

1704.559

the same id so if i can run this let's

1707.2

do it like this

1707.919

clear the screen real quick if i run it

1711.84

so here my id is seven if i run it again

1716.32

my id is seven i run it again

1720.559

my id is seven so i'm getting this every

1722.799

time and doing that little things

1724

printing out it's

1724.72

it is very consistent now why that thing

1727.84

is an idea seven is actually pretty

1729.6

interesting in itself

1731.76

um not sure why it generated

1735.039

that number uh let's see what is test v2

1738

that must be seven and eight

1746.48

yep so it's always eight there

1749.76

but what i do know is that i now have a

1751.279

i have a consistency within

1754.159

my objects oh and actually right here oh

1756.88

this is going to be a neat one because i

1758.159

bet if i print my object id here

1762

permanently while i'm playing around a

1763.12

little bit because this is but i think

1764.64

this is sort of useful is what i think

1765.84

what we're going to see is because it is

1767.52

i bet it didn't blow away the whole

1768.96

database

1770.799

um i don't need these cert equals

1774

i don't need the assert equals

1777.76

so probably what we're going to see is

1778.96

we're going to actually see this crawl

1780.159

up because it's going to

1781.2

delete the records and not drop the

1783.2

database let's see what that does there

1786.399

just because

1789.44

yep so we can see here it's not actually

1791.679

so it is it's cleaning out the data it's

1793.84

because this is an auto-generated uh

1796.32

primary key

1798.159

then we will see that it's uh it's

1800.72

actually not just

1801.6

like recreating the database from

1803.76

scratch

1804.799

it is uh cleaning up the objects and

1808.799

recreating them the next time around so

1811.44

and so it's kind of saying which again

1812.72

goes back to id

1814.08

the idea that you don't want to actually

1815.679

look for ids you don't want to

1817.84

look for those because those technically

1819.919

should have nothing to do with your

1821.12

records you should instead be

1822.72

doing things like here you know

1824.08

searching by name or description

1825.679

something along those lines

1830.24

so that's the

1834.159

the back end the middle tier side of it

1836.88

now

1837.84

django we have a you know this is a a

1840.08

web application

1841.84

so we also want to have the ability to

1844.559

test that out

1845.52

is to be able to look at our our urls

1847.84

our views and see how those things work

1850.24

now we can we could within our

1855.36

oh good okay it's right here so if i

1856.88

wanted to look at my views

1860.08

i could go in and try to mock these

1862.399

things up i mean these are all built

1863.84

within my views

1864.799

these are functions that require a

1866.96

request

1868.72

now what i could do is uh basically find

1871.679

a way to abstract each of these out to

1873.44

just a straight

1874.48

function one that's you know behind a

1876.72

middle tier function

1878.159

and then the request would just pass

1879.84

things into it that seems like a lot of

1882

extra work

1883.279

when one of the things i want to do is

1885.36

is really validate

1886.64

my my urls which are over here i want to

1890.32

be able to validate that these things

1891.76

are doing something

1893.44

you know functional and so we

1896.88

we talked about client is something

1899.36

we're going to take a look at next

1900.48

that's that other piece we had test case

1902.559

and then we have client and so what

1905.44

client gives

1906

us this is for our test purposes it

1907.919

gives us sort of a

1909.039

it gives us a test server this up that's

1912

not

1912.72

going to interfere with other existing

1914.72

servers we have

1916.399

and while we can extract stuff into

1920

others functions and methods this gives

1922.24

us the

1923.2

the ability to test that web side of it

1925.36

so even if we abstract them we still

1926.96

want to make sure that our urls

1928.72

go and do as we design them

1931.84

and so you have to have some way to test

1934.08

it from a

1934.88

browser point of view and since it's a

1937.76

unit test you don't really

1939.12

care to you don't have to actually see

1941.76

it it's not like

1942.96

selenium or something where you need to

1944.399

actually go in

1946.08

and record stuff uh for this point part

1949.039

where really we're gonna do things like

1950.32

say hey i want to just be able to see

1952.08

what you know can i get what i need from

1955.039

these

1955.6

uh these paths and so in that case

1959.519

uh where's my test so in this case we're

1962

gonna actually start creating some stuff

1963.36

related to client

1964.799

so let's go pull

1968.64

and go pull a bunch of these real quick

1972.08

well two of these

1975.2

and

1980.159

let's see did i get it oh there we go so

1983.279

it's gonna be test four and five

1989.84

and with a client all you have to do

1993.6

is you're going to create we need to

1996.72

actually create an instance of it so i'm

1998.64

just going to do client actually i'm

2000.24

going to call it c

2001.039

because i did call it c yeah

2004.799

and so i'm going to just create that as

2006.48

at the the class level i could

2008.32

recreate it at each time but i'm just

2009.76

going to create at the class level and

2010.88

let it sit there

2012

and so now all i need to do

2015.039

is i'm going to refer to that

2020

i'm going to look at my property called

2021.84

c and all i need to do as a post

2025.84

is and that's that's it i'm going to

2027.84

post and i can do a post i can do a get

2029.6

i can do a put but i can post to

2034.24

and all i have to do is just give it the

2035.919

url so if i want to test my urls

2038.159

i could actually walk through this i

2040.32

could take this list

2043.519

just to make you know sort of do a

2044.64

sanity check on my urls is i could

2046.96

actually

2047.6

do for each of these so here

2050.72

now i am going to put in some potential

2052.72

uh some cases i'm going to do like a

2054.24

post or something like that

2056.96

but i can do here i've got a list

2061.2

i'm looking at feeds if i want to do

2065.839

an article and go to try to grab one

2067.839

it'll probably give me an

2068.879

issue because i don't have any articles

2070.8

in this test database but

2072.399

whoops let's go ahead and throw that in

2074.079

there just to throw one more

2079.04

so article and i can just give it an id

2081.76

oops

2082.159

that one yeah article id

2088.56

and that'll be test six so as far as

2092.399

as testing from a um

2096.24

a web point of view it's actually again

2098.16

very simple as i just

2100

come in and say here's where i'm going

2101.839

and so what i'm going to do here is i'm

2102.88

not going to actually do my assertions

2103.92

yet i'm going to actually print out the

2105.119

response in each of these

2106.96

so we can see those and actually um

2110.079

let me put a little more around that

2114

so this is test four

2117.04

and

2121.2

i think this will give me something

2122.56

that's a little bit more

2124.11

[Music]

2125.68

reader friendly

2134.56

so let's go take a look at what that

2135.839

does

2137.76

uh let's clear this out

2141.04

and so we're going to run through uh

2143.76

let's see it's complaining oops

2146.56

i'm sorry i did that the wrong way

2151.04

i did it in java style

2157.359

okay whoops that needs to be an equals

2161.76

so i'm going to come in and i'm going to

2162.96

assign it to client so now if i come

2164.88

over here

2168.16

um let me clear this out real quick

2173.839

i'm going to get a different error

2174.96

apparently

2178.16

so it's going to print out that it's the

2180

same thing i had before now it comes in

2181.44

here

2182

and i'm getting a status code

2185.599

here i can do test four which

2188.64

is uh let me get rid of some of these

2192.88

other prints

2194.72

just to clean that up a little next time

2196.16

we go through it

2199.359

so test four i went to

2203.52

slash list and

2206.56

um actually for this purpose let's go

2209.68

back to

2210.4

let me go to my settings i think this

2213.2

needs to be

2214.4

set up here

2217.52

let's see if i can get my server running

2218.88

real quick

2226.56

so if i do a run server and do this

2230.56

whoops okay

2234.48

so

2237.76

over here i was going to

2240.88

um let's go back to my test so if i go

2244.96

to list

2246.48

let's flip back over if i actually go to

2248.4

list what should i be seeing

2252.88

so here it's actually it's going to try

2254.16

to log in because list forces

2256.32

that authentication now if i'm logged

2260.16

in

2265.52

oh i don't remember what the password

2267.359

was for this i want to say it was like

2272.4

maybe now i'll have to go check what

2274.64

that was i may not have that database

2276.079

set up

2277.119

but normally what's going to happen now

2278.48

is because it's it's ringing here it's

2280.24

actually redirecting me and so we're

2281.599

going to see that

2283.359

here um

2284.82

[Music]

2287.839

let me get rid of this back to that

2292.079

and we're going to see that is that when

2293.52

it comes darn it

2295.119

wrong test wrong app

2299.2

from the test and so when it comes

2303.04

through it

2303.76

actually gets the response where it's

2306.72

doing the redirect to accounts login

2310

and it's going to pass here did i do it

2312.96

i guess i did have a

2315.76

issue at the end of six so we'll take a

2318.16

look at that

2319.119

uh but here we're gonna see because this

2320.72

was protected it's gonna go over

2323.04

and try to force a log in here for the

2326.32

next one i did where i did just the

2328.4

feeds

2330.4

apparently that is not because it comes

2332.24

back

2333.44

and it just gives me a straight response

2335.359

of 200 and there's no other

2338.079

records in it so i don't have to i'm not

2340.48

going to see

2341.2

anything um although i should

2346.88

oh because that's actually the response

2348.48

there's not any kind of result or

2350.4

anything like that that i'm working with

2352.16

and then if i come into this one where i

2354.079

post it against article

2359.52

um oh it's actually giving me so when i

2363.44

try to call

2365.52

this i'm going to see that in

2369.119

the view somewhere probably where does

2371.599

it show it's not showing me oh

2373.839

no that's the test

2378.72

and it should tell me where it was in

2381.04

the view but i'm not seeing that one but

2383.04

i the issue here

2384.4

is that query does not exist and so

2387.68

i don't have an article one so i'm

2389.359

actually this is actually showing up in

2391.68

my code i'm seeing where my code does

2393.44

not handle

2394.72

the case where i don't have this article

2396.96

so i would have to do

2400.4

is probably create

2404.64

oh this is based off of an id so what i

2407.2

really would want to do

2408.72

because article is a feed i'd have to

2410.24

actually come in and do the

2413.04

uh i want to get

2416.4

to do this correctly i'm going to get

2418.56

that test feed 1

2420.079

that i've built out and then i'm going

2422.64

to want to add

2424.24

the object id so now if i were to view

2428.16

it

2436.72

then it comes in

2439.76

oh it's i'm sorry it's looking for

2443.2

uh that treats that as an integer and

2445.119

not a string so let's clean that up real

2447.359

quick

2451.04

and

2454.4

uh it doesn't like that anyway so i'd

2455.76

have to there's probably something

2456.72

broken in the code itself but what i'm

2458.4

seeing

2458.96

is that that is actually broken uh even

2462.319

though there's not an assertion

2464.319

i'm getting i'm getting an actual

2466.16

exception so i'm not even

2467.44

you know my code's not even running so

2468.72

this is something where i would have to

2469.92

actually

2470.72

fix this um

2474

so somewhere here where it says

2478.4

oh my mistake is that right

2486.24

oh it is but for so it's not picking

2487.92

that item that id

2489.359

up so that may not be the feed itself so

2491.92

i'm

2492.4

i'm here and i'm getting exactly what i

2495.2

should

2495.599

out of my unit test as i'm seeing that

2497.28

i'm getting some successes in here

2499.28

but i'm also getting failures and i get

2500.8

to see exactly

2503.119

from a development point of view or even

2505.92

a qa point of view

2507.04

i can see exactly that it's this is a

2508.88

test that it's blowing up on

2510.56

and i get to see you know the trace

2513.76

uh the stack trace of that issue so i

2516.8

could actually if i'm

2517.839

if i'm a qa person i could send this off

2519.92

to the developer and say hey when i run

2521.359

this

2522.319

you know when i run this thing

2526.319

this is you know or here this is what i

2528.64

get over here so you need to fix it or

2530.48

as a developer as you're running through

2532

your unit test which is

2533.359

really at the point you should be seeing

2534.839

this

2536.4

is i'm going to see that this thing is

2537.68

blowing up i'm not getting the

2540.72

the pieces back the way i want it to

2542.4

something's not

2544

working right here so something about

2546.16

this article which i could go look if i

2548

want to look at that

2548.96

real quick if i look at the views well

2550.72

let's see i got to see what is article

2552.24

called so article

2554.16

calls display article if i go here

2557.52

and go up there was display article if i

2560

take a look

2560.8

at well let's do this

2565.28

if i do display article oh it's a feed

2568.96

item

2569.599

that it's looking for not a feed and i

2571.599

was sending a feed in so i'd have to

2573.04

actually create a feed item

2574.48

in order to do that

2577.839

and a feed item is probably yeah so

2581.04

there's a there's a fair amount of stuff

2582.319

i'd have to do to create my feed item so

2583.76

i'm not going to

2584.88

go into that uh mostly because

2589.359

this is really the the meat of one that

2591.359

i wanted to cover

2592.88

in looking at the the testing here is

2594.56

that we've got

2596.56

uh looking at our test actually i can

2599.28

look at well i'll go with this one

2601.359

is that we've got within the matter of a

2603.44

couple of things that we import

2605.119

and we don't have to we didn't have to

2606.319

do any additional uh

2608.16

library downloads or anything like that

2609.839

it's this is all within

2611.359

the django environment that we can

2613.68

create a test case

2616.64

and then it does allow for setup we can

2619.359

do so we can

2620.4

set stuff up for each of our tests and

2623.599

then we're going to name them just

2625.28

as long as the name starts with test

2626.96

then it's ready to go so if i wanted to

2628.64

shut one of these down so like right now

2632.8

well really test 4 5 and 6 don't do

2635.52

anything

2636.079

so i could just come in and i could just

2638.319

call these

2641.04

x

2644.24

and i'm going to get a success because

2645.839

it's only running three tests

2648.48

because the name does not start with

2650.079

test anymore then i've i've basically

2652.72

blocked those out and there are

2654.319

situations where i've done that where

2655.68

i've made some changes and i've got

2657.44

maybe a huge script

2658.88

and i want to see what's working then i

2661.359

don't i may just say that this is yeah i

2663.2

could do like

2664.16

i could name it fail as i know this

2666.319

failed so i'm going to have to come

2668.16

through

2672.24

i can say those failed whoops

2675.76

and i can see here where okay i've got

2677.92

success well i could come in and say

2679.2

well i want to try to fix this one

2681.44

so i can fix this one

2684.56

and let me get rid of those prints i can

2687.2

fix this one

2689.839

um then run it not worry about those

2692.8

failures

2693.359

and say okay did i fix it yes i ran four

2696.88

tests

2697.359

okay so i fixed it so now i can move on

2699.04

to my next one so there's some easy ways

2701.04

that we can

2701.839

you know work within the system they

2703.119

have it's not the most you know

2705.04

complicated thing but

2706.72

i think from a unit test point of view

2708.079

that may be what we're looking for

2710.16

something nice and simple it's easy to

2712

add our tests

2713.119

it's easy to do some validations

2716.24

and move forward knowing that we have

2718.88

some level of comfort

2720.079

in our code working correctly

2725.599

so what have we learned uh hopefully

2728.4

we've learned that unit testing in

2729.52

django is built in and very simple

2732

and honestly as sort of a side note unit

2734.079

testing in most

2735.28

modern environments is actually pretty

2737.119

easy and should be

2739.52

it is it should not be an obstacle to

2741.44

most development

2742.96

teams groups methodologies whatever

2746

you're doing unit testing has gotten so

2748.8

it's a

2750.8

it's it's an accepted and expected

2754.56

part of so much development that i

2757.92

even in your your personal side projects

2760.8

i think it's very useful to make sure

2762.72

that that's just one of the habits you

2764.24

have is building out unit tests

2766.72

it's a great way to see how your

2769.28

application works or doesn't work

2771.839

and to really validate uh in a lot of

2774.48

cases you can i think you can almost

2775.76

code faster because you can just you can

2777.359

crank through some codes you can do some

2778.72

quick validations through unit tests

2780.72

make sure it works right and if you're

2783.119

you're right you move on if not then you

2784.72

fix it

2785.28

and then then you move on but with this

2788.56

in the in the django world we're able to

2790.319

leverage all of the other pieces that we

2794.16

looked at you know through the client or

2795.76

even through or through the

2797.599

unit test class we can we can look at

2801.119

urls we can look at views we can

2803.2

go if we're building out forms we're

2804.64

building out models if we're building

2805.92

out utility functions all of that stuff

2807.92

we can just pile it into our unit tests

2810.8

and

2811.28

uh that that client is actually very

2813.359

powerful so we've got a client provided

2815.28

so we can test our browser interaction

2816.96

very quickly we can look at responses

2818.96

and i could build assertions based on

2820.56

those you know through the

2822.079

um again looking at like the uh

2825.119

where a response is is i could actually

2827.92

go through and

2828.72

do some work with this is i could i

2830.319

could start parsing and try to see what

2831.92

my you know what my status code is make

2833.599

sure it's correct

2834.96

in this case for example i would expect

2838.72

in everything that is protected that

2840.4

this is essentially what i should get i

2842

should see

2843.359

the redirect should come there so i

2845.599

could easily build out unit tests to

2847.2

validate what's

2848.4

what requires authentication and what

2850.24

does not

2853.92

so at this point like no questions

2856.839

comments

2859.92

it's a comment that may lead to a

2861.76

question

2863.599

oh go ahead michael unless that was an

2866.88

echo no go ahead

2868.319

okay um yeah uh i just find it so easy i

2872.24

as you've mentioned it just it's so cool

2874.64

how easy it is

2876

to um set up these tests uh

2879.359

you almost would find yourself uh

2882.8

wanting to set up your testing framework

2885.52

um

2886.26

[Music]

2887.68

and in django and then just you know

2890.559

having it

2891.52

uh you know your code written in a

2893.44

different language that's just how easy

2895.359

it looks to

2896.319

to do and i think we mentioned that even

2898.319

for for instance like a

2900

your your crud operations for your uh

2902.96

your

2903.359

app setting that up in django and then

2905.92

the

2906.72

application written in a different

2908.079

language i wanted to ask though was

2910.4

there a

2911.28

uh particular and probably too nuanced

2914.16

uh but is there a particular

2916

testing design pattern you found useful

2918.16

or might be useful

2919.839

uh with this uh language django python

2923.52

that probably wouldn't be as easily

2925.92

implemented

2926.96

in any other language

2930.4

um

2931.06

[Applause]

2933.52

i'll answer that i guess with the com

2934.88

with a very big caveat is it

2936.96

uh no there isn't but there's also i

2939.119

haven't spent a lot of time

2941.359

digging into testing patterns i sort of

2945.839

particularly from a unit test point of

2947.44

view i i sort of have

2949.04

i've developed my own

2952.4

methodology or process of of how i i

2955.599

build out unit tests related to

2957.92

code i'm working on um and it works very

2960.88

well for that it's it's rather

2962.319

it's it's actually rather i guess in

2964.079

ways simplistic it's it's basically

2966.559

the idea of of testing uh within bounds

2971.2

edge conditions and then out of bounds

2973.44

and and then you know like nulls and

2975.44

things like that

2976.559

um back to your your other point too

2980

though

2980.319

is yeah it's i could easily

2983.44

see situations where i would build out

2987.52

especially the data side the database

2989.28

side of stuff where i could build that

2991.119

out

2992.16

using django and really use django

2995.52

almost as like a data

2997.28

almost like a data management testing

2999.2

tool so that i could just

3001.119

i could focus on back end stuff with

3003.04

that and whatever the front end doesn't

3005.119

matter it could be a java app it could

3007.28

be a

3009.119

you know angular app it could be

3010.839

whatever

3012.96

but i would be able to use this to

3015.599

actually test

3016.72

things like you know adding records and

3019.44

referential integrity and foreign key

3021.119

relationships

3022.72

and all of those kinds of data related

3027.119

testing items uh very quickly i mean

3029.839

it's you say there's there's not a whole

3031.28

lot you have any and really the

3032.8

python itself that's i think one of its

3035.119

strengths

3036.16

is it's such a simple language there's

3038.16

not a whole lot you have to do you don't

3039.68

have to

3040.559

you know build you know it's not like c

3042.16

plus plus where you have like your

3043.28

header file and your you know your

3044.88

source file and all this kind of other

3046

stuff you have to worry about

3046.88

compilation

3048

it's really quick so you know even here

3051.359

i was cranking through tests and and

3053.52

looking at results and making changes

3055.68

in a matter of seconds really and so to

3058.319

me it is it is very valuable for that

3060.559

is to use it as a way to you know really

3063.839

sort of

3064.24

i guess a data centric way to do some

3067.2

testing of your of your back end and

3069.68

potentially even your middle tier

3071.04

because you could turn around and point

3072.24

that to urls they don't have to be

3074.96

django urls per se and just

3078.319

validate the responses are coming back

3081.04

another other tools that do that kind of

3082.72

stuff you know you may

3083.76

like if you're going to test an api or

3085.04

something you may want to use like a i

3086.72

don't know postman or something like

3087.92

that there's

3088.8

there's other tools out there but if you

3090.4

want sort of a

3093.2

sort of like a one size fits all

3094.8

solution that i think it does fit that

3098.72

absolutely yeah

3102.64

uh michael you had a question or comment

3106.88

yeah i had a question so

3110.48

uh you have the setup method is it

3113.52

similar to like the other unit test

3115.28

where you can have a tear down

3116.88

and also have one that runs in front of

3120

each individual uh like

3121.839

you could have a set up and tear down

3123.2

for each of those tests within your test

3125.68

or is it basically just whatever's in

3128.72

that

3129.04

test file is what's going to get uh

3131.04

handled by the setup and teardown

3133.52

it does have a teardown i didn't get

3136.24

into that as mostly

3137.44

it was mostly just time constraints and

3139.599

stuff um

3141.359

i'd i've got to go back i would have to

3144.559

go back and verify it the way i've done

3146.16

it in the past

3147.119

is actually have multiple test scripts

3149.28

and so i end up importing a script

3151.119

you know within that so i would have um

3153.79

[Music]

3154.88

you know for example i don't know like a

3156.72

certain like if i have just like a

3158.16

normal customer relation

3159.76

type app i would maybe have uh customer

3162

related tests and then would have maybe

3164.079

organization related tests uh security

3166.8

related tests

3167.839

and do separate uh setup and tear downs

3170.559

for those

3171.76

uh i use it and that's that's also that

3174.72

sort of goes back to my style a little

3176.16

bit i usually do not do stuff where i'm

3178

gonna do a

3178.8

setup and tear down at a test level but

3181.28

i will do it for

3182.319

a group of tests and the way that you do

3184.8

that in python is you would have a class

3186.96

that has that so if i flip back over to

3190.319

the code

3192.16

so i would maybe have this would be um

3196.16

like here this would be maybe feed tests

3198.72

and then i could create i would maybe

3200.319

have a separate one

3202.72

uh which i could actually do in this

3204.24

this file or in another one and i could

3205.92

maybe have like feed

3207.52

item tests which would actually make

3210.96

sure you know

3211.68

in this case would be a good example

3213.68

where i want to do that is so i would

3215.119

come in with feed tests and i would have

3216.64

stuff based on these feed

3217.839

objects and have tests related to that

3220.079

separately i would have this feed item

3221.76

and i'd probably maybe i create one feed

3224.48

because feed items have a foreign key

3226.319

relationship but then i would have a

3227.68

bunch of feed items that i would create

3229.68

so i'm able to rebuild

3233.44

um my database you know as as needed

3236.88

and also keep it um

3239.92

sort of focus on the data that i need

3242.079

and i could do and i can do inherited

3244.16

tests as well so i could have i can

3245.76

actually

3246.48

you can get sort of complicated so i

3248.64

could have

3250.72

like an all tests

3254.48

um yeah that's what happens because

3257.599

yeah go ahead because there's cases

3261.04

where

3261.52

you want to basically do a setup

3264.559

and then run multiple test uh files

3268.48

um because you you're using test files

3271.44

to get very big if you try to put

3273.28

all your test cases in one file so

3275.52

sometimes it makes sense to

3277.2

split them out into multiple files but

3279.04

apply one

3280.799

uh setup and tear down and then

3283.28

essentially kick

3284.079

all those other files with that

3285.76

essentially the test utility the

3287.44

the master test so that's where i was

3289.76

asking about that so

3290.88

it looks like it has it like you said

3293.599

you just didn't have time to cover it

3295.68

yeah it's got there's it has some other

3298.4

functionality i kept it sort of simple

3299.92

and there's ways and there are ways that

3301.28

you can change around sort of how it

3302.96

looks for a tests and

3306.24

and things like that um but it's

3310

yeah it does allow for that idea of

3313.2

you could have you know sort of like a

3314.559

foundation of

3316.799

data and then within specific areas

3319.2

where you would want to have

3320.799

you know maybe add on top of that data

3322.64

but you don't really need that for the

3323.92

other

3324.799

pieces um so it does have that it's just

3327.92

we didn't you know we just really didn't

3329.359

get into it

3330.24

and i haven't pushed it i haven't built

3332.88

very

3333.359

big huge applications that way

3337.28

the largest one that i built using uh

3340.4

unit tests within python i actually we

3343.68

it was actually sort of interesting

3345.04

because the guy that i inherited from

3346.96

actually built his own um infrastructure

3350.559

that was essentially it's

3352

actually it's sort of funny because he

3353.76

it was very cool it's very complicated

3355.359

he'd

3355.839

tear down and rebuild the database and

3357.28

everything but django

3358.88

all the stuff django provides would have

3361.119

eliminated

3362.079

you know hundreds or thousands of lines

3363.76

of code that he had to go through

3365.68

um and it allows you to do it but the

3368.4

way

3368.72

the way i i focused it was that it was

3370.96

um it was a series of files and they

3373.2

were very

3373.92

functional so for any given set of

3377.2

functions

3377.839

i would basically build up an entire

3380.559

database that i wanted for that

3382.96

and then add on top of it and do my

3384.799

tests and then i ended up doing sort of

3386.48

basically it was a copy paste method

3388.64

instead of doing inheritance i would

3389.92

just copy and paste the script to the

3391.359

other one

3392.559

so i don't know how uh

3395.68

how well it handles deep relationships

3398.559

and inheritance

3399.68

i do know it's there but that would be

3402.559

something that would be sort of a you

3403.92

know

3404.16

unit test two or advanced unit testing

3406.16

or something like that

3409.599

true one approach even though you're

3412.799

copying your scripts over which is fine

3414.96

and that's actually a pretty standard

3416.799

way of doing testing with databases and

3418.48

stuff like that

3419.359

but what you really want to do if you're

3421.28

doing something like this

3422.48

is you want to essentially test all your

3425.68

inserts deletes and all that correctly

3427.52

so you build all that

3429.119

first and make sure that that gets run

3431.839

at the start of your test

3433.04

so you're testing all your uh you know

3436.4

all the correct inputs and outputs of

3438

the database and then run all your tests

3439.92

against the data after you actually do

3441.68

all the transactions at the beginning

3444.64

yeah yeah usually that's what you would

3446.319

that's where what you'd normally want to

3447.839

do is that's why you'd want to have

3448.96

essentially some sort of a setup

3450.799

is that you have a you know or a a

3452.88

prerequisite test or something like that

3454.72

so you go run

3456

all your inserts and updates and deletes

3458.64

and

3459.599

all the crud related functions build all

3461.92

your tests related to that

3463.599

and then i you know ideally that you

3465.2

would build on top of that so you would

3466.72

go run

3467.359

you would lay out your foundational data

3469.44

you would test all that make sure it's

3470.799

good

3471.359

and then you would run your tests on top

3473.52

of that so that if the

3475.44

um the foundational tests fail

3478.799

then you know theoretically you wouldn't

3480.319

even you know just go address those

3482.24

first

3482.64

and you wouldn't even worry about the

3483.839

other pieces because they

3485.92

probably are poisoned by those you know

3488.079

those bugs

3489.119

upstream um and that was roughly how it

3492.48

worked it was just uh

3493.68

again it was because this was built off

3495.44

of somebody else's stuff and

3497.359

and just shortcuts as opposed to doing

3499.92

it the right way so exactly the way i

3501.44

said you should do it i did it

3502.799

differently

3503.44

just out of the shortcut method

3506.559

and it did end up running you know what

3508.319

you'd end up doing is you'd have

3509.839

because of the way it worked um the

3512.72

foundational stuff got run along with

3514.48

your unit test so you had

3516.079

with each of those tests probably

3519.2

i don't know dozens you know maybe 100

3521.2

tests that were run

3522.72

over and over and over and over again it

3524.64

really didn't need to be you know it

3525.68

could have just been run once

3527.119

and and move on which is where you would

3529.68

want to do it in this case where you'd

3530.96

want to have some sort of a

3532.64

if you do an inheritance or some

3534.319

inclusions or things like that

3536.4

then you have some opportunities so that

3538

you can you can go build out some of

3539.76

those pieces

3541.119

um and test them once and test them in

3544.88

uh the most specific way you need to

3547.599

good points you know good

3548.96

good ideas through all of that

3552

other questions or con comments

3560

hearing none or everybody that's doing

3561.92

so is you did

3564.079

um i'll wrap this one up so just want as

3567.52

always uh thank you always appreciate

3570.64

your time

3571.28

you know listening inputs uh as always

3574.079

we're

3574.48

we're open to uh suggestions and

3577.68

uh other you know directions that we can

3579.359

take some of this stuff if you have

3580.96

questions comments or additional stuff

3582.48

you can always reach us at info

3584.839

developer.com developernoor.com we've

3586.88

got a contact us forum that you can jump

3588.64

on there

3589.44

you can check us out on youtube we've

3591.52

got videos going up there on a regular

3593.2

basis or we've got

3594.4

a lot of those thing out there in vimeo

3596.319

as well

3598

as always and thanks for spending your

3599.76

time investing in your future because

3601.92

uh you know your goal is our goal we

3603.92

will make every developer better and

3605.68

that includes you

3607.119

so go out there and get better and we

3609.359

will talk to you next

3617.64

[Music]

3629.68

you