2011-04-27 128 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