As websites grow they become harder to test manually. Not only is there more to test, but, as interactions between components become more complex, a small change in one area can impact other areas, so more changes will be required to ensure everything keeps working and errors are not introduced as more changes are made. One way to mitigate these problems is to write automated tests, which can easily and reliably be run every time you make a change.
This tutorial shows how to automate unit testing of your website using Django's test framework. The Local Library currently has pages to display lists of all books and authors, detail views for Book and Author items, a page to renew BookInstance s, and pages to create, update, and delete Author items and Book records too, if you completed the challenge in the forms tutorial.The Django Test Driven Development Cookbook - Singapore Djangonauts
Even with this relatively small site, manually navigating to each page and superficially checking that everything works as expected can take several minutes. As we make changes and grow the site, the time required to manually check that everything works "properly" will only grow. If we were to continue as we are, eventually we'd be spending most of our time testing, and very little time improving our code. Automated tests can really help with this problem!
The obvious benefits are that they can be run much faster than manual tests, can test to a much lower level of detail, and test exactly the same functionality every time human testers are nowhere near as reliable! Because they are fast, automated tests can be executed more regularly, and if a test fails, they point to exactly where code is not performing as expected.
In addition, automated tests can act as the first real-world "user" of your code, forcing you to be rigorous about defining and documenting how your website should behave. Often they are the basis for your code examples and documentation.
For these reasons, some software development processes start with test definition and implementation, after which the code is written to match the required behavior e. This tutorial shows how to write automated tests for Django, by adding a number of tests to the LocalLibrary website. There are numerous types, levels, and classifications of tests and testing approaches. The most important automated tests are:. Note: Other common types of tests include black box, white box, manual, automated, canary, smoke, conformance, acceptance, functional, system, performance, load, and stress tests.
Look them up for more information. Testing a website is a complex task, because it is made of several layers of logic — from HTTP-level request handling, queries models, to form validation and processing, and template rendering.
Django provides a test framework with a small hierarchy of classes that build on the Python standard unittest library.Best practices for Django unit and integration tests for models, views, forms, and templates. Testing is an important but often neglected part of any Django project. In this tutorial we'll review testing best practices and example code that can be applied to any Django app. While we might we use a unit test to confirm that the homepage returns an HTTP status code ofan integration test might mimic the entire registration flow of a user.
For all tests the expectation is that the result is either expected, unexpected, or an error. An expected result would be a response on the homepage, but we can--and should--also test that the homepage does not return something unexpected, like a response.
Anything else would be an error requiring further debugging. The main focus of testing should be unit tests. You can't write too many of them. They are far easier to write, read, and debug than integration tests.
They are also quite fast to run. Complete source code is available on Github.
Recommended Django Project Layout
The short answer is all the time! Practically speaking, whenever code is pushed or pulled from a repo to a staging environment is ideal. A continuous integration service can perform this automatically. You should also re-run all tests when upgrading software packages, especially Django itself. By default all new apps in a Django project come with a tests. As projects grow in complexity, it's recommended to delete this initial tests.
Let's create a small Django project from scratch and thoroughly test it. It will mimic the message board app from Chapter 4 of Django for Beginners.
On the command line run the following commands to start our new project. We'll place the code in a folder called testy on the Desktop, but you can locate the code anywhere you choose.
Now update settings. Our Django application only has two static pages at the moment. There's no database involved which means we should use SimpleTestCase. Take a look at the code below which adds five tests for our homepage. First we test that it exists and returns a HTTP status code. Then we confirm that it uses the url named home. We check that the template used is home. It's always good to test both expected and unexpected behavior.
As an exercise, see if you can add a class for AboutPageTests in this same file. It should have the same five tests but will need to be updated slightly.When Django 1. This is a question we get asked all of the time so I wanted to take a bit of time and write down exactly how we feel about this subject so we can easily refer clients to this document.
Note that this was written using Django version 1. Assuming you have two apps blog and users and 2 environments dev and prod your project layout should be structured like this:. The rest of this article explains how to move a project to this layout and why this layout is better. If you kick off your project using django-admin. This layout is a great starting place, we have a top level directory foo which contains our manage.
This is the directory you would check into your source control system such as git. The process to do this is:. So why is this important? Now if your production site is safe from that silly mistake.
What else can you customize? So adjust those settings in each environment file. Using these settings is easy, no matter which method you typically use. Another useful tip with Django settings is to change several of the default settings collections from being tuples to being lists. For example, maybe you only want django-debug-toolbar installed in dev, but not your other environments.
Another useful trick we often use is to break up your apps into two lists, one your prerequisites and another for your actual project applications. So like this:. Why is this useful? For one it helps better distinguish between Django core apps, third party apps, and your own internal project specific applications.
You have a list of your apps, so you can easily and automagically make sure their tests are run and coverage is recorded just for them, not including any third party apps, without having to maintain the list in two separate places. This is sufficient for small simple projects, but a little known feature of requirements files is that you can use the -r flag to include other files. So we can have a base. Why did we separate out the tests files so much?
But that example mainly focus on Django application models test. Django also provide class django. Client for you to test your Django application views.
This example will tell you how to use it. Client behave like a light weight web browser, it provide method for you to send GET or POST request to a url, and then return a django. HttpResponse object. With this HttpResponse object, you can get various information from the response such as response status code, headers, cookies and the response content.
To use django. Client class to implement Django app views test, follow below steps. Now we will also use django. Client in Django project test case class to test application views. To implement this, you do not need to instantiate django. Client class instance, you can use it directly. Your email address will not be published. This site uses Akismet to reduce spam.
Learn how your comment data is processed. Skip to content. Leave a Reply Cancel reply Your email address will not be published.Articles on web-centric development using Python, Django, Flask and ColdFusion, the i2 suite, and custom Intelligence Analysis software.
Get the elapsed running time for individual tests [see part 2]. This should get your tests up and running quickly, so think of it as a starting point I encourage you to do your own research once you find its limitations.
Subscribe to RSS
These are used to test Django views, by simulating a user request. Client tests go through Settings, URL configs and middleware, so they take longer than the simpler request tests technically speaking, they are integration tests. I use those to test authenticated views and form submissions - by setting up some form data and using self. These are tests that use Selenium to simulate a browser session.
Since they are much slower than everything else, they are used only to test more complex user behavior e. This should group logic that is used across test suites, so we can keep our tests DRY:. For more complex applications, you should definitely look into using fixtures, Factory Boy or Mocking or not mocking. The other functions can also be called when needed some tests need the client logged in, for example.
After importing the needed dependencies, class RequestTests TestCase is used to group a test suite and its different methods:. See the Official Django Reference for more details on django. Again, after handling the imports, we group our tests in the ViewTests class:.
I am just being extra-paranoid. Again, we create a class - FunctionalTest - that groups our tests and helper methods:. If you are using Django 1. Important Note: If you run several tests that use LiveServerTestCase or StaticLiveServerTestCase or tests in parallelsuch as the case in the functional tests above, you can pass the test runner a comma-separated list of ports, or a range of ports, to avoid your tests failing due to the Address already in use error:.
See this section of the Django docs for more information. Be sure to read Part 2 to see how to get individual test times. This structure allows developers to: Organize and group different test types unit, integration, functional tests, etc…. Run tests individually, or by group, or all of them. Define logic that is common to all tests e.
WebDriver self.This is the fourth in a series of Django testing posts. Today is the start of a sub-series, which is practical examples. This series will be going through each of the different kinds of tests in Django, and showing how to do them. Instead of picking some contrived models and views, I figured I would do something a little bit more useful.
Everyone loves getting patches, and patches that are tests are a god send. So I figured that I might as well do a tutorial and give back to the community at the same time. It also happens to be the code that powers my blog here, with some slight modifications. So this is a win-win-win for everyone involved, just as it should be. He was gracious enough to allow me to publicly talk about his tests. Usually when I go about testing a Django application, there are 3 major parts that I test.
Models, Views, and Template Tags. Templates are hard to test, and are generally more about aesthetics than code, so I tend not to think about actually testing Templates. This should cover most of the parts of your application that are standard. Of course, if your project has utils, forms, feeds, and other things like that, you can and should probably test those as well! So lets go ahead and take a look to see what the tests used to look like. He has already updated the project with my new tests, so you can check them out, and break them at your leisure.
Notice how he is using reverse when referring to his URLs, this makes tests a lot more portable, because if you change your URL Scheme, the tests will still work. A good thing to note is that a lot of best practices that apply to coding apply to testing too!
Change your preferences any time.
Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. From my understanding testing the whole view in one go seems impossible. We need to distinguish between pre-post and post states of request. But I have no idea how to design this. Is there any real life example? NB NB! This isn't strictly a "unit test"; it's difficult and uncommon to write an independent unit test for Django view code.
This is more of an integration test I tend to test it anyway just in case we've forgotten to use that decorator. I'm not sure the failure case a error page in 2 is what you really want. Depending on how much custom validation you have, 4 may not really need to be tested. Obviously, a drawback here is hard-coded URLs. You could either use reverse in your tests or build requests using RequestFactory and call your views as methods rather than by URL.
With the latter method, though, you still need to use hard-coded values or reverse to test redirect targets. You would also need a test which does a POST and asserts a successful redirect as expected.
Learn more. How to write a unit test for a django view? Ask Question. Asked 7 years, 8 months ago. Active 3 months ago. Viewed 37k times. I have problems understanding how the unit tests should be designed for django. Looking at the documentation the examples are too simplified and only focused on the model. POST if form. Houman Houman Also, the Django docs recommend against if request.
POSTand suggest if request. POSTwhich tests as false and triggers the wrong branch. Thank you for the great tips. Active Oldest Votes. In any case, given all of the above, I would do something like: from django. Hope this helps. Took me a few days to get all these running. Thanks again for your great explanation. Hence the test fails. Its weird how do I test for success then?