У pytest в чому полягає використання файлів conftest.py?


217

Я нещодавно виявив pytest. Це здається чудовим. Однак я вважаю, що документація може бути кращою.

Я намагаюся зрозуміти, для чого призначені conftest.pyфайли.

У моєму (на сьогоднішній день невеликому) тестовому наборі я маю один conftest.pyфайл у корені проекту. Я використовую його для визначення світильників, які я ввожу в свої тести.

У мене є два питання:

  1. Це правильне використання conftest.py? Чи є це в інших сферах використання?
  2. Чи можу я мати більше одного conftest.pyфайлу? Коли я хотів би це зробити? Приклади будуть оцінені.

Загалом, як би ви визначили мету та правильне використання conftest.pyфайлів (файлів) у тестовому наборі py.test?


9
Ви були у менеIt seems great. However, I feel the documentation could be better.
користувач9074332

7
Так, документація може бути набагато кращою. Я шукав всю документацію pytest conftest.pyі хоча є багато посилань на те, що робити це чи робити це з конфіденційним файлом, ніде в документації ніколи не вказується, що коли pytest робить тестове виявлення, всі файли conftest.py знайдені (в межах Структура каталогів, над якою проводиться виявлення тесту) буде запускатися під час фази збору тестів (до запуску будь-яких тестів). Довелося розібратися в цьому через експерименти.
Даніель Голдфарб

Відповіді:


288

Це правильне використання conftest.py?

Так. Світильники є потенційним і поширеним використанням conftest.py. Світильники, які ви визначите, поділяться між усіма тестами у вашому тестовому наборі. Однак визначення світильників у корені conftest.pyможе бути марним, і це уповільнить тестування, якщо такі світильники використовуються не у всіх тестах.

Чи є це в інших сферах використання?

Так.

  • Світильники : Визначте кріплення для статичних даних, використовуваних тестами. До цих даних можна отримати доступ до всіх тестів у наборі, якщо не вказано інше. Це можуть бути як дані, так і помічники модулів, які будуть здані на всі тести.

  • Завантаження зовнішніх плагінів : conftest.pyвикористовується для імпорту зовнішніх плагінів або модулів. Визначивши наступну глобальну змінну, pytest завантажить модуль і зробить його доступним для його тестування. Плагіни - це, як правило, файли, визначені у вашому проекті або в інших модулях, які можуть знадобитися у ваших тестах. Ви також можете завантажити набір заданих плагінів, як пояснено тут .

    pytest_plugins = "someapp.someplugin"

  • Гачки : Ви можете вказати гачки, такі як методи встановлення та вилучення та багато іншого для покращення тестів. Про набір доступних гачків читайте тут . Приклад:

    def pytest_runtest_setup(item):
         """ called before ``pytest_runtest_call(item). """
         #do some stuff`
  • Шлях коріння тесту : це трохи прихована функція. Визначившись conftest.pyз вашим кореневим шляхом, ви будете pytestрозпізнавати свої додатки без уточнення PYTHONPATH. У фоновому режимі py.test модифікує ваш sys.path, включаючи всі підмодулі, що знаходяться з кореневого шляху.

Чи можу я мати кілька файлів conftest.py?

Так, ви можете, і настійно рекомендується, якщо ваша структура тесту є дещо складною. conftest.pyФайли мають область каталогу. Тому створення цільових світильників та помічників є хорошою практикою.

Коли я хотів би це зробити? Приклади будуть оцінені.

Кілька випадків можуть відповідати:

Створення набору інструментів або гачків для певної групи тестів.

root / mod / conftest.py

def pytest_runtest_setup(item):
    print("I am mod")
    #do some stuff


test root/mod2/test.py will NOT produce "I am mod"

Завантаження набору світильників для одних тестів, але не для інших.

root / mod / conftest.py

@pytest.fixture()
def fixture():
    return "some stuff"

root / mod2 / conftest.py

@pytest.fixture()
def fixture():
    return "some other stuff"

root / mod2 / test.py

def test(fixture):
    print(fixture)

Буде надруковано "деякі інші речі".

Переважаючі гачки, успадковані від кореня conftest.py.

root / mod / conftest.py

def pytest_runtest_setup(item):
    print("I am mod")
    #do some stuff

root / conftest.py

def pytest_runtest_setup(item):
    print("I am root")
    #do some stuff

Запустивши будь-який тест всередині root/mod, друкується лише "Я мод".

Більше про це можна прочитати conftest.py тут .

Редагувати:

Що робити, якщо мені потрібно викликати звичайні допоміжні функції з ряду тестів у різних модулях - чи вони мені будуть доступні, якщо я поміщу їх у conftest.py? Або я повинен просто помістити їх у модуль helpers.py та імпортувати та використовувати його у своїх тестових модулях?

