2013-06-26 134 views
0

我有一個對象名單調用蟒蛇測試

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

    def method2(self): 
     print 'method2' 

    def method3(self): 
     print 'method3' 

和功能

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

我想要寫的測試,測試do_something和的OBJ對象。 如何接收在obj上調用的方法列表而不替換(嘲笑)並改變obj行爲?

喜歡的東西

['method2', 'method1', 'method3'] 
+0

(1)使用測試框架; (2)'[getattr(obj,name)()for name namelist]' – Marcin

+0

是的。我使用測試框架,我只是調用'do_something()'。我如何獲得'obj'對象的函數調用列表? –

+0

是否可以定義一個通用包裝類,以便每個對象都可以被包裝?就像'obj = Obj()'然後'x = Wrapper(obj)' – Brian

回答

1

使用trace包。見文檔:http://docs.python.org/2/library/trace.html

從文檔:

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=".") 
+0

你能舉一個例子來說明如何使用trace來跟蹤單個對象的調用嗎?看起來似乎需要什麼,但我從來沒有用過痕跡,現在我很好奇。 – Brian

+0

在文檔中有一個例子。 – Marcin

+0

這不區分特定類的不同實例。 – Brian

1

您可以創建一個通用的Wrapper類將封裝的對象,並跟蹤更改。

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) 

通過重新定義__getattr__我們使所有屬性訪問在包裝上,以獲取在被包裝對象的屬性。通過以上的定義,我可以做到以下幾點:

>>> 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'] 

可以進一步提高Wrapper__getattr__滿足您的需求。 (記錄方法調用的時間戳,記錄輸出,記錄到數據庫等)

+0

爲什麼你會這樣做,當你可以避免改變你的代碼?您只是重新實現了標準功能。 – Marcin

+0

因爲它符合OP描述的需求,所以它是高度模塊化的,它有7行代碼... – Brian