2010-08-31 33 views
9

我有一組測試用例,都應該完成相同的測試,沿着「方法x返回現有文件的名稱?」的行。如何將測試方法添加到一組Django TestCase派生類?

我認爲最好的方法是從TestCase派生出來的基類,它們都共享,並且簡單地將測試添加到該類中。不幸的是,測試框架仍然試圖對基類進行測試,但沒有任何意義。

class SharedTest(TestCase): 
    def x(self): 
     ...do test... 

class OneTestCase(SharedTest): 
    ...my tests are performed, and 'SharedTest.x()'... 

我想在一個檢查,以破解簡單地跳過測試,如果它被稱爲基類對象上,而不是派生類是這樣的:

class SharedTest(TestCase): 
     def x(self): 
      if type(self) != type(SharedTest()): 
       ...do test... 
      else: 
       pass 

,但得到這個錯誤:

ValueError: no such test method in <class 'tests.SharedTest'>: runTest 

首先,我想要這樣做的任何優雅的建議。其次,雖然我不想使用type()入侵,但我想了解爲什麼它不起作用。

+0

@jivanamara:有一種方法可以避免超類測試方法被計數_and_在沒有'if getattr(...)'檢查的情況下編寫測試方法。看到我的答案的第二個更新。 – 2010-09-01 15:45:57

回答

1

我遇到過類似的問題。我無法阻止正在執行的基類中的測試方法,但我確保它沒有執行任何實際的代碼。我通過檢查屬性並在設置後立即返回。這個屬性只是爲Base類設置的,因此除了基類之外,其他地方的測試都運行了。

class SharedTest(TestCase): 
    def setUp(self): 
     self.do_not_run = True 

    def test_foo(self): 
     if getattr(self, 'do_not_run', False): 
      return 
     # Rest of the test body. 

class OneTestCase(SharedTest): 
    def setUp(self): 
     super(OneTestCase, self).setUp() 
     self.do_not_run = False 

這是一個黑客。有 大概 更好的方法做到這一 但我不知道如何

更新

由於sdolan says一個mixin是正確的方式。爲什麼我以前沒有看到?

更新2

這將是很好,如果(1)超類方法能夠避免的hackish if getattr(self, 'do_not_run', False):檢查(閱讀評論後); (2)如果測試數量準確計數。

有一種可能的方法來做到這一點。 Django選取並執行tests中的所有測試類,無論是tests.py還是帶有該名稱的軟件包。如果測試超類之外被聲明爲測試模塊,那麼這將不會發生。它仍然可以被測試類繼承。例如SharedTest可以位於app.utils然後由測試用例使用。這將是上述解決方案的更清晰版本。

# module app.utils.test 
class SharedTest(TestCase): 
    def test_foo(self): 
     # Rest of the test body. 

# module app.tests 
from app.utils import test 
class OneTestCase(test.SharedTest): 
    ... 
+0

因爲你沒有問過這個問題:) – sdolan 2010-08-31 07:05:44

+0

這就是我提出問題後編寫的。這有點破解,但pylint更喜歡它,我沒有看到它比mixin差得多。唯一不利的一面是它增加了一個不存在的測試計數......這不會讓我在晚上保持身材。 – JivanAmara 2010-09-01 09:18:19

+0

因爲我對mixin的哲學不是很熟悉,所以我把它從朋友那裏拿走了,他證實了我的遺憾;說mixin應該是獨立的。由於mixin解決方案使mixin依賴於將使用它的類,因此我將使用此解決方案。 – JivanAmara 2010-09-01 09:41:25

22

你可以通過利用使用混入了測試運行僅運行測試從unittest.TestCase繼承例如(其中Django的TestCase繼承。):

class SharedTestMixin(object): 
    # This class will not be executed by the test runner (it inherits from object, not unittest.TestCase. 
    # If it did, assertEquals would fail , as it is not a method that exists in `object` 
    def test_common(self): 
     self.assertEquals(1, 1) 


class TestOne(TestCase, SharedTestMixin): 
    def test_something(self): 
     pass 

    # test_common is also run 

class TestTwo(TestCase, SharedTestMixin): 
    def test_another_thing(self): 
     pass 

    # test_common is also run 

欲瞭解更多關於爲什麼這個作品搜索python方法解析順序和多重繼承。

+0

+1。這是乾淨利落的方式。 – 2010-08-31 04:54:57

+0

感謝您的回覆, 我是這樣開始的,不喜歡我有一個叫做方法的類,它沒有。 Pylint也吠叫了這一點,我大量使用pylint。 – JivanAmara 2010-08-31 05:38:12

+0

@jivanamara:你不需要在你的'TestOne'和'TestTwo'測試類中調用'test_common'。它是「混合在一起」的,因爲它是通過多重繼承而成爲班級的一部分。 – sdolan 2010-08-31 06:17:16

相關問題