I decided to add some tests to my frisor application, so that my Travis CI could actually be useful. Testing web applications is very annoying for me, I’m not sure what I should test. There are some methods or views, which are really simple and I don’t feel it’s possible to write a meaningful test for them. Anyway, as I played more with tests in my side project frisor (more about it here: Introduction to frisor) here are some of my thoughts.
Where are my tests?
My requirements for testing framework were at least:
- tests are in
testssubdirectory in my application
- having more than one file with tests
- readable output with summary
In Django there is a builtin testing engine which does test discovery (so finds tests
locations) and runs tests. It uses
unittest library for running tests.
To run tests use
manage.py script with command
test. When none of your tests will be
found, there can be a few reasons of it:
Running manage.py from invalid location
If you are running
manage.py from invalid location, tests may not be run.
For example: I was running it from as
$ python frisor/manage.py test,
so not in place where
manage.py is located. There are two ways of fixing it:
- use your application name (but it tests only for this application),
in my case:
$ python frisor/manage.py test frisor_urls
manage.pywhen being in place where it is located, so:
$ python manage.py test
Subdirectory for tests should be a python package
If you are using
tests subdirectory it’s possible that you forgot to make it
Python package - this subdirectory has to contain
__init__.py file as it defines a package.
Tests have a naming convention
All tests names should start from
test_ prefix to be found. If there are no tests
found, check if they are named properly and if your test class
How to do something for all tests in class?
Let’s say we want to have a default variables or do some actions before for each test,
for example I wanted to use the same url for POST requests in all tests
It can be done using two strategies:
- running some method before each test
- running some method before all tests (once)
Usually using the first one is better, because tests will be independent from each other. When using the second one approach, there might appear some dependency between tests - you should avoid it at all costs! When tests are dependent on each other, they can’t be run in parallel, they are also much harder to debug.
Doing something before each test
setUp method can help you set up variables before each test,
so before every test you can have a fresh instance of variables -
is run before each test.
Here I added
setUp method where I define
url_add_url variable. I can use
it in all my tests to create a POST request to that url. It will be easy to change
it in the future.
Of course there is also a method which runs after each test, it’s
Doing something before all tests
Sometimes you want to do something before all tests in your test class.
For example I wanted to create some urls for testing list view of urls
To achieve this it’s enough to implement
setUpClass method, but you have to remember
classmethod, not an instance method. It will be run before class
instance creation. For example:
In example above I’m creating some urls before running other tests in
tearDownClass is run after all tests in test class are run.
There are also similar methods for whole modules (
You can find my tests in my frisor github: firsor tests.