Pytest簡介
Pytest is a mature full-featured Python testing tool that helps you write better programs.
Thepytest
framework makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries.
通過官方網站介紹我們可以瞭解到,pytest是一個非常成熟的全功能的python測試框架,主要有
以下幾個特點:
- 簡單靈活易上手
- 支援引數化
- 支援簡單的單元測試和複雜的功能測試,還可以用來做自動化測試
- 具有很多第三方外掛,並且可以自定義擴充套件
- 測試用例的skip和xfail處理
- 可以很好的和Jenkins整合
- 支援執行由nose, unittest編寫的測試用例
Pytest安裝
1.直接使用pip命令安裝
pip install -U pytest # -U是如果已安裝會自動升級最新版本
2.驗證安裝結果
pytest --version # 展示當前安裝版本 C:\Users\edison>pytest --version pytest 6.2.5
3.在pytest測試框架中,要遵循以下約束:
- 測試檔名要符合test_*.py或*_test.py格式(例如test_min.py)
- 測試類要以Test開頭,且不能帶有init方法
- 在單個測試類中,可以包含一個或多個test_開頭的函式
Pytest測試執行
pytest進行測試比較簡單,我們來看一個例項:
import pytest # 匯入pytest包 def test_001(): # 函式以test_開頭 print("test_01") def test_002(): print("test_02") if __name__ == '__main__': pytest.main(["-v","test_1214.py"]) # 呼叫pytest的main函式執行測試
這裡我們定義了了兩個測試函式,直接列印出結果,下面執行測試:
============================= test session starts ============================= platform win32 -- Python 3.8.0, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- D:\Code\venv\Scripts\python.exe cachedir: .pytest_cache rootdir: D:\Code collecting ... collected 2 items test_1214.py::test_001 PASSED [ 50%] test_1214.py::test_002 PASSED [100%] ============================== 2 passed in 0.11s ============================== Process finished with exit code 0
輸出結果中顯示執行了多少條案例、對應的測試模組、通過條數以及執行耗時。
測試類主函式
pytest.main(["-v","test_1214.py"])
通過python程式碼執行 pytest.main() 1.直接執行pytest.main() 【自動查詢當前目錄下,以test_開頭的檔案或者以_test結尾的py檔案】 2.設定pytest的執行引數 pytest.main(['--html=./report.html','test_login.py'])【執行test_login.py檔案,並生成html格式的報告】
main()括號內可傳入執行引數和外掛引數,通過[]進行分割,[]內的多個引數通過‘逗號,’進行分割
執行目錄及子包下的所有用例 pytest.main(['目錄名'])
執行指定模組所有用例 pytest.main(['test_reg.py'])
執行指定模組指定類指定用例 pytest.main(['test_reg.py::TestClass::test_method']) 冒號分割 -m=xxx: 執行打標籤的用例 -reruns=xxx:失敗重新執行 -q: 安靜模式, 不輸出環境資訊 -v: 豐富資訊模式, 輸出更詳細的用例執行資訊 -s: 顯示程式中的print/logging輸出 --resultlog=./log.txt 生成log --junitxml=./log.xml 生成xml報告
斷言方法
pytest斷言主要使用Python原生斷言方法,主要有以下幾種:
- == 內容和型別必須同時滿足相等
- in 實際結果包含預期結果
- is 斷言前後兩個值相等
import pytest # 匯入pytest包 def add(x,y): # 定義以test_開頭函式 return x + y def test_add(): assert add(1,2) == 3 # 斷言成功 str1 = "Python,Java,Ruby" def test_in(): assert "PHP" in str1 # 斷言失敗 if __name__ == '__main__': pytest.main(["-v","test_pytest.py"]) # 呼叫main函式執行測試
============================= test session starts ============================= platform win32 -- Python 3.8.0, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- D:\Code\venv\Scripts\python.exe cachedir: .pytest_cache rootdir: D:\Code collecting ... collected 2 items test_pytest.py::test_add PASSED [ 50%] test_pytest.py::test_in FAILED [100%] ================================== FAILURES =================================== ___________________________________ test_in ___________________________________ def test_in(): > assert "PHP" in str1 E AssertionError: assert 'PHP' in 'Python,Java,Ruby' test_pytest.py:11: AssertionError =========================== short test summary info =========================== FAILED test_pytest.py::test_in - AssertionError: assert 'PHP' in 'Python,Java... ========================= 1 failed, 1 passed in 0.18s ========================= Process finished with exit code 0
可以看到執行結果中明確指出了錯誤原因是“AssertionError”,因為PHP不在str1中。
常用命令詳解
1.執行指定案例
if __name__ == '__main__': pytest.main(["-v","-s","test_1214.py"])
2.執行當前資料夾包括子資料夾所有用例
if __name__ == '__main__': pytest.main(["-v","-s","./"])
3.執行指定資料夾(code目錄下所有用例)
if __name__ == '__main__': pytest.main(["-v","-s","code/"])
4.執行模組中指定用例(執行模組中test_add用例)
if __name__ == '__main__': pytest.main(["-v","-s","test_pytest.py::test_add"])
5.執行失敗的最大次數
使用表示式"--maxfail=num"來實現(注意:表示式中間不能存在空格),表示用例失敗總數等於num 時停止執行。
6.錯誤資訊在一行展示
在實際專案中如果有很多用例執行失敗,檢視報錯資訊將會很麻煩。使用"--tb=line"命令,可以很好解決這個問題。
介面呼叫
本地寫一個查詢使用者資訊的介面,通過pytest來呼叫,並進行介面斷言。
1 # -*- coding: utf-8 -*- 2 import pytest 3 import requests 4 5 def test_agent(): 6 r = requests.post( 7 url="http://127.0.0.1:9000/get_user", 8 data={ 9 "name": "吳磊", 10 "sex": 1 11 }, 12 headers={"Content-Type": "application/json"} 13 ) 14 print(r.text) 15 assert r.json()['data']['retCode'] == "00" and r.json()['data']['retMsg'] == "呼叫成功" 16 17 if __name__ == "__main__": 18 pytest.main(["-v","test_api.py"])