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
[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