Контроль выполнения тестов с помощью 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 2

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.