I was first introduced to doctests working on Zope 3 at early PyCon sprints. At the time the combination of documentation, specification, and test in a single document seemed pretty interesting to me. These days I like to use them for testing my documentation.
Last week stvs2fork helpfully opened a pull request for Rebar, fixing some syntax that’s no longer valid in Python 3. I decided that it’d be interesting to add Python 3.3 to the automated test runs. Fixing the code to work with Python 3 was easy enough, but when I ran the doctests I discovered an issue I hadn’t thought of:
Unicode string output looks different in Python 3 vs Python 2..
>>> validator = AgeValidator() >>> validator.errors({'age': 'ten'}) {'age': [u'An integer is required.']}
This example works exactly the same in Python 2 and 3: in both cases the error messages are returned as a list of Unicode strings. But in Python 2 the output has the leading u indicator. Not so in Python 3.
What I needed to do is strip the Unicode indicator from the output strings before executing the test; then I’d have the Python 3 doctest I needed. So I wrote a tool that lets me do that.
DocSix lets you run your doctests on Python 2 and 3.
DocSix builds on Manuel, a library for mixing custom test syntax into doctests. DocSix can work with existing uses of Manuel, or it can load your doctests into a unittest TestSuite, ready to go:
from docsix import get_doctest_suite test_suite = get_doctest_suite( 'index.rst', 'advanced.rst', )
Potentially useful links:
- DocSix git repository
- DocSix documentation
- Rebar uses DocSix with the Django test runner; see run_tests.