2016-12-28 74 views
1

是否有可能將pytest fixtures編寫爲龍捲風協程?例如,我想寫一個夾具用於創建數據庫,就像這樣:如何使用協程作爲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的進行清潔。我發現非常有用。

編輯:我發現上面的方法有一個限制。您不能更改get_db_connection夾具的範圍,因爲它使用範圍爲「function」的io_loop夾具。