Log in

No account? Create an account

Django doctest coverage

After reading Siddharta Govindaraj's blog post titled "Code coverage for your Django code", I was able to obtain coverage report from my Django app's unittest.

Unfortunately, Siddhi's setup doesn't handle doctest.

After some research (Google) and development (ebuilds), I was able to obtain coverage report from my Django app's doctest.

I will try to document what I did in a distro-neutral way. But if you use Gentoo, you'll be having a much easier time.

  1. I made some ebuilds. You can get them from my Portage overlay.
    • python

      I applied Zope.testing's doctest patch, to enable doctest to report coverage.

      My version: =dev-lang/python-2.4.4-r5

      Both django-0.96 and python-2.4.4 distribute doctest. They're different. I tried patching Django's doctest, but I got no doctest coverage.

    • coverage

      Ned Batchelder's coverage module.

      Fetch and install in Python path (in my case, /usr/lib/python2.4/site-packages/).

      My version: =dev-python/coverage-2.6

    • colorize

      Sébastien Martini's cookbook recipe for "Generating Code Coverage HTML Output".

      Fetch and install in Python path (in my case, /usr/lib/python2.4/site-packages/)

      My version: =dev-python/colorize-1.5

    • django

      I added the "new" python, coverage, and colorize to django's runtime dependencies (${RDEPEND}).

      I patched Django django/test/simple.py:run_tests() according to Siddhi's article. I renamed coverage_color to colorize and added one line so run_tests() will generate coverage report.

      My version: =dev-python/django-0.96-r1

  2. I keyworded these packages: Append /etc/portage/package.keywords with the following lines:
  3. I merged these packages: emerge django. Portage took care of merging the "new" django's dependencies.
  4. Added doctests all over my app.
  5. Add a testcase in app.tests that runs doctests

    django-0.96 only run tests found in app.models and app.tests. I want my doctest to be near my code (some of which are not in app.models nor app.tests). So, in my app.tests, I added a unittest TestCase which run doctests of other modules.

    def testDocStrings(self):
        import doctest
  6. Followed Siddhi's instructions from step 9 onwards.
  • submit all these upstream.
  • colorize.py is in UTF-8. Explicitly tell Python about it.
  • colorize and coverage ebuilds should write their setup.py, instead of relying on ${FILESDIR}. Might use seemant's trick in writing settings.py in django ebuild's src_test().
  • QA on colorize and coverage (some bash strings needs to be quoted).
  • QA on names of patches.
  • coverage have tests. The ebuild should run them.



Nice. I've never used doctest. How would you say it compares with unittest?

Re: Nice

How would you say it compares with unittest?

I like doctest better than unittest.

I like my tests to be as close to my code as possible.

I haven't found a way to do that using unittest in Django. They're all in tests/__init__.py, one God-class with various test* functions.

Doctest allowed me to put my tests very close to the chunk of code that is being tested.

DISCLAIMER: I am still very inexperienced with respect to "agile" practices. So I might think I'm doing "agile" when I'm not.