简体   繁体   中英

List of functions calls in python tests

I have an object

class Obj:
    def method1(self):
        print 'method1'

    def method2(self):
        print 'method2'

    def method3(self):
        print 'method3'

and function

def do_something():
    obj = Obj()
    obj.method2()
    obj.method1()
    obj.method3()

And I want to write test which tests do_something and Obj object. How can I receive list of methods which was called on obj without replacing (mocking) and changing obj behavior?

Something like

['method2', 'method1', 'method3']

Use the trace package. See docs: http://docs.python.org/2/library/trace.html

From the docs:

import sys
import trace

# create a Trace object, telling it what to ignore, and whether to
# do tracing or line-counting or both.
tracer = trace.Trace(
    ignoredirs=[sys.prefix, sys.exec_prefix],
    trace=0,
    count=1)

# run the new command using the given tracer
tracer.run('main()')

# make a report, placing output in the current directory
r = tracer.results()
r.write_results(show_missing=True, coverdir=".")

You can create a generic Wrapper class which will encapsulate your object and track changes to it.

class Obj:
    def method1(self):
        print 'method1'

    def method2(self):
        print 'method2'

    def method3(self):
        print 'method3'

class Wrapper:
    def __init__(self, wrapped):
        self.calls = []
        self._wrapped = wrapped
    def __getattr__(self, n):
        self.calls.append(n)
        return getattr(self._wrapped, n)

By redefining __getattr__ we cause all attribute accessing on the wrapper to retrieve the attribute in the wrapped object. With the above defined I can do the following:

>>> obj = Obj()
>>> x = Wrapper(obj)
>>> x.calls
[]
>>> x.method2()
method 2
>>> x.method1()
method 1
>>> x.method3()
method 3
>>> x.calls
['method2', 'method1', 'method3']
>>> x.method1()
method 1
>>> x.method1()
method 1
>>> x.calls
['method2', 'method1', 'method3', 'method1', 'method1']

You can further improve __getattr__ in Wrapper to fit your needs. (record timestamps for the method calls, record output, log to a database, etc.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM