Как настроить pytest, чтобы избежать сбоя при сбое импорта? - PullRequest
2 голосов
/ 11 июля 2019

У меня есть несколько более сложных проектов, в которых, если вы запустите pytest --collect-only, вы в конечном итоге столкнетесь с большим количеством сбоев импорта, вызванных обнаруженными тестовыми файлами с импортом вещей, которые еще не были установлены.

Я хочу изменить эти тестовые файлы таким образом, чтобы они не сбоили при сборе.

Это связано с тем, что пользователь может захотеть запустить тесты с использованием определенного шаблона, например pytest -k foo, но он не сможет сделать это, если сбор не удастся на несвязанных тестах.

Я знаю, что могу определить pytest_configure метод, который будет называться коллекцией durind, но если я перенесу в него импорт, я все равно получу сбои позже, когда интерпретатор достигнет кода, пытающегося использовать отсутствующий импорт.

def pytest_configure(config):
    try:
        import foo
    except:
        pytest.skip("skipping when foo is not installed")

def test_foo()
  assert foo.is_enabled()  # <-- foo is undefined here

Мой пример явно слишком схож с тем, что мы все знаем, что я мог бы снова добавить импорт в тестовый метод, но я не хочу делать это в десятках методов. Я ищу более чистое решение.

1 Ответ

1 голос
/ 12 июля 2019

Если вы не хотите прерывать тестовую коллекцию при ошибках импорта (или любых других), используйте флаг --continue-on-collection-errors.Пример:

test_spam.py имеет неразрешенный импорт:

import foo


def test_foo():
    assert foo.is_enabled()

test_eggs.py работает:

def test_bar():
    assert True

Запуск тестов дает:

$ pytest --continue-on-collection-errors -v
======================================= test session starts =======================================
...
collected 1 item / 1 errors                                                                       

test_eggs.py::test_bar PASSED

============================================= ERRORS ==============================================
__________________________________ ERROR collecting test_spam.py __________________________________
ImportError while importing test module '/home/hoefling/projects/private/stackoverflow/so-56997157/test_spam.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
test_spam.py:2: in <module>
    import foo
E   ModuleNotFoundError: No module named 'foo'
================================ 1 passed, 1 error in 0.06 seconds ================================

Это будет указывать pytest запускать все тесты, которые он может собрать (test_eggs::test_bar в этом примере), но не выполнять его, так как не удалось собрать один модуль.Если вы не хотите проваливать тестовый прогон, pytest предлагает удобную функцию importorskip:

import pytest
foo = pytest.importorskip('foo')


def test_foo():
    assert foo.is_enabled()

Запуск тестов теперь дает:

$ pytest -v
======================================= test session starts =======================================
...
collected 1 item / 1 skipped                                                                      

test_eggs.py::test_bar PASSED                                                               [100%]

=============================== 1 passed, 1 skipped in 0.04 seconds ===============================

Как вы можете видеть, разница между этими двумя заключается в обработке ошибок сбора (1 errors против 1 skipped) и результирующего кода выхода (1 против 0).


Лично,Я склонен не использовать importorskip, потому что это может привести к тому, что тесты не будут выполняться в долгосрочной перспективе.Если у вас большой набор тестов, обычно вы просто кратко смотрите на результат теста (провал / не провал) и явно не проверяете, есть ли новые пропущенные тесты.Это может привести к ситуациям, когда тесты нигде не выполняются (даже на сервере CI) до тех пор, пока кто-то не заметит это (лучший случай) или (худший случай) код, который предполагается тестировать, покажет ошибку в производственной системе.Конечно, есть и другие доступные метрики, которые могут косвенно охранять этот случай (например, следить за тестовым покрытием и запрещать коммиты, которые его снижают), но явный сбой IMO устанавливает огромный восклицательный знак, которого вы просто не можете избежать.

Источник: Пропуск отсутствующей зависимости импорта .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...