ASPN ActiveState Programmer Network  
ActiveState, a division of Sophos
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups
Submit Recipe
My Recipes

All Recipes
All Cookbooks


View by Category

Title: decorator for doctests
Submitter: Ben Hayden (other recipes)
Last Updated: 2008/03/30
Version no: 1.0
Category: Debugging

 

Not Rated yet


Description:

This "tested" decorator assigns decorated_function.test() to call doctest.run_docstring_examples appropriately.

Source: Text Source

def tested(fun=None, pre=None, post=None, verbose=False, globs=None):
    ''' 
        >>> def my_pre(): print "this will be printed before running tests"
        ... 
        >>> def my_post(): print "this will be printed after running tests"
        ... 
        >>> @tested(pre=my_pre, post=my_post, verbose=True)
        ... def foo():
        ...     """ 
        ...         >>> foo()
        ...         True
        ...     """
        ...     return True
        >>> foo.test()
        this will be printed before running tests
        Finding tests in foo
        Trying:
            foo()
        Expecting:
            True
        ok
        this will be printed after running tests
    '''
    from sys import _getframe
    from doctest import run_docstring_examples
    
    if globs is None:
        globs = _getframe(1).f_locals
    if fun:
        def test():
            if callable(pre):
                pre()
            run_docstring_examples(fun, globs=globs, verbose=verbose, name=fun.__name__)
            if callable(post):
                post()
        fun.test = test
        return fun
    else:
        return lambda fun: tested(fun, pre=pre, post=post, verbose=verbose, globs=globs)
tested = tested(tested, verbose=True)

Discussion:

You can't debug all of your functions at once. It makes no sense to run all of a module's doctests at once. You just want to run one function's doctests, tweak it, rinse and repeat until that function passes, then move on to another function, rinse and repeat until your whole application.
Known issues include head aches while trying to understand the implicit recursion in "tested.test()".



Add comment

Number of comments: 1

why use caller's locals as globals?, Edward Loper, 2008/04/02
What benefit do you get from using the caller's locals as globals for the tests? If anything, it seems like the default should be to use the decorated function's globals (i.e., fun.func_globals).
Add comment



Highest rated recipes:

1. A simple XML-RPC server

2. Web service accessible ...

3. IPy Notify

4. Changing return value ...

5. Quantum Superposition

6. Pickle objects under ...

7. Generalized delegates ...

8. Reorder a sequence (uses ...

9. Setting Win32 System ...

10. ObjectMerger




Privacy Policy | Email Opt-out | Feedback | Syndication
© 2006 ActiveState Software Inc. All rights reserved.