Last post we talked about how to set up and use doc tests inside of Django.Today, in the second post of the series, we’ll be talking about how to usethe other testing framework that comes with Python, unittest. unittest is axUnit type of testing system (JUnit from the Java world is another example)implemented in Python. It is a much more robust solution for testing than Doctests, and allows for a lot more organization of code. We’ll get into that inthe next post in the series, comparing unit and doc tests.
Essentially, Django’s core test runner class, DiscoverRunner, can now optionally use Python’s logging framework. This is useful for customizing its output, or for testing custom runner subclasses and making assertions on its output. Thanks to Chris Jerdonek and Daniyal Abbasi for the contributions in Ticket #32552. Thanks to Ahmad Hussein.
- This is a custom test runner for Django that gives you.really. colorful test output.
- Django 2.2 documentation. Django.test.runner; Getting help FAQ Try the FAQ — it's got answers to many common questions. Index, Module Index, or Table of Contents Handy when looking for specific information. Django-users mailing list Search for information in the archives of the django-users mailing list, or post a question.
- The default database construction mostly follows Django’s own test runner. You can however influence all parts of the database setup process to make it fit in projects with special requirements. This section assumes some familiarity with the Django test runner, Django database creation and pytest fixtures.
So we’re going to assume that you are picking up after the previous post inthis series. If so, you should have a basic tests directory, with an__init__.py
and a doctst.py
file inside of it. Today we are going towrite some very basic unit tests, and figure out how to wire those into yourexisting test suite.
Writing your first unit test¶
Making a unit test is a lot like making a Python class. As per usual, theDjango docs have lots of great information and examples. They will showyou how to do some easy stuff with your Django models. This tutorial willmostly be about how to use unit tests inside Django, regardless of the dataat hand. So let’s start with a very basic unit test.:
This is a very basic unit test. You will notice it is just a normalPython class. You create a class that inherits from unittest.TestCase. Thistells unittest that it is a test file. Then you simply go in and define somefunctions (Note: they need to start with test so that unittest will runthem), in which you assert some conditions which are true. This allows you alot more flexibility in the tests.
Now if you try to run these tests, you will again not see them showingup in your output! You need to go into your __init__.py
in your testsdirectory. It should now look like the following (assuming you followed part1 of this series):
Unit tests are a lot easier to import than doctests. You simply do a from<filename>import<testnames>
. I named my unit test file unittst.py
,and Python will import that from the current directory. You are importing thetest classes that you defined in your file. So I could have as easily putfromunittestimportTestBasic
and it would work. Using the import*
syntax allows us to add more tests to the file later and not have to edit it.
You can go ahead and run your tests, and see if they’re being properlyimported.:
Awesome!
A couple neat features¶
There are some neat things you can do with basic unit tests. Below I’ll showan addition to the above file, which is another test class, with a bit morefunctionality.:
Here you see that you can define a docstring for the tests. These are usedwhen you are running the tests, so you have a human readable name. You’llalso notice that I’ve used some more assertions. The Python docs have afull list of assertions that you can make. The setUp
and tearDown
methods are run before and after every test respectively. This allows you toset up a basic context or environment inside of each of your tests. This alsoinsures that each of your tests do not edit the data that other tests dependon. This is a basic tenet of testing, that each test should stand alone, andnot affect the others.
Django Custom Test Runner Free
This also seems like a good time to explicitly say that all of your testclasses and files should start with test! If not, they will not be run! Ifyou have a test not running and everything else looks right, this is probablyyour problem. Also note that they cannot be named the same thing! These willoverwrite one another with the last one being imported into the file running.It is generally a good practice to name your tests something that is certainto be unique. I generally tend to follow whatever naming convention I’ve usedfor my named url patterns.
When you go ahead and run your tests, you should see one that fails (the lastone).:
Django Unit Test
You can see the value of unit tests here. Each test is run seperately, so youget a nice human readable error message when it breaks. You can go ahead andmake that test pass (self.assertFalse(self.a2)
). You get an OK fromyour tests, and we can go on our merry way.
Django Custom Test Runners
Now you can see for yourself that there are a lot of differences between Doctests and unit tests. They each serve their own purpose, and in the next postin this series I will talk about when you should use each. Unit tests requirea little bit more up front effort; you can’t just paste something out of yourPython shell and have it work. However, they give you a lot more flexibility.