[TIP] RFF: Article on python test design pattern - DAI

exarkun at twistedmatrix.com exarkun at twistedmatrix.com
Tue Dec 8 07:30:50 PST 2009


On 03:13 pm, olemis at gmail.com wrote:
>On Tue, Dec 8, 2009 at 9:55 AM,  <exarkun at twistedmatrix.com> wrote:
>>On 04:07 am, amax at redsymbol.net wrote:
>>>
>>>(that's Request For Feedback)
>>>
>>>Hi everyone,
>>>
>>>Here is a draft article about a useful design pattern for Python code
>>>tests:
>>>
>>>http://redsymbol.net/articles/deep-assertion-injection/
>>>
>>>I am surely not the first to use this idiom, but I *might* be the 
>>>first to
>>>document it this well, and to give it a name.  Have you seen this 
>>>before?
>>>Constructive feedback is appreciated.
>>>
>>>Thanks in advance for your comments.  Either reply here on the list, 
>>>or by
>>>email to amax at redsymbol.net.
>>
>>Hi Aaron,
>[...]
>>
>>This has the shortcoming that it's harder to use the failure to 
>>pinpoint the
>>exact code which is wrong, though.  It'd be nice to have some tools to 
>>make
>>it easy to combine the advantages of each of these approaches. For 
>>example,
>>a non-exception based failure signaling mechanism,
>
>Hmmmm ... if something failed in your (unit)tests then it should be an
>exception condition (considering unittest philosophy and | or style
>since you write «positive» test cases i.e. conditions that have be
>asserted in to make the TC pass) . Isn't it ?

I don't know.  I'd rather discuss practicalities and then determine the 
consequences of those for philosophies or styles.
>>or a stack capturing
>>helper which allows for easy annotation of later assertions.
>
>Little comment :
>
>Modules that contain __unittest = True are hidden in failure
>tracebacks . Is this what you 'r talking about ?

Nope.  Consider this modified version of one of the snippets from the 
essay:

    def __init__(self, rel_url, urlopen=urlopen):
        '''rel_url is the HTTP URL of the resource, relative to the 
server urlopen is the function to open the URL'''
        url = 'http://{}/{}'.format(self.server, rel_url)
        try:
            self.resource = urlopen(url)
        except:
            # Blah blah blah
            self.resource = another_opener(url)

This isn't the best example of what I'm talking about, since there's 
probably no good reason to have a bare except here, but one could 
imagine other scenarios where it's less unreasonable (catch-all error 
handling around an application-supplied function, for example, which 
logs the exception rather than allowing it to disrupt execution).

With this version of the code, the exception raised by the failing 
assertion goes nowhere, and the test does not fail (or at least does not 
fail in the "right" way).

Jean-Paul



More information about the testing-in-python mailing list