简体   繁体   English

如何在Python(2.7)单元测试中参数化setUpClass()

[英]How to parametrize setUpClass() in Python (2.7) unittests

I am currently implementing a kind of table with interpolation between the values, boundary handling, etc. and want to write unit tests for it. 我目前正在实现一种在值,边界处理等之间进行插值的表,并希望为其编写单元测试。

There is quite a set of possible scenarios eg the tables could have only one/multiple row(s)/column(s) and different boundary conditions. 存在很多可能的场景,例如,表可能只有一个/多个行/列和不同的边界条件。 The tables in all of these scenarios should all pass the same set of unittests. 所有这些方案中的表都应通过相同的单元测试集。

For now I am writing a base class for one of the cases and derive from it overriding the setUpClass() method. 现在,我正在为其中一种情况编写基类,并从中派生重写setUpClass()方法。 This is however tedious for testing all combinations. 然而,这对于测试所有组合而言是乏味的。

Is there to generate the TestCase classes dynamically run them with different parameters. 是否可以生成TestCase类,并使用不同的参数动态运行它们。

When googling for the problem the best thing I found was overloading load_tests() and add all test methods one by one (which means setting up the objects prior to running each test method instead of once per scenario). 搜索该问题时,我发现最好的事情是重载load_tests()load_tests()添加所有测试方法(这意味着在运行每个测试方法之前先设置对象,而不是每个场景一次)。

Thanks to the hint from @jonrsharpe I managed to do it. 感谢@jonrsharpe的提示,我设法做到了。

My solution is to create the classes dynamically and then add them to the TestSuite using load_tests : 我的解决方案是动态创建类,然后使用load_tests将它们添加到TestSuite中:

def create_test_case(testcase_name, scenario_data):
    class ScenarioTestCase(BaseTestCase):
        @classmethod
        def setUpClass(cls):
            cls.fillClassVariables(scenario_data)
    return_class = ScenarioTestCase
    return_class.__name__ = testcase_name #for separating the results
    return return_class


def load_tests(loader, tests, pattern):
    list_scenario_names = [...]
    list_scenario_data = [...]

    loader = unittest.TestLoader()
    tests = TestSuite()
    for scenario_name, scenario_data in zip(list_scenario_names, list_scenario_data):
        tests.addTests(loader.loadTestsFromTestCase(
            create_test_case(scenario_name, scenario_data)))
    return tests

This way the TestCases are created dynamically with different parameters and listed separately in PyCharm's Test Runner Tab. 这样,可以使用不同的参数动态创建TestCases,并在PyCharm的“ Test Runner”选项卡中单独列出。

Though this has an accepted answer, I want to document how to do this with subclassing, since it took me a long time to find the details of such a solution. 尽管这是一个可以接受的答案,但是我想记录一下如何使用子类化,因为花了我很长时间才能找到这种解决方案的细节。 In my case, the goal is for a TestCase class with several methods to have a class fixture (setting up files on the filesystem to test a cli tool), and vary this slightly in the parametrization. 在我的案例中,目标是使TestCase类使用几种方法具有类固定装置(在文件系统上设置文件以测试cli工具),并在参数化方面稍有不同。

# Inherit from object to not run this abstract class
class TemporaryFolderClassSetup(object):

    @classmethod
    def setUpClass(cls):
        try:
            cls._root = tempfile.mkdtemp()
            # .. create some files here ...
            # allow subclasses to manipulate file tre
            cls.prepare_directory(cls._root)
        except Exception as e:
            cls.tearDownClass()
            raise

    @classmethod
    def tearDownClass(cls):
        shutil.rmtree(cls._root)

    @classmethod
    def prepare_directory(cls, root):
        pass

    # test methods that will run in each subclass
    def testX():
        pass

# scenariotest, must inherit from superclass first, before unittest.TestCase)
class ScenarioTests(TemporaryFolderClassSetup, unittest.TestCase):

    # ... called by parent class
    @classmethod
    def prepare_directory(cls, root):
        pass

    # test only for this scenario
    def testY(self):
        pass

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM