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 у меня есть утверждение, которое находится в конце функции, а не в возврате, поэтому я не смогу использовать эту функцию в качестве инструмента. Как это сделать? Я знаю, что это не очень хорошая практика, когда мой один тест зависит от другого, но есть ли работа вокруг?
Заранее благодарим за ваши ответы.
Ответы
Ответ 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)