2016-12-28 9 views
1

Можно ли написать pytest светильники как торнадо сопрограммы? Например, я хочу, чтобы написать приспособление для создания БД, например:Как использовать сопрограмму в качестве фитинга для pytest?

from tornado import gen 
import pytest 

@pytest.fixture 
@gen.coroutine 
def get_db_connection(): 
    # set up 
    db_name = yield create_db() 
    connection = yield connect_to_db(db_name) 

    yield connection 

    # tear down 
    yield drop_db(db_name) 


@pytest.mark.gen_test 
def test_something(get_db_connection): 
    # some tests 

Очевидно, что это приспособление не работает, как и следовало ожидать, так как он вызывается как функция, а не как сопрограммы. Есть ли способ исправить это?

ответ

0

После некоторых исследований я пришел с этим решением:

from functools import partial 
from tornado import gen 
import pytest 

@pytest.fixture 
def get_db_connection(request, io_loop): # io_loop is a fixture from pytest-tornado 
    def fabric(): 
     @gen.coroutine 
     def set_up(): 
      db_name = yield create_db() 
      connection = yield connect_to_db(db_name) 
      raise gen.Return(connection) 
     @gen.coroutine 
     def tear_down(): 
      yield drop_db(db_name) 
     request.addfinalizer(partial(io_loop.run_sync, tear_down)) 
     connection = io_loop.run_sync(set_up) 
     return connection 

    return fabric 


@pytest.mark.gen_test 
def test_something(get_db_connection): 
    connection = get_db_connection() # note brackets 

Я уверен, что это можно сделать чище с помощью некоторого pylint магии. Я нашел this slides очень полезно.

EDIT: Я узнал, что выше метод имеет ограничение. Вы не можете изменить область действия устройства get_db_connection, поскольку он использует io_loop fixture с функцией «функция».