调用load_tests()时的奇怪行为

时间:2012-08-22 22:50:14

标签: python unit-testing

在Python 2.7中使用新发现功能时,我遇到了一个奇怪的错误。我有一些单元测试,需要一些额外的设置和文件中的一些成员数据。我正在尝试将我的设置测试用例添加到传递给load_tests()的当前测试套件中。但是因为测试套件tests已经包含标准测试(包括当前模块中的TestCase个对象),所以没有完成自动添加的测试用例的正确设置,我得到了一个AttributeError。

在下面的代码中,load_tests()用于为csv文件中的每行数据创建一个测试用例。该文件有三行,但由于某种原因,正在创建第四个测试用例。

#!/usr/bin/python
import unittest

class Foo(unittest.TestCase):    
    def setup(self,bar):
        print "Foo.setup()"
        self.bar = bar 
    def runTest(self):
        print self.bar

def load_tests(loader, tests, pattern):
    f = open('data.csv')  # data.csv contains three lines: "a\nb\nc"
    for line in f:
        tc = Foo()
        tc.setup(line)
        tests.addTest(tc)
    return tests

unittest.main()

当我执行此代码时,输​​出显示执行了4个测试,其中一个失败。数据文件只包含三行,Foo.setup()仅调用三次。所以load_tests()按照设计创建了三个测试用例。

Foo.setup()
Foo.setup()
Foo.setup()
Ea

.b

.c

.
======================================================================
ERROR: runTest (__main__.Foo)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./foo.py", line 11, in runTest
    print self.bar
AttributeError: 'Foo' object has no attribute 'bar'

----------------------------------------------------------------------
Ran 4 tests in 0.002s

有没有办法删除套件中自动加载的TestCase?我无法创建一个新的空TestSuite,因为我需要已经存在的所有其他测试。我只想将这些测试添加到套件中。

编辑:澄清了我的问题和代码示例。我以前有点暧昧。

2 个答案:

答案 0 :(得分:0)

有几种方法可以做到这一点。

如果你总是要实例化Foo,你可以在班级的__init__方法中设置吧。

class Foo(unittest.TestCase):
    def __init__(self, bar, *args, **kwargs):
        super(Foo, self).__init__(*args, **kwargs)
        self.bar = bar
    def runTest(self):
        print self.bar

f = Foo("some string")

我之前没有直接使用load_tests模式 - 我通常只依赖于nose的自动测试发现,但所有这些都可以用于您的设置。如果您以后想要使用TestSuiteunittest / nose的测试自动发现,并希望使用类,则可以使用类工厂:

def make_foo_case(the_bar):
    class Foo(unittest.TestCase):
        bar = the_bar
        def runTest(self):
            print self.bar
    return Foo

f = (make_testcase("some string"))()

或使用type继承foo并在成员中设置元素(基本上与前一个相同),例如:

class Foo2(object):
    def runTest(self):
        print self.bar

f = (type("Tester2", (Foo2,unittest.TestCase), {"bar":"some string"}))()

答案 1 :(得分:0)

显然我误解了load_tests()。根据{{​​1}}中的Python代码,测试从模块正常加载。然后,如果存在/usr/lib/python2.7/unittest/loader.py,也会调用它。

load_tests()

所以我想我的解决方案是接受创建的额外测试用例,检查它,然后传递它。非常感谢Jeff试图帮助我。