2011-04-27 171 views
2

我正在寫一個包,做我的測試是一個不錯的小程序員,但在這裏會發生什麼:新的類實例未初始化

class TestOne(unittest.TestCase): 
    def setUp(self): 
     self.finder = Finder() 

    def test_default_search_parts(self): 
     self.assertEqual(self.finder.search_parts, []) 

class TestTwo(unittest.TestCase): 
    def setUp(self): 
     self.finder = Finder() 

    def test_add_letter(self): 
     self.finder.add('a') 
     self.assertNotEqual(self.finder.search_parts, []) 
在這種情況下

test_default_search_parts失敗,AssertionError: ['a'] != []test_add_letter通行證。我不知道這裏發生了什麼事。當我重寫test_default_search_parts時會變得很奇怪:

def test_default_search_parts(self): 
    f = Finder() 
    self.assertEqual(f.search_parts, []) 

發生同樣的故障。我在做什麼錯在這裏初始化我的實例?

哦,我用鼻子來運行它們,如果那麼重要。

+0

你可以拋出Finder的代碼嗎?請記住,測試的*順序*不一致或不能保證,所以如果這些實例共享某些全局狀態,可能會以混亂的方式發生嚴重錯誤。 – Henry 2011-04-27 17:50:48

+0

也許'Finder'將'search_parts'存儲爲類級屬性? – samplebias 2011-04-27 17:51:55

+0

@samplebias準確的,我會發佈一個問題的例子。 – Henry 2011-04-27 17:55:15

回答

4

正如@samplebias提到的,在這種情況下,共享狀態與類級別的屬性可能會導致問題。這裏是一個可能的情況下,您有:

import unittest 

# bad implementation of Finder, class-level attribute 
class Finder(object): 
    search_parts = [] 

    def add(self, letter): 
     self.search_parts.append(letter) 


# using 'Zne' here makes sure this test is run second   
class TestZne(unittest.TestCase): 
    def setUp(self): 
     print 'I am run next' 
     self.finder = Finder() 

    def test_default_search_parts(self): 
     self.assertEqual(self.finder.search_parts, []) 


class TestTwo(unittest.TestCase): 
    def setUp(self): 
     print 'I am run first' 
     self.finder = Finder() 

    def test_add_letter(self): 
     self.finder.add('a') 
     self.assertNotEqual(self.finder.search_parts, []) 

unittest.main() 

輸出

Traceback (most recent call last): 
    File "test.py", line 18, in test_default_search_parts 
    self.assertEqual(self.finder.search_parts, []) 
AssertionError: Lists differ: ['a'] != [] 

的問題是所有的搜索實例共享這個類級屬性search_parts,並add_letter被默認搜索測試之前運行。

要解決問題,使用類似:

class Finder(object): 
    def __init__(self): 
     self.search_parts = [] 

這將確保它是實例唯一屬性。

+0

謝謝,這工作。 – 2011-04-27 18:01:59

+1

有關Henry所描述的區別的詳細說明,請參見此問題:http://stackoverflow.com/questions/207000/python-difference-between-class-and-instance-attributes – Wilduck 2011-04-27 18:03:58