Есть хороший шаблон для скриптов: вы пишете их тесты прямо в скрипте. Это позволяет обойти любые проблемы с импортом и просто отправлять код и тесты вместе.
Этот подход отлично работает, если у вас есть только простые тесты:
def my_production_function(x): if x > 0: return x+1 else: raise Exception("Negative") ### TESTS HERE def test_1(): assert my_production_function(1) == 2
Но что мы не можем импортировать что-либо связанное с тестами в верхний уровень модуля. Может быть, этот код будет работать в среде, где у нас нет pytest. С простыми тестами все просто: у вас просто есть неиспользуемая функция (test_1 и т. д.), которая игнорируется при обычном выполнении кода. Если вы пишете import pytest
в начале файла, у вас должен быть запущен pytest, что странно.
Но, допустим, вы хотите проверить свою функцию на наличие исключений. Как? Мой старый подход заключался в том, чтобы импортировать pytest внутри теста:
def test_0(): import pytest pytest.raises(Exception): my_production_function(0)
Все было в порядке… пока не пройдет один или два теста. Если у вас их больше, множественный импорт замедляет работу и выглядит некрасиво.
Сегодня я нашел красивое решение. Посмотри на это!
def setup_module(): global pytest import pytest def test_0(): with pytest.raises(Exception): my_production_function(0) def test_negative(): with pytest.raises(Exception): my_production_function(-1)
Хитрость заключается в setup_module
, где вы можете иметь глобальные переменные (верхнего уровня). А модуль - это переменная! Pytest запускает setup_module
перед запуском тестов, поэтому он импортирует модуль pytest. Это аккуратный трюк в стиле pytest.