Python Testing, как запустить параметризованные тестовые случаи и передать параметр в setupClass

У меня есть питонский юнитест. В методе setupClass я так много трудоемких задач... Сам тесты работают очень быстро. Теперь я хотел бы запустить один и тот же Testcase с несколькими наборами параметров. Как мне этого добиться?

Я пробовал разные подходы с nose_parameterized и т. Д., Но там я не могу использовать @parameterized.expand()

import unittest
from nose_parameterized import parameterized


parameters = [('test1', 2 ),('test2', 3)]


class TestParameterizedTestcase(unittest.TestCase):
    @classmethod
    def setUpClass(cls, param=1):
        """
        Do some expensive stuff
        """
        cls.param = param
        print 'Param in setup class  %s'


    def test_is_one(self):
        """
        A fast test
        """
        self.assertEqual(1,self.param)

    def test_is_two(self):
        """
        Another fast test
        """
        self.assertEqual(2, self.param)

    def test_is_three(self):
        """
        Another fast test
        """
        self.assertEqual(3, self.param)

3 ответа

Решение

К сожалению, нет никакого способа создать параметризованные тестовые классы с unittest, nose, или же parameterized,

py.test пример, показывающий, как вы можете создать свой собственный параметризованный тестовый класс, здесь: https://pytest.org/latest/example/parametrize.html

И вы можете создать свой собственный генератор параметризованных классов следующим образом:

class MyTestClassBase(object):
    # Inherit from `object` so unittest doesn't think these are tests which
    # should be run

    @classmethod
    def setUpClass(cls):
        print "doing expensive setup with", cls.param

    def test_one(self):
        self.assertEqual(self.param, 1)


params = [('test1', 1), ('test2', 2)]

for name, param in params:
    cls_name = "TestMyTestClass_%s" %(name, )
    globals()[cls_name] = type(cls_name, (MyTestClassBase, unittest.TestCase), {
        "param": param,
    })

Который будет генерировать новый тестовый класс для каждого параметра.

Вот один из способов сделать это с помощью unittest для полноты, но я предпочитаю ответ Дэвидса.

Импортировать юнит-тест из носа

class TestParameterizedTestcase(unittest.TestCase):
    param =3
    @classmethod
    def setUpClass(cls):
        """
        Do some expensive stuff
        """

        print 'Param in setup class  %s' % cls.param


    def test_is_one(self):
        """
        Some fast test
        """
        self.assertEqual(1,self.param)

    def test_is_two(self):
        """
        Anoter Fast test
        """
        self.assertEqual(2, self.param)

import unittest
from unittest import TestLoader

if __name__ == '__main__':
    for param in range(5):
        suite = unittest.TestSuite()
        loader = TestLoader()
        test = None
        test = TestParameterizedTestcase
        test.param =param

        tests = loader.loadTestsFromTestCase(test)
        suite.addTest(tests)
        unittest.TextTestRunner().run(suite)

Вы можете использовать следующий подход, если у вас есть несколько параметров и вы можете вызывать только метод с этими значениями:

      import unittest
from parameterized import parameterized

def custom_name_func(testcase_func, param_num, param):
    """
    The names of the test cases generated by @parameterized.expand
    :param testcase_func: will be the function to be tested
    :param param_num: will be the index of the test case parameters in the list of parameters
    :param param: (an instance of param) will be the parameters which will be used.
    :return: test case name
    """
    return "%s_%s" % (
        testcase_func.__name__,
        parameterized.to_safe_name("_".join([str(param.args[0]), param_num])),
    )


class SomeTestCase(unittest.TestCase):
    @parameterized.expand([
        ('ex1', 2, 3, 5),
        ('ex2', 2, 5, 7),
        ('ex3', 3, 8, 11)
    ], name_func=custom_name_func)

    def test_add(self, name, a, b, expected):
        self.assertEqual(a + b, expected)

запуск теста вернет:

      python -m unittest /tests/test_one.py -v      
                 
test_add_ex1_0 (tests.test_one.SomeTestCase) ... ok
test_add_ex2_1 (tests.test_one.SomeTestCase) ... ok
test_add_ex3_2 (tests.test_one.SomeTestCase) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.000s
Другие вопросы по тегам