Ви можете використовувати conftest.pyдля визначення своїх помічників. Однак слід дотримуватися загальної практики. Помічники можна використовувати як світильники принаймні в pytest. Наприклад, в моїх тестах у мене є помічник з макетом Redis, який я ввожу в свої тести таким чином.

root / helper / redis / redis.py

@pytest.fixture
def mock_redis():
    return MockRedis()

root / тести / речі / conftest.py

pytest_plugin="helper.redis.redis"

root / тести / речі / test.py

def test(mock_redis):
    print(mock_redis.get('stuff'))

Це буде тестовий модуль, який ви можете вільно імпортувати у своїх тестах. Зверніть увагу, що ви потенційно можете назвати redis.pyтак, conftest.pyніби ваш модуль redisмістить більше тестів. Однак ця практика не рекомендується через неоднозначність.

Якщо ви хочете скористатися conftest.py, ви можете просто покласти цей помічник у свій корінь conftest.pyта ввести його, коли потрібно.

root / тести / conftest.py

@pytest.fixture
def mock_redis():
    return MockRedis()

root / тести / речі / test.py

def test(mock_redis):
    print(mock_redis.get(stuff))

Ще одна річ, яку ви можете зробити, це написати плагін, який можна встановити. У такому випадку ваш помічник може бути записаний де завгодно, але для цього потрібно визначити точку входу, яку слід встановити у вашій та інших потенційних тестових рамках. Дивіться це .

Якщо ви не хочете використовувати світильники, ви, звичайно, можете визначити просту помічницю і просто використовувати звичайний старий імпорт там, де це потрібно.

корінь / тести / помічник / redis.py

class MockRedis():
    # stuff

root / тести / речі / test.py

from helper.redis import MockRedis

def test():
    print(MockRedis().get(stuff))

Однак тут можуть виникнути проблеми з контуром, оскільки модуль не знаходиться в дочірній папці тесту. Ви повинні мати можливість подолати це (не перевірено), додавши __init__.pyсвого помічника

root / тести / помічник / __ init__.py

from .redis import MockRedis

Або просто додати допоміжний модуль до свого PYTHONPATH.


я стикаюся з ситуацією, коли мій перший модульний тестовий модуль test_aaaaa.pyнасправді намагається запустити до завершення налаштування кріплення conftest.py. Будь-які думки щодо того, чому це може статися?
user9074332

Без conftest.py ваш тестовий корінний шлях не додається до sys.path, і ви побачите помилки типу "ModuleNotFoundError: Немає модуля з назвою" foobar "".
Cale Sweeney

11

У широкому значенні conftest.py - локальний плагін для кожної каталогу. Тут ви визначаєте конкретні каталоги та кріплення для конкретних каталогів. У моєму випадку є кореневий каталог, що містить конкретні каталоги тестів для проекту. Деякі поширені магії розміщуються в "root" conftest.py. Конкретний проект - у власних. Не можу побачити нічого поганого в зберіганні світильників у conftest.py, якщо вони не використовуються широко (У такому випадку я вважаю за краще їх безпосередньо визначати у тестових файлах)


10

Я використовую conftest.pyфайл для визначення світильників, які я ввожу в свої тести, це правильне використання conftest.py?

Так , зазвичай кріплення використовується для отримання даних, готових до декількох тестів.

Чи є це в інших сферах використання?

Так , кріплення - це функція, яку виконують pytestраніше, а іноді і після, власне тестові функції. Код у кріпленні може робити все, що завгодно. Наприклад, кріплення може бути використане для отримання набору даних для тестів для роботи, або кріплення також може бути використане для введення системи у відомий стан перед запуском тесту.

Чи можу я мати більше одного conftest.pyфайлу? Коли я хотів би це зробити?

По-перше, можна поставити світильники в окремі тестові файли. Однак, щоб поділитися світильниками між декількома тестовими файлами, вам потрібно використовувати conftest.pyфайл десь у центрі для всіх тестів. Світильники можуть ділитися будь-яким тестом. Їх можна помістити в окремі тестові файли, якщо ви хочете, щоб кріплення використовувалося лише тестами у цьому файлі.

По-друге, так , ви можете мати інші conftest.pyфайли у підкаталогах верхнього каталогу тестів. Якщо ви це зробите, світильники, визначені у цих conftest.pyфайлах нижчого рівня, будуть доступні для тестів у цьому каталозі та підкаталогах.

Нарешті, розміщення світильників у conftest.pyфайлі у тестовому корені зробить їх доступними у всіх тестових файлах.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.