Test-first development workflow in Django
Writing tests as you write code is good strategy for writing clean code and building stable product. In this post I'll give a quick overview of my Django development workflow.
Doctests
Let's assume we're working on simple blog-like web application and we want to add search form. We will start with doctests and then incrementally refactor to unit tests:
-
First we think about search interface. Search form is simple text field with optional submit button. Users submit search query to some URL where we capture and validate query, filter posts and return results. Simple.
-
Next we write simple doctests for testing searching interface:
Copy and paste code into tests.py file of core app. Run test with ./manage.py test core:
Oops! Test failed. Django was not able to find URL named search. This is good because we know exactly what to do: URL pattern for searching.
-
Add following line to urls.py:
Run tests again:
Test failed again. But, just like before, we know what is missing: search view in blog.core module.
Let's run tests again:
We have green testing bar! Now let's implement actual search.
-
Remember: test first! Create couple of posts in testing database and write test:
Of course, test are red now:
It's time to revisit our searching code:
-
Simple post searching can be implemented using filter method:
And tests are green again!
In a nutshell: (1) write simple test for URL availability, (2) add URL patterns in urls.py and view function, (3) test trivial case and, (4) add more tests, (5) refactor implementation ...
Unit tests
Doc tests are fine for small projects. For larger projects you should switch to unit testing. Unit test are real code (doctests are code too, but in form of one large string hard to refactor and debug). Tests from this post can be refactored to Unit tests easily:
Conclusion
Good practice is writing tests while writing code (or better, before) and running tests before pushing changes to repository. My workflow forces me to think about interface first, write simple test and incrementally implement functionality. Developing using this methodology improves programming process and code quality while building test suite that is always available for validating code base consistency and improving programmer's self confidence. There's more to testing than just writing tests: fixtures, regression testing, mocking, browser/gui testing... Stay tuned..