Two years on, and I still love the combination of tox and Travis. I still write changes to my tox.ini and .travis.yml files separately, despite having written a tool for this. It occurred to me yesterday that there was a better way of writing this now - since tox now has a command for listing out what environments are set up (something which I think didn’t exist when I wrote the original Python script).
I love tox - it’s a great tool for checking that your Python packages are installable, and that you support all the various configurations of Python versions and other package versions that you think you do. It’s also quite a neat way of checking your documentation builds properly, and that your code remains PEP 8 compliant1. I also love Travis, since it helps me accomplish much the same thing as tox, but does so in an automated way, with every push.
Yesterday, I found two bugs whilst looking at a code coverage report. I tend to think that shooting for 100% code coverage adds unnecessary overheard - often the last few percent doesn’t give you much benefit, and takes a disproportionate amount of time to reach, but it’s useful to at least understand why particular lines of code aren’t hit by your tests. Perhaps those lines are dead code, or perhaps - as was the case for me yesterday - it’s because your code is broken.
A long while ago, I discovered that running Django tests is much faster if you use SQLite, and if you turn off South (this now seems pretty obvious, but at the time was a bit of a revelation to me). Since then, I’ve come across a better way of setting this up, to avoid having a test_settings.py: # If manage.py test was called, use SQLite import sys if 'test' in sys.
I started with unit testing about 4 years ago. I started writing what were probably integration tests, when I was working on the database backend of our application. The tests I wrote were designed to make sure that our process which saved data actually saved data. Saving data involved creating a document, calling save on it, which would save it in the file system-based database, which would hit the file system.
I’d basically given up on attempting test-driven with Django, given the project I’m currently working on uses models with a lot of South migrations. Just building the database and running the migrations could take a minute or so when running manage.py test, and resetting the database to a clean state meant the test suite would take several minutes to run. I’ve had an idea in the back of my mind for a while, and today I finally got around to making it work.