DocSix: Doctests on Python 2 & 3
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.