Django Testing - Model Testing Introduction

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome to testing in django so this tutorial is going to give you an introduction to django model testing so in this tutorial we're going to cover four items here so first of all test organization just going to give you a few ideas on how you might want to organize your tests and then of course we're moving to model testing so the idea here is that we'll start with a simple model and then we add items to the model typical things you might want to add to your or include in your models and items that might need testing so while we're doing this i'm going to introduce a package called coverage assuming that you're completely new to testing one of the important questions that you've probably asked is what do i actually need to test so this is going to be a good package to answer that question and then finally i'll introduce you to a package called model bakery this is just going to create as it says here fixtures for our testing so assume that you've got a massive database so this package is essentially going to auto create data for you in your model when you're utilizing it a model to test so instead of having to populate the whole model this will auto generate items for you okay so first up let's just talk a little bit about test management or folder and file structure so first of all we realized from the first tutorial that we have tests in this test pi file here so we can remove this and then what we can do here is that we can create a new folder so this is one folder structure that you might want to follow so inside of here we could for example call this tess if you wanted to and then inside of here we could then manage our files so for example we might want to run model tests in a separate file and then our views and then our urls so we would separate our tests into individual files in that manner now if we wanted to work this way we would need to include a a dunder init file so that would be important to include here and we see why shortly so we're going to be utilizing this method here so a second method we could utilize we might want to test per feature rather than model view urls etc in a separate file so here we would have a separate folder maybe again you'd call it tess uh test2 and then inside of here we would have a folder so for everything we wanted to test for every feature we would have a folder associated to that feature so here would have a new file for folder sorry called comments inside of comments i would then have my file tests and obviously that would include all my tests that's associated to this feature the comments feature of my application of course there's many different ways you can structure your folders for testing but those are just two very common ways you'll probably read online and in books of structuring your tests so we're going to be utilizing this first method so i'm just going to remove this and we're going to go into the model because we're going to be testing some models so we're going to need a model to test so i've headed over to the app one models i've created this very simple model so we're going to start simple and we're going to add on items to this model and expand our testing so we'll also include the model string representation so our function here our dunder string function and that's going to return the title so now let's think about testing this model so the biggest question here is what exactly do i test so what we're going to do now is install a package which is going to identify for us potential areas that we need to test in this model so let's go ahead and pip install and we're going to run a package called coverage coverage so this package is going to give us an insight into what potentially needs to be tested inside of this model here and it's going to give us a two interfaces we can use the interface here in the console or it's going to provide us a html page which we can utilize for more information about what tests we might want to run so let's have a look at how we can actually utilize coverage so if we run coverage run manage pi tests that's going to run the tests associated in this project so it's going to look for the tests and try and run them obviously we don't actually have any tests at the moment so that's the command we're going to utilize for that so once we run some tests we can then check the report the coverage report and it gives us details on areas potentially that we need to test so we can run coverage report so here what you're going to notice is it picks up quite a lot of different things here but if you look at the results here you can see it comes from the virtual environment and moving up to the top here you'll eventually find your application or app one and there's some tests here that might need completing so what we need to do is remove the virtual environment from this report and to do that we just need to run a separate command where we can omit the the vamp or the virtual environment folder that we've created so if you're not using the virtual environment you're not going to have this come up but you can see here that i've got the virtual environment here in a folder called vmv so what you need to do here is just run the command again but here use the omit and then define the folder you want to emit here and carry on so we run the test now and then we can now get the results so if i now run the results again you can now see it just indicates or it just shows the application and avoids the virtual environment folder so having a look at these results here what's uh something to point out is this section here are app1 models so there's six statements in this model and apparently we've missed one so here's indicating that potentially there is a test that's required and here we have coverage so the idea here is a little bit like a game really you're trying to build as many tests as possible to get a hundred percent coverage of testing in these particular areas so this isn't always going to show you all the tests that you need to do but for beginners who are looking into testing in django this is a very good indicator to help guide you on what is needed to be tested so to help you define this further what we can do is we can run the coverage html so let's run this it's just coverage html and this is going to provide you a new section here in the left-hand side you can see a new folder here inside of here we have an index so i'm just going to copy that path so i've opened up a new browser and i've copied and pasted the copy paste is a link that i copied there you saw me copy and you can now see i can see the coverage report and what's handy about this is i can drill down into my model so i can select this item here and it tells you now exactly what potentially is missing so here it's indicating the fact that i need to test this dunder string method here so that is exactly what we need to do first so now let's go ahead to the test and actually build a test to actually overcome this missing test that's required okay so head over to app1 in test folder here i'm going to be utilizing the model file here for my tests and of course make sure you've got this dunder method here otherwise you'll have problems actually running the test we'll see that shortly in action so in the model file we're going to have a a line of code here which is going to bring in the test case so let's uh get that in and then we need to go ahead and actually import the table so we're going to be utilizing that so we're not actually going to be running these tests on the actual table and the tests are going to create a separate table for us to actually run the test remember and then we build a new class so this is going to be our tests and here i'm going to test at models so i've called it test at models and i've imported the i'm utilizing or extending from the test case and here i'm going to create a new function so this is going to be called test model string okay so what do i need to do to test this model string so if i go back in you can see that this string is going to output the title so what i'm essentially doing here is i'm just checking to make sure if i'm utilizing a post or if i'm outputting a post that the title of the post equals the title of the output of this string here so that's what we're trying to do so first of all we go and we create some data for our new table that we're going to make for testing essentially so post objects create and then the title is just going to be called django testing so i've added this piece of information um i could go ahead if i wanted to and add some content so i can just extend this and add some content here equals content so once i've got that information in i'll just remove that for now and we now go over and you can also additionally just make a new line for the content so you can add in information that way if you prefer so now we've got the data ready in our test database we can now test so what we're doing here is we're using an asset equal so basically what we're trying to say here is that this item here needs to equal this item here so here we have str so in this instance the dunder string method is called whenever you use or whenever you call the str function here on an object so this is essentially a really simple test you can see we're going to just call this title and obviously it's going to represent this here so let's now go ahead and run this test so just to make your life a little bit easier potentially i've added all the different commands i'll add some more as we go along in this test in series some useful commands sorry that will be easy for you to access if you forget them and that you can utilize in these tutorials and when you're testing so there's a whole load of different commands here and i'll just try and add two of them if you find that i've forgotten any then please just let me know in the comments and i'll add them into the commands text so let's now go ahead and try and run these tests so here we're going to run this here so we want to run the test in app one so we go ahead and do that so here it says rand 0 test now let's just expand this and see what the potential problem is here um so it says manage pi test one system check identified no issues around zero tests so there's clearly something going wrong here because we have actually defined one test so what we're going to need to do here in actual fact in our um under init file here if we open this up move this down we're going to need to add a line here for it to be utilized correctly and to pick up everything that we need so what we're going to do is say from models import all now in actual fact it's going to be model important so what we're doing here is we're just importing or we're just including all of the tests that are inside of this model here so now what we're going to do is go back here and try and run the test again and you can see that we've got a problem so it says here no such table at one post so i'm just trying to um honestly i am just trying to give you an idea of some of the um different problems that you might have here again i'm assuming that you're new to django or you're fairly newish to django whilst undertaking this tutorial so you can pretty much guess potentially what the problem is here we've created a new table and we haven't actually migrated the data so the table doesn't actually exist yet no such table so let's go ahead and make migrations and we'll go ahead and then migrate and then we're going to run the test again so test app one and this time you can see that we've ran one test and everything was okay so there are a few different ways of testing the string that under string so if you do have any different ways and you want to share them in the comments please do and i will update this to include the different options and different methods of doing that okay so that's running the test but of course we need to use coverage here so we're going to run the test using coverage so coverage run manage pi test app so go ahead and do that and that's then going to allow us then to update the html so we'll do that we'll do the coverage html that's going to produce a a new html list and of course it's going to be in the same places where it was previously so we can just go ahead and access the the html page and then let's just do a refresh and you can now see we have six statements here and there's zero missing so there's zero tests that need to be done so essentially this is 100 tested congratulations okay so now let's expand our model so back in the app one models here we're just going to make this a little bit more complex so now we're adding the user so we're going to import the users from the models of the auth model and we're then going to now build a many to many so you don't necessarily have to test uh many-to-many um but you can do of course and so we're gonna do that next so this is a many many to field we've got like so this indicates all the users um that have light this post that's essentially what's going to happen here so if you're following the um simple blog project that i'm running at the moment you'll notice that our table has this so to test that we can follow this procedure so now if we head back into the test let's think about how we're now going to do that of course let's just not forget this time to maker the migrations and then obviously migrate oh sorry what's going on there okay so we've migrated that let's go and head into the testing now so let's build a test for this main to many okay so we're going to need the user model so we've imported that in there and then we're going to create a new function here so this is going to be test post like users so what we're going to need here is obviously some users so let's just build a user to begin with so we're going to call that test user and you can see here we've got user objects create user and we're going to give it a username and a password so that's pretty much all we're going to need there then what we're going to do in actual fact is we're going to build two users so let's go ahead and do that of course we could just use one or two i just want to give you an example of utilizing two users and then we're going to need an actual post so let's go ahead and build a post so this is just going to have a title and here you can also see that i've included content and a slug so we've just added some new items here in this new post that we've created now slug doesn't actually exist yet so we get rid of that right so now what we need to do is uh test this out so so before we can test this we need to actually add some users to this entry in the database so if you remember we've got title content and likes so we need to refer these users or add them to the like section of this post entry here so let's just do that first so we're going to need to set this up in a way that we take in the title and then define the likes and then dot set and then we set the test user primary key for the test user and then the test user 2 we set the primary key here so now we've got two users associated in this single post right here so essentially what we're testing now is that there are two users associated to this post here so let's go ahead and do that so again we're just going to count the amount any amount of likes we have in this user post here or this post here so assert equals so on the left hand side we have title likes count so we count how many likes there are um or users that have liked this post and that should equal two okay so let's go ahead now and test that out so we covered run manage pi test app one so that should now include two tests so we ran two tests they're all okay you can see that destroying the test database has been completed so now we've got two tests so let's just see um let's just remove this test uh temporarily and just see if it gets picked up by coverage so let's just run coverage again and then we run the coverage html so let's just see if it gets picked up first um as something that needs to be tested so if we go back into the browser and refresh so isn't actually identifying this as something that does actually need to be tested so like i said some some developers might actually test this but um you may choose not to so i just wanted to provide an example of doing that of course you could do the same with the um one-to-many links as well if you wanted to okay so the next stage let's just build this up further this table so this time we're going to add a slug so we're going to use this log field to utilize or create and get absolute url let's pretend that we've created a post field here and we want to on one page for example show all posts and then another page show a single post so we want to um get the absolute url for that single post so let's just set up a function here so a absolute url and we're using reverse so we need to kind of import that in so what we're doing here is that in our templates we can use the get absolute url to actually get the url of a single post and that will then auto generate a url string that can be placed in a link a html link and we click on that and it takes us then to that page you can see here that we're using the slug for this so that's how we're linking to or creating the link so let's just quickly go into the views and we'll just build up these views here so there's going to be two views we're going to have a a home view and then also a post single view so here we're just rendering out a new template called index and just showing all the posts and then here we've got the detail page where we're just going to show the individual item notice here it says sluggish post so we're going to get the post from the database utilizing the post name or the post slug so here just to clarify what's going on um when the user clicks on a single item that would take them to their single post page and that's all referenced via the slug so yeah essentially we're just going to test this get absolute url um so let's just go ahead and create a new folder here we're going to call this templates you can skip ahead if you don't want to see all this um so we've got templates here so we've got two templates we're going to create i've already pre-made them so in here we're just going to loop through the post that we might have and then here we're just going to show the post title and post content so just two simple pages pages just for now just to see that it's working and here you can see that we're using the get absolute url so of course we're going to need some urls so let's go ahead and type in urls.pi and then we're going to need some urls here so let's go ahead and create those so here we're just going to um using this namespace app1 here we've got two urls one for the home and one here for the actual single page where we take in the path of the slug post so we're generating um the slug the uh we're generating the get absolute url um slug via the slug and then we're utilizing that to then identify an individual single post and then displaying it on the details page so with that in place obviously we need to go to the core and we just need to replace these urls with the new set of urls so we'll go ahead and do that so and we've just got one for the admin and then one single one here for app one urls and that just connects via the namespace app one okay so let's just go ahead and create a new um super user so i've gone ahead and created a new cpu user i've gone into the admin of app one i've just registered the post um in the admin here and i've turned the server on so now we can go back into the server i've already logged in okay so i just make a a new post here press save um this is really just to show that it's working so you can see here that we've got this um item here and we've got the uh slash new so that's taken from the slug so if i inspect this you can see we're getting the link via if i go back into the code you can see in the templates again just to um we're getting the absolute url uh which is the uh post if we go back into the model it's the post slug we're getting it from the slug which we wrote as new so titles new slug was new so that's how that's all being generated and you can see i'll click on that and takes us to the post so if you weren't too familiar about what that meant um in terms of get absolute url you now absolutely know hopefully what that's all about so we're now going to test this so let's first of all just uh double check that it needs testing so let's go ahead and use sylla's coverage so let's just run the tests again the coverage test so we've still got two tests at the moment so now let's go ahead and run the html again and then we'll head over to the coverage page so just refresh you can now see that we've got one missing so you're probably seeing a pattern here in tests so custom methods methods in your model you're gonna test yeah or you should test that um that's um usually tested with a unit test so that's essentially what we're doing here so um let's go ahead now and go in our tests and now make the test for this absolute url so here's the problem i've got the moment uh you can see i'm repeating myself or repeating code quite a lot here so we're trying to obviously follow the dry principles here don't repeat yourself so let's have a look at what we can do to potentially change this so what we have available is a function here setup function so we can utilize this in the other functions here so what we can do instead of creating a new item every single time manually we can just define it once here in the setup so let's go ahead and do that so here i'm going to create a new user or two new users i'm going to create a new post entry and apply the users in that post entry like we did before so what i can do now uh is go ahead and cut out some of this code here potentially so anywhere where it repeats so for example here um we can get rid of that now you'll notice that the title is now django and not django testing so let's just change that so that's what the title is going to equal and potentially we don't need that so let's just go ahead and run this um just run this one test to see if this gets picked up so you can clearly see that that wasn't going to work because we had the yellow underline here so we need to reference the title here like i've done here in order for us to utilize this information in this function so we're just using self.title here so now if we go ahead and run this test we should have a pass run one test everything is okay so i want to show you what's happening here with utilizing setup so all i'm going to do is just copy this twice um i could just tell you but i thought i'd just show you and let's just write here print um and let's just print something um hello on a database uh database creation okay so let's go ahead in the console here and just run the tests again so i should be running two tests here i've called them the same am i um let's just call this one and two so let's just go ahead again and test these so you can see i've run it on the test now and notice that db creation appears twice so this is important to understand that when we utilize setup and we define our testing parameters in this case our model data you can see that's going to be individually created for each test so you can imagine here that if you're running quite a lot of tests here that's going to take quite a lot of time so django does provide a different method so what we can utilize here is the setup test data so if i copy across that so this is set up test data here we're just doing the same thing again referencing across um the title so that we can utilize the data um so here you can see that if i were to run the same situation again so if i do a print again of database test i need to just turn that across let's just run these uh model tests again so number one and number two so hopefully this time when we go ahead and test this we should only make one instance of the table okay sorry i've forgotten the act class method okay so with that in place let's just save that so let's go ahead now in the terminal and run the test again so again so we run the tests and at this time notice that we only get db test one so essentially what's happening here is this data is going to memory and it's just being utilized again for the next test so we aren't actually rebuilding this data okay so now we've gone ahead and i've just refactored everything now into place you can see now we've created created our three tests and it's completely referencing our setup data up the top here so notice the use of self to reference the testing setup data and here for example you can utilize sealed the self send also be careful maybe not a very good naming here of the variable uh title so this isn't essentially the title this is just creating a new instance so this really should just say um new so let's just go ahead and refactor that so here you can see that i've changed it all to new so we're just saying a new record so a new post object create and then go into new and set the likes and so on so if you're not familiar with this type of syntax down here for example we want to get the account of the likes so we go we start with self so that brings us over here to our setup data and then new so now we're inside of the new and inside of new there's a there's likes so we added the likes here in actual fact to it so new and then likes and then we count so we're just counting how many of these items that we have so hopefully that gives you a little bit of an overview of how to set up some simple tests of some very familiar functions and setups you might have within your model so finally for this tutorial we're going to have a look at the model baker or the model bakery so what we need to do is just ins pip install that so go ahead and get that installed so pip install model bakery uh so like i said in the preview or in the introduction this is going to be a tool that's going to auto generate data for us particularly if we've got large data sets because you can see here for example we've only using content slug and new but obviously your tables might be quite large so if you want to replicate a lot of data in your database this is definitely a method of doing that so head over to the top here what we need to do is just import that into our project and once we've done that we can now set something up so let's just build something at the bottom here i'm just going to build a simple class a new class uh i'm just going to call this test new and you can see here what we're doing is um i'm also bringing in a pretty print so um just here so i'll put that in as well so you can see what we're doing here so we're just using the setup again and this time we're using baker to make the data so basically it's going to find this model it's going to look at all the different um model elements um or the the different fields sorry that the model has and it's going to then identify what needs to be placed within it so let's go back to the test so what we're going to do here is just going to print it out so you can see what's happening so this on its own won't work because we're using setup setup's only going to be initiated if we actually run a test on the data so this here is just a a simple setup so you can see that you can actually overwrite the baker so if there is information that you want to type um variably there will be or to add you can add the data yourself but here you can see that i'm just going to return the string so it should say django testing so while this test is set up it's going to use this information and it's going to print out what the baker has made so let's give that a go so this time i'm going to drill down and actually just run this individual test i'm just going to be utilizing manage pi test and then app one test and then model so that's the file and inside of here we've got the class test new so i'm just going to run all the tests or the functions in there so let's just go ahead and do that and you'll see that what's happened here is our baker has made some data and you can see all the data that is built here so the slug and the title and the content and so on so head across to the manual um we'll potentially use this later in later tutorials but i just wanted to show you it is quite a useful tool to have potentially if you want to test the whole data here or you want to utilize the whole data set in your models okay so hopefully you'll agree that's a much better tutorial than the first in this series um i definitely need to look at that and change that um it's definitely not a very good tutorial i do apologize about that there is some information in the first tutorial um that is useful towards the end but it's um very weak to say the least so i do apologize for that so hopefully i made up here in testing the models uh in django um this was an introduction um we've covered quite a lot in this tutorial we have um briefed you on some test organization we've looked at model testing we've gone through the basics that you might find or utilize within your models when you're starting up using django so hopefully now you can apply this or start to apply this in your projects so i hope you see the benefit of having coverage i would definitely be utilizing it later for the views and so on in our testing it is a good tool to um use it almost like a game it tests it shows you where you need to make tests it allows you to kind of think about tests in a way that if you want to kind of drop into testing test some things and go back to development and maybe you see that you do some more testing later it's kind of structured in a way if you do forget something well it's there it's going to show you what you need and then you can play around and try and create more tests and then until you complete the 100 coverage so again hopefully you enjoyed and then the model bakery application will be coming useful for you and thank you very much so hopefully i'll see you in the next tutorial
Info
Channel: Very Academy
Views: 6,859
Rating: 4.9710145 out of 5
Keywords: django testing, django unit test, django and testing, test in django, django tut, django tutorial, django 3, django examples, learn django, django beginners, beginners django, django framework, django 2020, django example, django testing models, django model testing, django, django coverage, django model baker
Id: GBgRMdjAx_c
Channel Id: undefined
Length: 36min 33sec (2193 seconds)
Published: Tue Aug 25 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.