2016-09-25 76 views
1

可以通過命令行參數對測試函數進行參數化。 可以將一個燈具作爲一個類的範圍。 我想結合這兩個東西,以便每個類都接收參數化參數,這些參數賦予課程中的燈具。 (基本上,每個命令行參數我需要運行一個非常昂貴的操作,然後針對該操作的結果做各種便宜,快速的測試,並且我不希望重新運行昂貴的操作對於每個廉價的測試,所以我想要一種方法來保存它)使用pytest動態參數化類級別的燈具

換句話說,我正在尋找一個相當於pytest_generate_tests(metafunc),這將工作動態參數化夾具,而不是測試功能。

我已經嘗試過一次沒有成功的事情是通過pytest_generate_tests鉤子讀取請求參數並設置那些

conftest.py: 
    def pytest_generate_tests(metafunc): 
     metafunc.parametrize("result", [ 
       (1,0),(1,2) 
      ]) 

test_thing.py: 
    class TestThingy: 
     @pytest.fixture(scope="class") 
     def result(self, request): 
      a,b=request.param 
      return a+b 

    #@pytest.mark.parametrize("result", [(0, 1), (1, 2)]) 
    def test_one(self, result): 
     assert result!=2 

運行這個測試會導致拋出以下錯誤(請注意,測試運行正常,當我嘗試它沒有conftest掛鉤,並與註釋行註釋掉):

@pytest.fixture(scope="class") 
def result(self, request): 
    a,b=request.param 

AttributeError: 'SubRequest' object has no attribute 'param'

我也會對任何其他替代方法感興趣,以達到相同的結果。

+0

如果py.test團隊可以權衡,那將是非常好的。文檔在這一點上根本不明確。 –

回答

2

我做了一個醜陋的,下鍋的-A-工作在基於命令行參數這樣的參數化夾具:

# contents of conftest.py 
import pytest 

def pytest_addoption(parser): 
    parser.addoption("--test-local", action="store_true", default=False) 

def pytest_generate_tests(metafunc): 
    if "dummy" in metafunc.fixturenames: 
     #driverParams sets dummy[0], dummy[1] parametrically (as seen below) 
     if metafunc.config.getoption("--test-local"): 
      driverParams = [(True, None)] 
     else: 
      driverParams = [(False, "seriousface setting 1"), 
          (False, "seriousface setting 2")] 
     metafunc.parametrize("dummy", driverParams) 

#driver can then be used as a standard fixture 
@pytest.fixture(scope="function") 
def driver(dummy): 
    _driver = makeDriverStuff(dummy[0], dummy[1]) 
    yield _driver 
    _driver.cleanup() 

@pytest.fixture(scope="function") 
def dummy(): 
    pass 

從本質上講這是怎麼回事的是,當metafunc.parametrize("dummy", driverParams)運行時,它擲driverParams成爲任何依靠虛擬夾具。更重要的是,這意味着虛擬夾具功能從未實際執行

起初,我嘗試使用metafunc直接參數化我的司機夾具,並注意到清理從未發生,因爲(錯誤的)辦法,我以前做的事情是metafunc.parametrizemakeDriverStuff(param1, param2)直接,然後撓我的頭不知道爲什麼driver()從未被調用。假人的意思是說,「嘿,這裏有一個合法的夾具,不要抱怨你找不到它!」,然後總是用一些實際有用的東西搶佔它。

就像我說的,這是一個醜陋的黑客。但你應該可以適應它

+0

我實施了這個建議。然後,我添加了一個打印語句來檢查昂貴代碼被調用的次數。不幸的是,對於每個獲取參數的測試,答案都是一遍又一遍。 – dWitty

+0

在我正在做的事情中,這是故意的。我的'makeDriverStuff()'旋轉了一個新的WebDriver(從而創建了一個新的瀏覽器實例),我特別想讓這些測試更加獨立。 –

+0

會更改燈具裝飾器以使其具有'scope =「session」'(或類或模塊,視情況而定)爲您解決嗎? –