Есть закономерность, которую я иногда вижу. Есть приспособление, с которым нужно что-то делать посреди теста. Это фикстура, потому что она зависит от других фикстур (в моем случае host волшебная фикстура из тестовой инфраструктуры), и ее нужно очищать после выполнения теста.

Один недостойный способ - вернуть функцию:

@pytest.fixture()
def myfixture():
    def retfun():
       doing_something()
    return retfun

В этом случае test может использовать myfixture как функцию:

def test_foo(myfixture):
  myfixture()

Здесь нет этапа очистки, а вложенный «def» всегда трудно читать.

Я просто сделал его немного более функциональным.

def put_data(host):
    yield lambda: (
        host.check_output('/usr/bin/truncate testblob --size 1337')
    )
 host.check_output('rm testblob')

Вызов из теста такой же:

def test_foo(put_data):
    do_something()
    put_data()
    assert result()

Основные преимущества:

  1. Нет чрезмерного объявления «def». Labmda — это почти то же самое, что и функция, но ясно видно, что это «запускаемый один раз» код.
  2. yield lambda сделать так, чтобы это выглядело ближе к возвращению закрытия
  3. yield вместо return позволяет выполнить очистку (даже после неудачного теста!)
  4. наконец, эти скобки вокруг тела lambda позволяют поместить тело лямбды в отдельную строку, что упрощает чтение.

Я прекрасно понимаю, что между yield func и yield lambda нет никакой разницы, но сочетание yield и lambda в одной строке (вместо отдельных def) делает его более лаконичным, на мой взгляд.