引言
Pytest 作為 Python 中最受歡迎的測試框架之一,以其簡潔的語法、強大的功能和豐富的插件生態系統,極大地提升了自動化測試的效率和可維護性。在本文中,我們將深入探討 Pytest 的兩大核心特性:Fixture 和插件管理,幫助您更高效地編寫和管理您的測試用例。
一、夾具fixture
Fixture 是 Pytest 中一個非常強大的特性,它允許您定義在測試用例執行之前或之后自動運行的代碼。這對于設置測試環境(前置操作)和清理測試環境(后置操作)非常有用,例如:
?前置操作:加密參數、啟動瀏覽器、注冊并登錄賬號。
?后置操作:解密結果、關閉瀏覽器、刪除賬號。
1. 創建 Fixture
創建 Fixture 非常簡單,只需遵循以下步驟:
1.創建一個函數。
2.使用 @pytest.fixture 裝飾器裝飾該函數。
3.在函數中使用 yield 關鍵字來分隔前置操作和后置操作。yield 之前的代碼是前置操作,yield 之后的代碼是后置操作。
import pytest
from datetime import datetime@pytest.fixture
def f():print(datetime.now(), "用例開始執行")# 前置操作yield # 開始執行測試用例# 后置操作print(datetime.now(), "用例執行結束")
2、使用fixture
1.在用例的參數列表中,添加fixture的名字即可
2.給用例加上一個標記usefixtures
示例:
from datetime import datetimeimport pytest@pytest.fixture
def f():print(datetime.now(),"用例開始執行")#前置操作yield#開始執行測試用例#后置操作print(datetime.now(),"用例執行結束")def test_1(f):pass@pytest.mark.usefixtures("f")
def test_2():
3、 Fixture 高級使用
3.1 自動使用 (autouse)
如果您希望某個 Fixture 自動應用于所有或特定范圍內的測試用例,而無需顯式地將其作為參數傳遞或使用 usefixtures 標記,可以使用 autouse=True 參數。
from datetime import datetimeimport pytest@pytest.fixture(autouse= True)
def f():print(datetime.now(),"用例開始執行")#前置操作yield#開始執行測試用例#后置操作print(datetime.now(),"用例執行結束")def test_1():passdef test_2():pass
3.2 依賴使用
Fixture 之間可以存在依賴關系。一個 Fixture 可以通過在其參數列表中聲明另一個 Fixture 來使用它。Pytest 會確保被依賴的 Fixture 在依賴它的 Fixture 之前運行。
from datetime import datetimeimport pytest@pytest.fixture
def ff():print("我也是一個fixture,但我被fixture使用")@pytest.fixture(autouse= True)
def f(ff):print(datetime.now(),"用例開始執行")#前置操作yield#開始執行測試用例#后置操作print(datetime.now(),"用例執行結束")def test_1():passdef test_2():pass
- linux:使用Linux進行編譯
- git:使用git進行版本控制
- fixture:使用fixture進行前后置自動操作
3.3 返回內容:接口自動化封裝
Fixture 可以返回數據,這些數據可以被測試用例或其他 Fixture 接收。這在接口自動化測試中非常有用,例如,一個 Fixture 可以負責登錄并返回認證 token,其他測試用例可以直接使用這個 token。
# ... (接上文 f() fixture 定義,假設 yield 123)def test_1(f):print('收到fixture傳遞的數據', f) # f 將會是 123def test_2():passdef test_3(f, ff):pass
3.4 范圍共享 (Scope)
Fixture 默認的作用域是 function,這意味著每個測試函數都會執行一次 Fixture。Pytest 提供了多種作用域,以控制 Fixture 的生命周期:
?function (默認):每個測試函數執行一次。
?class:每個測試類執行一次。
?module:每個模塊執行一次。
?package:每個包執行一次。
?session:整個測試會話只執行一次。
使用 scope 參數來指定 Fixture 的作用域。例如,scope="session" 可以讓 Fixture 在整個測試會話中只運行一次,這對于啟動和關閉數據庫連接等耗時操作非常有用。
使用 conftest.py 文件:
conftest.py 文件是 Pytest 中一個特殊的本地插件文件,它可以用來存放 Fixture 和鉤子函數,使其在整個項目或特定目錄下自動被發現和使用,而無需導入。
def test_1(f):print('收到fixture傳遞的數據',f)def test_2():pass
def test_3(f,ff):pass
from datetime import datetimeimport pytest@pytest.fixture(scope = "session")
def ff():print("我也是一個fixture,但我被fixture使用")@pytest.fixture(autouse = True,scope = "session")
def f(ff):print(datetime.now(),"用例開始執行")#前置操作yield 123#開始執行測試用例#后置操作print(datetime.now(),"用例執行結束")#python語法允許函數中有多個 yield
運行結果:
當 f 和 ff 都設置為 session 作用域時,它們只會在整個測試會話開始時執行一次前置操作,并在會話結束時執行一次后置操作。
二、Pytest插件管理
Pytest 強大的插件生態系統是其核心優勢之一,它極大地擴展了框架的功能。Pytest 插件可以分為兩類:
?內置插件:Pytest 框架自帶,無需額外安裝即可使用。
?第三方插件:由社區開發,需要通過 pip 等工具進行安裝。
插件的啟動與管理
Pytest 提供了靈活的方式來啟用或禁用插件:
?啟用插件:使用 -p <plugin_name> 參數。例如,pytest -p no:cache 可以禁用內置的緩存插件。
?禁用插件:使用 -p no:<plugin_name> 參數。例如,pytest -p no:html 可以禁用 pytest-html 插件。
插件使用方式
插件通常通過以下幾種方式與 Pytest 集成和交互:
1.命令行參數:許多插件提供額外的命令行參數來控制其行為。
2.配置文件:通過 pytest.ini、pyproject.toml 或 setup.cfg 等配置文件來配置插件。
3.Fixture:插件可以提供自定義的 Fixture,供測試用例使用。
4.Mark:插件可以注冊自定義的 mark,用于標記和過濾測試用例。
三、常用第三方插件
Pytest 社區提供了大量實用的第三方插件,以下是一些在實際項目中常用的插件:
1. pytest-html:生成美觀的 HTML 測試報告
?用途:將 Pytest 的測試結果生成美觀、易讀的 HTML 格式報告,方便查看測試概覽、詳細信息和失敗原因。
?安裝:
pip install pytest-html
?使用:
?命令行:
pytest --html=report.html --self-contained-html
?配置文件 (pytest.ini):
addopts = --html=report.html --self-contained-html
2. pytest-xdist:分布式并行執行測試
?用途:允許 Pytest 在多個 CPU 核心或遠程主機上并行執行測試用例,顯著縮短大型測試套件的執行時間。
?安裝:
pip install pytest-xdist
?使用:
-n N (N為需要用多少進程)
只有在任務本身耗時較長,超出調用成本很多的時候,才有意義。
分布式執行,有并發問題,資源競爭、亂序。
3. pytest-rerunfailures:失敗用例重跑
?用途:在測試用例失敗后,自動重新執行失敗的用例。這對于處理不穩定測試(例如,由于網絡波動或 UI 渲染問題導致的偶發性失敗)非常有用。
?安裝:
pip install pytest-rerunfailures
?使用:
?--reruns N:指定失敗后重跑的次數。
?--reruns-delay N:指定每次重跑之間的等待時間(秒)。
4. pytest-result-log:記錄測試結果到日志文件
?用途:將 Pytest 的測試執行結果詳細記錄到指定的日志文件中,方便后續分析和追蹤。
?安裝:
pip install pytest-result-log
?使用:主要通過 pytest.ini 配置文件進行設置。
log_file= ./logs/pytest.log
log_file_level= info
log_file_format= %(levelname)-8s %(asctime)s [%(name)s:%(lineno)s] : %(message)s
log_file_date_format= %Y-%m-%d %H:%M:%S;記錄用例執行結果
result_log_enable= 1
;記錄用例分割線
result_log_separator=1
;分割線等級
result_log_level_separator= warning
;異常信息等級
result_log_level_verbose= info
結論
通過本文的深入學習,您應該對 Pytest 的 Fixture 機制和豐富的插件生態系統有了更全面的理解。Fixture 能夠幫助我們更好地管理測試的前置和后置操作,提高測試代碼的復用性和可維護性;而各種強大的第三方插件則極大地擴展了 Pytest 的功能,使其能夠滿足各種復雜的測試需求。
掌握這些 Pytest 的核心特性,將使您在自動化測試的道路上更加得心應手,編寫出更高效、更健壯的測試代碼。希望本文能對您的 Pytest 學習之旅有所幫助!