Djangocon: Switching from nose to py.test at Mozilla - Mathieu Agopian

Tags: django, djangocon, python

(One of the summaries of a talk at the 2015 Djangocon EU conference).

Mathieu Agopian likes py.test much more than regular python unittests or nose.

A bit of terminology.

  • A test is a piece of code written to assert that another piece of code is behaving as expected.

  • Test runner: gathers test and runs them.

  • Test suite (or “a built”): full collection of tests to run.

py.test is already quite old and it is now maintained by a big team. One of the handy features is tests written without boilerplate. assert 1 + 1 == 2 works! No need for self.assertEquals(). There is a plugin system. Like nose, it doesn’t show output if the test runs OK.

If a test fails, py.test provides awesome error reports. “This item misses from the second dict” instead of only showing the two dicts, for instance.

Test fixtures are done via dependency injection: you just pass a fixture to the test function. No need for testSetup() and testTeardown().

You can run the same test with multiple parameters.

Plugins? For instance pytest-django, which runs createdb for you. pytest-cache is another good one. It allows you to run the tests with the --lf, “last failed”, option. It skips all tests apart from the ones that failed previously. Very useful.

pytest-django: look at the --reuse-db option, this speeds up the tests a lot. You can make it the default value, too and re-enable it with a --create-db option.

Why should you change to py.test? py.test is pythonic. You can just use a simple assert. There’s no camelCasing like self.assertEqual().

py.test is also better maintained (but see the correction below). When he made the slides, py.test had 7 open issues and nose had 313.

(Correction: Holger Krekel, py.test author, tweeted afterwards that there are much more than 7 issues in py.test… Turns out the bitbucket query was wrong, there are 7 “open” issues, but “open” + “new”, that are currently 302 issues.)

If you change, you often don’t need to change much. py.test supports existing unittests, for instance.

A model railway at the 2015 'ontraxs' exhibition in Utrecht logo

About me

My name is Reinout van Rees and I work a lot with Python (programming language) and Django (website framework). I live in The Netherlands and I'm happily married to Annie van Rees-Kooiman.

Weblog feeds

Most of my website content is in my weblog. You can keep up to date by subscribing to the automatic feeds (for instance with Google reader):