15

A fellow developer on a project I am on believes that doctests are as good as unit-tests, and that if a piece of code is doctested, it does not need to be unit-tested. I do not believe this to be the case. Can anyone provide some solid, ideally cited, examples either for or against the argument that doctests replace the need for unit-tests?

Thank you -Daniel

EDIT: Can anyone provide a reference showing that doctesting should not replace unit-testing?

daniel
  • 2,568
  • 24
  • 32
  • 4
    http://stackoverflow.com/questions/361675/python-doctest-vs-unittest – naivnomore Apr 15 '10 at 02:11
  • "I do not believe this to be the case." Why not create or find a class that's too complex for doctests? Why rely of belief when you can create an example that makes your point? – S.Lott Apr 15 '10 at 02:19
  • @iama, thanks for the link. I didn't see that when posting. @S.Lott, we are in the process to show proof to the developer – daniel Apr 15 '10 at 14:28
  • "provide a reference"? Do you mean 'provide an example'? Please revise that Edit if you only want an example? If not, what kind of 'reference" are you looking for? – S.Lott Apr 16 '10 at 01:21

6 Answers6

23

I (ab)used doctest in lieu of unittest, back when I started my gmpy project many years ago -- you can browse its sources and see that all the functionality is thoroughly tested with doctests (the functionality's supplied by a C-coded Python extension, and last time I instrumented it for coverage measurement I was over 95% coverage). Why did I do that? Because doctest was brand new, as was gmpy, and I was curious to see how far I could push it.

Answer: very far indeed -- but definitely not worth it (the novelty wears off, but you don't want to rewrite all your tests, which is why gmpy's tests are still all-doctests). The extreme fragility of doctests, where even the tiniest typo fix in a message breaks the test, is a real bother when they're being abused this way. It's kind of like traditional integration tests based on comparing output with a "golden" (known-good) expected output: easy to write the first time around, but you'll repent at leisure after a few years of fixing gratuitous test breakages;-).

If you find unittest's style onerous, there are other excellent alternatives that are still meant for use in unit tests, such as py.test and nose -- doctest is really meant for a different purpose (supporting docs, not generic unit tests) and while it's of course worth adding whatever doctests you've written for docs purposes to your test battery, it's not worth the test-maintenance headaches of replacing unit tests with it.

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • 1
    That's not to mention that doctests don't actually test the output of a function. They test the *repr()* of the output of the function. Sometimes the string form of an object is lossy compared to what a normal `==` or `assertEqual` would test, leading to a test that passes when it shouldn't. The string form can also have unimportant differences, like dict keys being in a different order than expected. – asmeurer Jan 09 '20 at 00:47
  • 1
    "They test the repr() of the output of the function." True, but you can do this instead to simulate assertEquals: `>>> result == expected` followed by `True` – pandichef Jul 13 '20 at 19:51
6

There really is no arguments for or against doc tests. They are simply tests. In fact as of python 2.4 there is a way to create unit test suits from your doctests: http://docs.python.org/library/doctest.html#unittest-api

In a sense you can think of doc-tests as a subset of unit tests, at least from the functional point of view.

However python docs suggest using doctests for things like:

  • examples in documentation
  • regression testing
  • writing tutorial documentation

Their argument is that if you write your tests within the documentation you will be forced to write both better docs and tests. As opposed to when you write unit tests separately - you rarely add sufficient documentation, and they tend to stagnate and go out of date.

See: http://docs.python.org/library/doctest.html#soapbox

I imagine doctests would be harder to write for things like integration testing. However, as you can see on python and Django - they make extensive use of doctests, which yields much more understandable documentation and tutorials.

It all depends on your project. There is no "right" way to test.

Also I recommend taking a look at Code Complete 2 book, as you may find that unit-testing is not the best way to make sure your software is fault free.

Andriy Drozdyuk
  • 58,435
  • 50
  • 171
  • 272
  • The intent of this question was not to be either for or against doctests, but whether doctests can replace unittests. I personally do not think this to be the case, but I was curious about others opinions. Code Complete 2 is a great book and I recommend that every developer read it. Again though, the goal of this question was not how to make software bullet proof. – daniel Apr 15 '10 at 19:01
  • Well, like some of the other people pointed out they CAN replace unit-tests but with some pains. Personally for me writing code within one big commented-out string is what doesn't jive. On the other hand - you could do anything you wanted to with doctests that you could do with unittests. – Andriy Drozdyuk Apr 16 '10 at 04:33
5

There's a concrete example in the Python standard library that persuades me that doctests alone aren't always enough, namely the decimal module. It has over 60000 individual testcases (in Lib/test/decimaltestdata); if all those were rewritten as doctests, the decimal module would become very unwieldy indeed. It's possible the number of tests could be slimmed down whilst still giving good coverage, but many of the numerical algorithms are sufficiently complicated that you need huge numbers of individual tests to cover all possible combinations of branches.

Mark Dickinson
  • 29,088
  • 9
  • 83
  • 120
  • 1
    It is possible to write your doctests in a separate file. It can reside anywhere and just needs sys.path reference for import of the file/module under test. – Steen Apr 15 '10 at 19:07
4

doctests are great for some uses

  • working and up to date documentation
  • sample tests embeded in docstrings
  • spikes or design phases when classes API is not really clear

unit tests are better in differents cases:

  • when you need clear and somewhat complex setup/teardown
  • when trying to get better coverage of all cases, inclusinf corner cases
  • for keeping tests independant from each other

In other words, at least for my own use, doctests are great when you focus on explaining what you are doing (docs, but also design phases) but more of a burden when you intent to use tests as a seat belt for refactoring or code coverage.

kriss
  • 23,497
  • 17
  • 97
  • 116
  • Can you cite a reference on this by chance? – daniel Apr 15 '10 at 19:05
  • @daniel: it's from personnal use of both kind of tests in projects I worked in. Hours spent fixing tests after refactoring and so on. Whar kind of reference are you seeking ? blog entries ? – kriss Apr 16 '10 at 04:29
  • 1
    Most satisfying answer in my point of view. Makes it clear where each tool makes sense to be used. – dnk8n Jan 08 '20 at 07:28
0

I think this is the wrong way to think about doctests. Doctests are documentation. They complement regular unit tests. Think of doctests as documentation examples that happen to be tested. The doctests should be there to illustrate the function to human users. The unit tests should test all the code, even the corner cases. If you add doctests for corner cases, or dozens of doctests, that will just make your docstring hard to read.

asmeurer
  • 86,894
  • 26
  • 169
  • 240
  • 2
    You can add corner-cases as a testfile, e.g. doctest.testfile("example.txt"). But for example mocking a database, etc would be difficult to do in doctest so that kind of corner case is better done with unit tests. – dnk8n Jan 08 '20 at 07:35
0

It is possible to implement a complete unit test suite with doctests. However, doctests are a bit limited and it's usually better to reserve that for simple documentation examples, and use a more robust unit test framework (eg. unittest) for the real, detailed unit tests.

Another advantage of unittest is that the test framework will be familiar to somebody coming from a different development environment that uses JUnit, NUnit, or similar. The doctest module is a little different.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • We currently have a mixture of doctest and unittest, and have absolutely no intention of going all for one or the other. Our doctests are there to show examples and to enforce that the documentation and code are in sync, the unittests to actually exercise all of the code. The developer believes that if a doctest is written, there does not need to be unittests for the same code. The last point is where I disagree – daniel Apr 15 '10 at 19:08