【问题标题】:Python parameterized unittest by subclassing TestCase通过子类化TestCase的Python参数化单元测试
【发布时间】:2015-12-23 05:00:45
【问题描述】:

如何创建多个测试用例并以编程方式运行它们?我正在尝试在一个常见的 TestCase 上测试一个集合的多个实现。

我更愿意坚持使用简单的单元测试并避免依赖。

以下是我查看的一些资源,但并不完全符合我的要求:

这是一个最小(非)工作示例。

import unittest

MyCollection = set
AnotherCollection = set
# ... many more collections


def maximise(collection, array):
    return 2


class TestSubClass(unittest.TestCase):

    def __init__(self, collection_class):
        unittest.TestCase.__init__(self)
        self.collection_class = collection_class
        self.maximise_fn = lambda array: maximise(collection_class, array)


    def test_single(self):
        self.assertEqual(self.maximise_fn([1]), 1)


    def test_overflow(self):
        self.assertEqual(self.maximise_fn([3]), 1)

    # ... many more tests


def run_suite():
    suite = unittest.defaultTestLoader
    for collection in [MyCollection, AnotherCollection]:
        suite.loadTestsFromTestCase(TestSubClass(collection))
    unittest.TextTestRunner().run(suite)


def main():
    run_suite()


if __name__ == '__main__':
    main()

上述方法在loadTestsFromTestCase中出现错误:

TypeError: issubclass() arg 1 must be a class

【问题讨论】:

    标签: python unit-testing python-3.x inheritance python-unittest


    【解决方案1】:

    pytest with to parametrize fixture怎么样:

    import pytest
    
    MyCollection = set
    AnotherCollection = set
    
    
    def maximise(collection, array):
        return 1
    
    @pytest.fixture(scope='module', params=[MyCollection, AnotherCollection])
    def maximise_fn(request):
        return lambda array: maximise(request.param, array)
    
    def test_single(maximise_fn):
        assert maximise_fn([1]) == 1
    
    def test_overflow(maximise_fn):
        assert maximise_fn([3]) == 1
    

    如果这不是一个选项,您可以制作一个 mixin 来包含测试函数,并创建一个子类来提供maximise_fns:

    import unittest
    
    MyCollection = set
    AnotherCollection = set
    
    
    def maximise(collection, array):
        return 1
    
    
    class TestCollectionMixin:
        def test_single(self):
            self.assertEqual(self.maximise_fn([1]), 1)
    
        def test_overflow(self):
            self.assertEqual(self.maximise_fn([3]), 1)
    
    
    class TestMyCollection(TestCollectionMixin, unittest.TestCase):
        maximise_fn = lambda self, array: maximise(MyCollection, array)
    
    
    class TestAnotherCollection(TestCollectionMixin, unittest.TestCase):
        maximise_fn = lambda self, array: maximise(AnotherCollection, array)
    
    
    if __name__ == '__main__':
        unittest.main()
    

    【讨论】:

    • 很好,mixin 的想法是完美的。有点重复,但很清楚。
    • CPython 测试套件使用 mixin 方法来测试,例如,C 和 Python 实现,或者,例如,对多个类通用的测试,例如 unicode 和字节或元组和列表(以及偶数范围)或集合和冻结集合。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-04
    • 1970-01-01
    • 2022-12-17
    • 1970-01-01
    • 2014-01-20
    • 2016-05-28
    • 1970-01-01
    相关资源
    最近更新 更多