Подтвердить что ты не робот

Unittest Vs pytest

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

class test_class(unittest.TestCase):
    def setUp(self):        
        self.varA = 1
        self.varB = 2
        self.varC = 3
        self.modified_varA = 2

    def test_1(self):
        do_something_with_self.varA, self.varB

    def test_2(self):
        do_something_with_self_modified_varA, self.varC

Таким образом, в unittest легко было собрать вместе множество тестов, которые могли бы проходить под одним классом, а затем использовать множество разных переменных (varA и varB) для разных методов. В pytest я создал приспособление в conftest.py вместо класса в unittest, как это...

@pytest.fixture(scope="module")
def input1():
    varA = 1
    varB = 2
    return varA, varB

@pytest.fixture(scope="module")
def input2():
    varA = 2
    varC = 3
    return varA, varC

Я передаю этот вход 1 и input2 в мои функции в другом файле (скажем, test_this.py) для двух разных функций. Вот вопросы, основанные на информации выше...

  • Так как я не могу просто объявлять локальные переменные в conftest.py, так как я не могу просто импортировать этот файл. Есть ли лучший способ объявления различных переменных здесь, которые могут использоваться в разных функциях в test_this.py? У меня есть пять различных конфигураций в моем фактическом тестировании для этих переменных, определяющих, что много разных приборов в conftest.py и использовать их как аргумент функции в пяти различных функциях в test_this.py звучит болезненно, я скорее вернусь к unittest структуре класса, определит мои переменные и выбрать и выбрать то, что я хочу

  • Должен ли я просто объявлять глобальные переменные в test_this.py и использовать их в функциях так, как я хочу? Кажется немного не питоническим. Эти переменные используются только в этом файле.

  • Скажем, у меня есть test_that.py и test_them.py. Если у меня есть общие переменные между этими разными файлами, как я могу их объявить? просто создайте файл calle variables.py в каталоге, где находятся все эти тестовые файлы, и выполняйте импорт, когда мне нужно? Таким образом, я могу хранить все данные отдельно.

  • Является ли мое впечатление, что pytest препятствует использованию класса для организации ваших функций? Каждый пример, который я читал в Интернете, все это, кажется, использует набор функций только с приборами. Какова конфигурация определения класса и методов и организации тестов в pytest?

  • У меня есть тестовый сценарий, где я должен использовать результат одной функции в другой. С pytest у меня есть утверждение, которое находится в конце функции, а не в возврате, поэтому я не смогу использовать эту функцию в качестве инструмента. Как это сделать? Я знаю, что это не очень хорошая практика, когда мой один тест зависит от другого, но есть ли работа вокруг?

Заранее благодарим за ваши ответы.

4b9b3361

Ответ 1

1) Прежде всего вы можете объявить эти светильники не только в conftest.py, но и в каждом модуле python, который вам нужен. И вы можете импортировать этот модуль. Также вы можете использовать приборы так же, как вы использовали метод setUp:

@pytest.fixture(scope='class')
def input(request):
    request.cls.varA = 1
    request.cls.varB = 2
    request.cls.varC = 3
    request.cls.modified_varA = 2

@pytest.usefixtures('input')
class TestClass:

def test_1(self):
    do_something_with_self.varA, self.varB

def test_2(self):
    do_something_with_self_modified_varA, self.varC

или вы можете определить отдельные переменные в отдельных светильниках:

def fixture_a():
    return varA

def fixture_b():
    return varB

def fixture_c():
    return varC

def fixture_mod_A():
    return modified_varA

или сделать одно приспособление, которое возвращает все переменные (почему бы и нет?) или даже сделать косвенное параметризированное приспособление, которое возвращает переменные по вашему выбору (довольно запутанный способ):

@pytest.fixture()
def parametrized_iput(request):
   vars = {'varA': 1, 'varB': 2, 'varC': 3}
   var_names = request.param
   return (vars[var_name] for var_name in var_names)

@pytest.mark.parametrize('parametrized_iput', [('varA', 'varC')], indirect=True)
def test_1(parametrized_iput)
   varA, varC = parametrized_iput
   ...

Или даже вы можете сделать приспособление factory, которое сделает вам светильники на лету. Звучит любопытно, когда у вас всего 5 тестов и 5 конфигураций переменных, но когда вы получаете сотни из них, это может быть полезно.

3) Конечно, вы можете. Но я рекомендую вам не импортировать этот файл напрямую, а использовать параметр командной строки, указывающий, какой файл нужно импортировать. В этом случае вы можете собрать еще один файл с переменными без изменения кода.

4) Я использую классы в своих тестах, потому что я перешел из nosetest. Я не упоминал о проблемах с использованием классов в pytest.

5) В этом случае я предлагаю вам сделать следующее: кулак выполняет функцию с желаемыми действиями:

def some_actions(a, b):
    # some actions here
    ...
    return c

то используйте его как в тесте, так и в приспособлении:

def test():
    assert some_actions(1,2) == 10

@pytest.fixture()
def some_fixture():
     return some_actions(1,2)