Python:制作全局单元测试功能

时间:2017-09-18 14:55:19

标签: python unit-testing

我想创建一个可以在脚本中的其他单元测试中使用的函数。这就是我的意思:

class TestSomething(unittest.TestCase):
    def __init__(self, title, description):
        self.title = title
        self.description = description
        self.tag = 'ts'

class TestSomething2(unittest.TestCase):
    def __init__(self, title, description):
        self.title = title
        self.description = description
        self.tag = 'ts2'

class TestWhatever(unittest.TestCase):
    def test_whatever(self):
        blah = TestSomething('Happy Gilmore', 'golf movie')
        AttributeCheck(blah, 'Happy Gilmore', 'golf movie', 'ts')

class TestWhatever2(unittest.TestCase):
    def test_whatever(self):
        blah = TestSomething2('Toy Story', 'kids movie')
        AttributeCheck(blah, 'Toy Story', 'kids movie', 'ts2')

class AttributeCheck(unittest.TestCase):
    def __init__(self, element, title, description, tag):
        super(AttributeCheck, self).__init__()
        self.assertEqual(element.title, title)
        self.assertEqual(element.description, description)
        self.assertEqual(element.tag, tag)

    def runTest(self):  # this is what causes problems
        print 'ok'


if __name__ == '__main__':
    unittest.main()

我得到的错误是:TypeError: __init__() takes at least 3 arguments (2 given)它基本上试图运行AttributeCheck,我认为它运行runTest就好像它是一个测试。但是,我需要def runTest(self):因为如果我没有它,那么我会得到:ValueError: no such test method in <class 'AttributeCheck'>: runTest

1 个答案:

答案 0 :(得分:2)

您以前所未见的方式使用unittest.TestCase,我认为与documentation不一致。我的回答使用TestCase我通常如何使用它,希望它能回答你的问题。

至于具有可在脚本中的多个测试中使用的函数,您可以向测试类中添加一个函数来检查您。如果它没有&#34;测试&#34;在名称中,它不会作为测试运行:

class TestWhatever(unittest.TestCase):
    def test_whatever_does_something(self):
        instance = Whatever('Happy Gilmore', 'golf movie', 'ts')
        self._check_attributes(instance, 'Happy Gilmore', 'golf movie', 'ts')

    def _check_attributes(self, element, title, description, tag):
        self.assertEqual(element.title, title)
        self.assertEqual(element.description, description)
        self.assertEqual(element.tag, tag)

这不是非常有用,因为您的检查方法仅限于此类。如果你愿意,可以将它导入另一个测试类,但就责任分离而言,这有点混乱。

我通常尝试为每个测试文件设置一个测试类,对应于一个生产类。每个测试&#39;是测试类中的方法。然后,如果我想要从很多测试类中运行一个函数,我将它放在一个单独的文件中,我称之为&#34; test_helpers.py&#34;。你不应该让你的测试助手从TestCase继承。您可以定义失败异常并从测试助手方法中提升它。

以下代码将分成同一目录中的5个单独文件。文件名在注释中。请注意,班级Blah生活在&#39; blah.py&#39;并对应test_blah.py中的测试类TestBlah。那是你用Blah测试一切的地方。

我直接从source code for unittest偷走了test_helpers.py中的FailureException代码。

#blah.py
class Blah(object):
    def __init__(self, title, description, tag):
        self.title = title
        self.description = description
        self.tag = tag

#test_blah.py
from test_helpers import check_attributes

class TestBlah(unittest.TestCase):
    def test_constructor(self):
        blah = Blah('Happy Gilmore', 'golf movie', 'ts')
        check_attributes(blah, 'Happy Gilmore', 'golf movie', 'ts')

#sub_blah.py
from blah import Blah

class SubBlah(Blah):
    def __init__(self, title, description, tag):
        super(SubBlah, self).__init__()
        self.different_attribute = "I'm Different!"

#test_sub_blah.py
from test_helpers import check_attributes

class TestSubBlah(unittest.TestCase):
    def test_constructor(self):
        sub_blah = SubBlah('Toy Story', 'kids movie', 'sb')
        check_attributes(blah, 'Toy Story', 'kids movie', 'sb')
        self.assertEqual("I'm Different!", sub_blah.different_attribute)

#test_helpers.py
import Exception

def check_attributes(element, title, description, tag):
    if not title == element.title:
            raise FailureException(msg or '%r != %r' % (title, element.title))
        if not description == element.description :
            raise FailureException(msg or '%r != %r' % (description, element.description))
        if not tag == element.tag:
            raise FailureException(msg or '%r != %r' % (tag, element.tag))

class FailureException(Exception):
    #pass here to make it a basic exception
    pass

    #If you  need custom code, you can override __init__
    #def __init__(self, message, errors):
    #
    #   super(FailureException, self).__init__(message)