2013-03-07 28 views
3

我想爲TestCase派生類的變體創建一個生成器。鼻子:基於TestCase的類的生成器

我想這是什麼:

import unittest 

def create_class(param): 
    class Test(unittest.TestCase): 
     def setUp(self): 
      pass 

     def test_fail(self): 
      assert False 
    return Test 

def test_basic(): 
    for i in range(5): 
     yield create_class(i) 

我得到的是這樣的:

====================================================================== 
ERROR: test_1.test_basic 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/usr/lib/python3.3/site-packages/nose/case.py", line 268, in setUp 
    try_run(self.test, names) 
    File "/usr/lib/python3.3/site-packages/nose/util.py", line 478, in try_run 
    return func() 
TypeError: setUp() missing 1 required positional argument: 'self' 

屈服實例,而不是類(yield create_class(i)())給我留下了這個錯誤:

====================================================================== 
ERROR: test_1.test_basic 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/usr/lib/python3.3/site-packages/nose/case.py", line 198, in runTest 
    self.test(*self.arg) 
    File "/usr/lib/python3.3/unittest/case.py", line 492, in __call__ 
    return self.run(*args, **kwds) 
    File "/usr/lib/python3.3/unittest/case.py", line 423, in run 
    testMethod = getattr(self, self._testMethodName) 
AttributeError: 'Test' object has no attribute 'runTest' 

有什麼建議嗎?

回答

4

當實例化一個TestCase,你應該通過測試的方法名稱:

yield create_class(i)('test_fail') 

否則,該名稱默認爲runTest(因而最後你得到的錯誤)。

另請注意,測試生成器與TestCase之間存在奇怪的相互作用。用下面的代碼:

import unittest 

def create_class(param): 
    class Test(unittest.TestCase): 
     def setUp(self): 
      pass 

     def test_fail(self): 
      print('executed') 
      assert False 
      print('after assert') 

    return Test 

def test_basic(): 
    for i in range(5): 
     yield create_class(i)('test_fail') 

我獲得此輸出:

$ nosetests -s 
executed 
.executed 
.executed 
.executed 
.executed 
. 
---------------------------------------------------------------------- 
Ran 5 tests in 0.004s 

OK 

正如你可以看到測試不會失敗,即使assert作品。這可能是由於TestCase處理了AssertionError這一事實,但nose並不指望這樣處理,因此它不能看到測試失敗。

這可以從TestCase.run的文件中可以看出:

Run the test, collecting the result into the test result object passed as result . If result is omitted or None, a temporary result object is created (by calling the defaultTestResult() method) and used. The result object is not returned to run() ‘s caller.

The same effect may be had by simply calling the TestCase instance. 

所以,nose沒有看到反對由發電機產生是TestCase應在一個特殊的方式來處理,它只是希望一個可調用的。運行TestCase,但結果被放入臨時對象中,並且這會消耗測試中發生的所有測試失敗。因此產生TestCase es根本不起作用。

+0

如果我在'Test'中有多個方法,該怎麼辦?明確地傳遞這些信息似乎是對DRY原則的一大破壞...... – dom0 2013-03-07 21:33:38

+0

@ dom0我認爲你應該仔細閱讀關於[測試生成器]的鼻子文檔(https://nose.readthedocs.org/en/latest/writing_tests.html#test -generators)。你在混合東西。 'TestCase's *不是*被設計用於這種方式,顯然這導致次優代碼。 – Bakuriu 2013-03-07 21:38:03

0

我已經運行您提供的代碼。我沒有收到任何錯誤。我使用的版本是python2.7。系統是ubuntu12.10。也許你需要檢查python2.7。

+0

好吧然後這對我來說似乎是一個錯誤。我使用Python 3.3的鼻子,也許這是問題。我不能(也不想)將項目切換回Python 2.x,所以我只是嘗試解決這個問題的同時...... – dom0 2013-03-07 21:27:48