doctest redundant mock class instantiations

M

mde

I'm wondering if there is a "best practice" for *creating doctests in
methods* that reduces clutter/duplication of dummy instantiations. In
the following code there are five (labeled 1-5) possible places to put
a
dummy mock instantiation. I have the impression that creating the
dummies in every method is the common practice (1-3), but I'm hoping
otherwise. I've found that creating the dummy down by the testmod
call
obviates the need to do any of the other (1-5) instantiations.

Doctests are written so concisely in *functions* (x6), but they are
tedious in *methods* due the redundant creation of dummies. This
tedium
makes me prefer writing functions over methods, but I hate to
sacrifice on design.

It seems that __init__ is the most intuitive place to put a single
instantiation (#1), but alas, that doesn't work as it's not visible to
#2,3. Next best would be in the module-level docstring (#5); also no
dice. #2,3 are tedious. The #4 approach works okay; is there any
problem with adopting this (#4) approach as a convention? Is there a
better way, to make it more like what's possible in functions?

""" """

class SillyMult(object):
def __init__(self):
""" """
pass
def x2(self, x):
""" 4
"""
return x*2

def x3(self, x):
""" 6
"""
return x*3

def x6(x):
""" 12
"""
return x*6

if __name__ == '__main__':
import doctest
#mockSM = SillyMult() # 4
doctest.testmod()
~
 
S

Steven D'Aprano

I'm wondering if there is a "best practice" for *creating doctests in
methods* that reduces clutter/duplication of dummy instantiations. In
the following code there are five (labeled 1-5) possible places to put a
dummy mock instantiation. I have the impression that creating the
dummies in every method is the common practice (1-3), but I'm hoping
otherwise. I've found that creating the dummy down by the testmod call
obviates the need to do any of the other (1-5) instantiations.

Doctests are written so concisely in *functions* (x6), but they are
tedious in *methods* due the redundant creation of dummies. This tedium
makes me prefer writing functions over methods, but I hate to sacrifice
on design.

It seems that __init__ is the most intuitive place to put a single
instantiation (#1), but alas, that doesn't work as it's not visible to
#2,3. Next best would be in the module-level docstring (#5); also no
dice. #2,3 are tedious. The #4 approach works okay; is there any
problem with adopting this (#4) approach as a convention? Is there a
better way, to make it more like what's possible in functions?

You've missed one: in the class doc string itself:

class SillyMult(object):
"""Object that multiplies in a silly fashion.

SillyMult objects have silly hard-coded methods to multiply
by two:
4

three:
6

and even six:
12

"""
# implementation [snipped]



Personally, I tend to use a combination of approaches. Since doctests
aren't intended for full test coverage, I use *short* tests in methods.
If I can't make a test short, it doesn't go into the method doctest. For
more extensive tests, I put them into the class or even module doctest.

However, short doesn't necessarily mean "one line". In most of my
methods, the docstring is fairly detailed, explaining arguments,
exceptions raised, results returned, with three or four doc tests to
cover the usual cases. Adding an extra line to create a dummy instance is
no hardship.
 
M

Marc 'BlackJack' Rintsch

Personally, I tend to use a combination of approaches. Since doctests
aren't intended for full test coverage, I use *short* tests in methods.
If I can't make a test short, it doesn't go into the method doctest. For
more extensive tests, I put them into the class or even module doctest.

IMHO doctests in docstrings are not for testing the code but for testing
usage examples in the docstrings. So I don't write *tests* there, but
useful examples for the programmer who might have to use that functions
or methods and use the doctest module to check if my examples agree with
the actual implementation.

Ciao,
Marc 'BlackJack' Rintsch
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top