On Mon, Nov 11, 2013 at 09:58:06AM +0100, Tarek Ziadé wrote:
Interesting... what if we could mark a block of tests like this :
# implementation of sum
asserts: assert sum() == 0 assert sum([1, 2, 3]) == 6
... ..more complicated testing here...
I often spell that:
if __debug__: assert sum() == 0
# more complicated testing here
I've been playing around with doctest, and I think it may be useful to have a "check" decorator that you use like this:
@check def spam(): """Return spam.
>>> spam() 'spam spam spam' """ return ' '.join(['spam']*3)
If the doctests pass, the function is returned unchanged, otherwise an exception is raised. Note that this will encourage a specific style of more limited tests focused on just one function at a time. Normally, doctests aren't run until after the entire module is loaded, which lets you do things like this:
def spam(): """Return spam.
>>> spam() 'spam spam spam' Like ham, but more tasty: >>> taste(spam()) > taste(ham()) True """ return ' '.join(['spam']*3)
# definitions of taste and ham follow later in the module.
That won't work with a check decorator, since at the time the decorator runs, the functions taste and ham don't exist. The same would apply to a "where" clause (or whatever name it is given).
This forces the doc tests to be more tightly focused on the function in isolation, which would be both good and bad. The good is that it would discourage overloading the docstring with too many too complex tests. The bad is that it would limit what can be tested this way, and the errors would no doubt be confusing to beginners. "What do you mean NameError? taste is defined right there..."
On balance, I think that such a check() decorator would be useful enough that it's worth my time writing it. (Perhaps not useful enough to include in doctest, but I'll certainly stick it in my own personal toolbox.) But I don't think it would be useful enough to make it syntax.