1. 程式人生 > >Pytest測試框架(三):pytest fixture 用法

Pytest測試框架(三):pytest fixture 用法

xUnit style 結構的 fixture用於初始化測試函式, pytest fixture是對傳統的 xUnit 架構的setup/teardown功能的改進。pytest fixture為測試準備一個良好的測試環境,測試函式使用的每個 fixture通常有一個引數(以 fixture 命名),測試函式通過引數訪問它們。本文將介紹pytest fixture的一些基本用法。 # @pytest.fixture ```python import pytest @pytest.fixture() def login(): print("登入") return 8 class Test_Demo(): def test_case1(self): print("\n開始執行測試用例1") assert 1 + 1 == 2 def test_case2(self, login): print("\n開始執行測試用例2") print(login) assert 2 + login == 10 def test_case3(self): print("\n開始執行測試用例3") assert 99 + 1 == 100 if __name__ == '__main__': pytest.main() ``` test_case2需要呼叫login方法(或者獲取login的返回值),pytest 將會尋找並呼叫`@pytest.fixture`標記的login() 方法。 結果: ```python PASSED [ 33%] 開始執行測試用例1 登入 PASSED [ 66%] 開始執行測試用例2 8 PASSED [100%] 開始執行測試用例3 ``` # 共享 fixture 函式:conftest.py 在測試過程中,多個測試檔案可能都要呼叫 fixture 函式,可以將其移動到 conftest.py 檔案中。conftest.py 檔案中的 fixture 函式不需要在測試函式中匯入,可以被 pytest 自動識別,查詢順序從測試類開始,然後是測試模組,然後是 conftest.py 檔案,最後是內建外掛和第三方外掛。 conftest.py : ```python import pytest @pytest.fixture() def login(): print("登入") return 8 ``` 測試用例: ```python import pytest class Test_Demo(): def test_case1(self): print("\n開始執行測試用例1") assert 1 + 1 == 2 def test_case2(self, login): print("\n開始執行測試用例2") print(login) assert 2 + login == 10 def test_case3(self): print("\n開始執行測試用例3") assert 99 + 1 == 100 if __name__ == '__main__': pytest.main() ``` 結果: ```python PASSED [ 33%] 開始執行測試用例1 登入 PASSED [ 66%] 開始執行測試用例2 8 PASSED [100%] 開始執行測試用例3 ``` # yield方法 使用yield關鍵字可以實現setup/teardown的功能,在yield關鍵字之前的程式碼在case之前執行,yield之後的程式碼在case執行結束後執行 ```python import pytest @pytest.fixture() def login(): print("登入") yield print("退出登入") class Test_Demo(): def test_case1(self): print("\n開始執行測試用例1") assert 1 + 1 == 2 def test_case2(self, login): print("\n開始執行測試用例2") assert 2 + 8 == 10 def test_case3(self): print("\n開始執行測試用例3") assert 99 + 1 == 100 if __name__ == '__main__': pytest.main() ``` 結果: ```python PASSED [ 33%] 開始執行測試用例1 登入 PASSED [ 66%] 開始執行測試用例2 退出登入 PASSED [100%] 開始執行測試用例3 ``` # addfinalizer方法 addfinalizer也可以實現環境的清理,實現與yield方法相同的效果,跟yield不同的是需要註冊作為終結器使用的函式。 ```python import pytest @pytest.fixture() def login(request): print("登入") def demo_finalizer(): print("退出登入") # 註冊demo_finalizer為終結函式 request.addfinalizer(demo_finalizer) class Test_Demo(): def test_case1(self): print("\n開始執行測試用例1") assert 1 + 1 == 2 def test_case2(self, login): print("\n開始執行測試用例2") assert 2 + 8 == 10 def test_case3(self): print("\n開始執行測試用例3") assert 99 + 1 == 100 if __name__ == '__main__': pytest.main() ``` 結果: ```python PASSED [ 33%] 開始執行測試用例1 登入 PASSED [ 66%] 開始執行測試用例2 退出登入 PASSED [100%] 開始執行測試用例3 ``` # fixture 作用範圍:Scope fixture 作用範圍可以為module、class、session和function,預設作用域為function。 - **function**:每一個函式或方法都會呼叫 - **class**:每一個類呼叫一次 - **module**:每一個.py檔案呼叫一次 - **session**:是多個檔案呼叫一次 ## scope="function" ```python import pytest @pytest.fixture(scope="function") def login(): print("登入...") class Test_Demo(): def test_case1(self, login): print("\n開始執行測試用例1") assert 1 + 1 == 2 def test_case2(self, login): print("\n開始執行測試用例2") assert 2 + 8 == 10 def test_case3(self, login): print("\n開始執行測試用例3") assert 99 + 1 == 100 if __name__ == '__main__': pytest.main() ``` 結果: ```python 登入... PASSED [ 33%] 開始執行測試用例1 登入... PASSED [ 66%] 開始執行測試用例2 登入... PASSED [100%] 開始執行測試用例3 ``` ## scope="class" 一個class裡面多個用例都呼叫了此fixture,那麼只在class裡所有用例開始前執行一次 ```python import pytest @pytest.fixture(scope="class") def login(): print("登入...") ``` 結果: ```python 登入... PASSED [ 33%] 開始執行測試用例1 PASSED [ 66%] 開始執行測試用例2 PASSED [100%] 開始執行測試用例3 ``` # fixture自動應用 ## autouse引數 autouse設定為True時,自動呼叫fixture功能。由於預設作用域為function,不指定scope則每個方法都會呼叫fixture方法。 ```python import pytest @pytest.fixture(autouse=True) def login(): print("登入...") class Test_Demo(): def test_case1(self): print("\n開始執行測試用例1") assert 1 + 1 == 2 def test_case2(self): print("\n開始執行測試用例2") assert 2 + 8 == 10 def test_case3(self): print("\n開始執行測試用例3") assert 99 + 1 == 100 if __name__ == '__main__': pytest.main() ``` 結果: ```python 登入... PASSED [ 33%] 開始執行測試用例1 登入... PASSED [ 66%] 開始執行測試用例2 登入... PASSED [100%] 開始執行測試用例3 ``` ## @pytest.mark.usefixtures() 在測試方法上加@pytest.mark.usefixtures() ```python import pytest @pytest.fixture() def login(): print("登入...") @pytest.mark.usefixtures("login") class Test_Demo(): def test_case1(self): print("\n開始執行測試用例1") assert 1 + 1 == 2 def test_case2(self): print("\n開始執行測試用例2") assert 2 + 8 == 10 def test_case3(self): print("\n開始執行測試用例3") assert 99 + 1 == 100 if __name__ == '__main__': pytest.main() ``` 結果: ```python 登入... PASSED [ 33%] 開始執行測試用例1 登入... PASSED [ 66%] 開始執行測試用例2 登入... PASSED [100%] 開始執行測試用例3 ``` # fixture函式引數化 如果多條用例都需要呼叫相同引數,可以將fixture函式引數化。fixture 函式將執行每個引數值,fixture通過固定引數request傳遞。 ```python import pytest @pytest.fixture(scope="module", params=[ [1, 1, 2], [2, 8, 10], [99, 1, 100] ]) def data(request): yield request.param class Test_Demo(): def test_case1(self): print("\n開始執行測試用例1") assert 2 + 8 == 10 def test_case2(self, data): print("\n開始執行測試用例2") assert data[0] + data[1] == data[2] def test_case3(self): print("\n開始執行測試用例3") assert 99 + 1 == 100 if __name__ == '__main__': pytest.main() ``` 結果: ```python PASSED [ 20%] 開始執行測試用例1 PASSED [ 40%] 開始執行測試用例2 PASSED [ 60%] 開始執行測試用例2 PASSED [ 80%] 開始執行測試用例2 PASSED [100%] 開始執行測試用例3 ```
--THE END--
> 文章標題:Pytest測試框架(三):pytest fixture 用法 > 本文作者:hiyo > 本文連結:[https://www.cnblogs.com/hiyong/p/14163280.html](https://www.cnblogs.com/hiyong/p/14163280.html) > 歡迎關注公眾號:「測試開發小記」及時接收最新技術文章!