pytest: Как выполнить установочный код, только если загружен определенный прибор - PullRequest
2 голосов
/ 06 мая 2019

Я разрабатываю базу данных на основе фляги (используя флягу-sqlalchemy). Я использую приборы для определения отдельных частей данных испытаний.


@pytest.fixture(scope='class')
def model_a(db):
   a = ModelA()
   db.session.add(a)
   db.session.commit()
   return a


@pytest.fixture(scope='class')
def model_b(db, a):
  b = ModelB(a=a)
  db.session.add(b)
  db.session.commit()
  return b

# …

Хотя он работает для вызова db.session.commit() для каждого тестового объекта, было бы более эффективно вызывать его только один раз непосредственно перед выполнением реальных тестов.

Есть ли способ запустить db.session.commit() перед каждым тестом, после загрузки всех приборов, но только если для теста прямо или косвенно требуется db?


То, что я не думаю, что они будут работать:

  • A python_runtest_setup -hook, похоже, не может получить доступ к приборам или определить, загружен ли прибор db для / необходим для теста.
  • Приспособление autouse должно зависеть от db, поэтому во всех тестах используется приспособление db. Кроме того, я не смог найти способ сделать его последним.

1 Ответ

1 голос
/ 07 мая 2019

Нельзя указывать порядок приборов, кроме как косвенно (приборы зависят от других приборов), см. Обсуждение в выпуск # 1216 .Вы можете получить доступ как к именам приборов, так и к значениям приборов в хуках, поэтому использование хуков на самом деле хорошая идея.Тем не менее, pytest_runtest_setup слишком рано для выполнения всех приборов;используйте взамен pytest_pyfunc_call.Пример:

from _pytest.fixtures import FixtureRequest


def pytest_pyfunc_call(pyfuncitem):
    if 'db' in pyfuncitem.fixturenames:
        db = FixtureRequest(pyfuncitem).getfixturevalue('db')
        db.session.commit()
    # ensure this hook returns None, or your underlying test function won't be executed.
...