Контроль выполнения тестов с помощью pytest
Я рассматриваю возможность преобразования некоторых unittest.TestCase
тестов в Pytest, чтобы воспользоваться преимуществами приспособлений Pytest. Однако одной из особенностей unittest
, которую я не смог легко найти в pytest, является возможность создавать наборы тестов и запускать их. В настоящее время я часто делаю что-то вроде этого:
import unittest
class TestSomething(unittest.TestCase):
def test_1(self):
self.assertEqual("hello".upper(), "HELLO")
def test_2(self):
self.assertEqual(1+1, 2)
if __name__ == "__main__":
suite = unittest.TestSuite()
# suite.addTest(TestSomething('test_1'))
suite.addTest(TestSomething('test_2'))
runner = unittest.TextTestRunner()
runner.run(suite)
Комментируя строки с помощью addTest
, я могу легко выбрать, какие тесты запускать. Как бы я сделал нечто подобное с Pytest?
5 ответов:
Вы можете использовать аргумент
-k
для выполнения определенных тестов. Например# put this in test.py import unittest class TestSomething(unittest.TestCase): def test_1(self): self.assertEqual("hello".upper(), "HELLO") def test_2(self): self.assertEqual(1+1, 2)
Выполнение всех тестов в классе
TestSomething
может быть выполнено следующим образом:py.test test.py -k TestSomething
Работает только
test_2
:py.test test.py -k "TestSomething and test_2"
Еще один способ-использовать специальные имена тестов. Их можно настроить в pytest.ini-файл.
# content of pytest.ini # can also be defined in tox.ini or setup.cfg file, although the section # name in setup.cfg files should be "tool:pytest" [pytest] python_files=check_*.py python_classes=Check python_functions=*_check
Другой способ состоит в том, чтобы принять меры в conftest.py в этом примере используется переменная collect_ignore config. Это список тестовых путей, которые следует игнорировать. В этом примере test_somthing.py всегда игнорируется для сбора. test_other_module_py2.py игнорируется, если мы тестируем с python 3.
# content of conftest.py import sys collect_ignore = ["test_something/test_something.py"] if sys.version_info[0] > 2: collect_ignore.append("test_other/test_other_module_py2.py")
Они были вольно взяты из документации pytest Глава изменение стандартного (Python) обнаружения тестов
Перейти к pytest. Это так мило.
В дополнение к использованию фильтров
-k
, Вы можете назвать конкретные тестовые классы или случаи, которые вы хотите запустить,py.test test.py::TestSomething::test_2
Будет работать только
test_2
Думаю, что лучший способ сделать это-использовать пользовательские маркеры pytest. Вы должны отметить конкретные тесты (которые вы хотите запустить) с помощью
@pytest.mark.mymarkername
И запускать только тесты с пользовательским маркером с помощью команды:
py.test -v -m mymarkername
Здесь вы можете найти дополнительную информацию о маркерах: http://doc.pytest.org/en/latest/example/markers.html
Основываясь на ответеmbatchkarov , поскольку названия моих тестов могут быть довольно длинными, я хотел бы по-прежнему иметь возможность выбирать тесты, комментируя строки и нажимая "Cntrl+B" в Sublime (или "Cntrl+R" с помощью Atom Runner). Один из способов сделать это заключается в следующем:
import unittest import pytest class TestSomething(unittest.TestCase): def test_1(self): self.assertEqual("hello".upper(), "HELLO") def test_2(self): self.assertEqual(1+1, 2) if __name__ == "__main__": tests_to_run = [] # tests_to_run.append('TestSomething and test_1') tests_to_run.append('TestSomething and test_2') tests_to_run = " or ".join(tests_to_run) args = [__file__, '-k', tests_to_run] pytest.main(args)
Идея заключается в том, что поскольку Pytest принимает строковое выражение для соответствия тестам (а не просто список тестов), необходимо создать список выражений, соответствующих только одному тесту, и объедините их с помощью
or
.