Python pytest 框架通關指南:自動化測試不再難
一、pytest介紹
pytest是一個非常流行且高效的Python測試框架,提供豐富功能和靈活用法,讓測試用例的編寫與運行變得簡單高效
官方文檔地址:pytest
1.1 pytest的優(yōu)點
- 簡單易用:語法簡潔清晰,對編寫測試用例非常友好,上手速度快;
- 強大的斷言庫:內置豐富斷言庫,可輕松判斷測試結果;
- 支持參數(shù)化測試:允許用不同參數(shù)多次運行同一個測試函數(shù),大幅提升測試效率;
- 豐富的插件生態(tài)系統(tǒng):可通過插件擴展多種功能(如覆蓋率測試、測試報告生成、失敗用例重復執(zhí)行等),還支持與selenium、requests、appinum等結合,實現(xiàn)Web自動化、接口自動化、App自動化測試;
- 靈活的測試控制:允許跳過指定用例,或標記預期失敗的用例,支持重復執(zhí)行失敗用例。
1.2 主流Python接口自動化框架對比
| 維度 | unittest(Python內置) | pytest | Robot Framework |
|---|---|---|---|
| 安裝方式 | 無需安裝(Python標準庫) | pip install pytest | pip install robotframework |
| 語法風格 | 基于類(需繼承TestCase) | 函數(shù)式或面向對象(無需樣板代碼) | 關鍵字驅動(表格化用例) |
| 斷言方法 | self.assertEqual() 等 | 原生assert表達式 | 關鍵字斷言(如Should Be Equal) |
| 參數(shù)化支持 | 需subTest 或第三方庫 | 內置(@pytest.mark.parametrize) | 數(shù)據驅動(Test Template) |
| 插件生態(tài) | 少(依賴擴展庫如HTMLTestRunner) | 豐富(如pytest-html、pytest-xdist、allure-pytest等) | 一般(需安裝額外庫如RequestsLibrary) |
| 測試報告 | 需插件生成報告 | 支持多格式報告(HTML、Allure等) | 自帶詳細日志和報告 |
| 學習曲線 | 中等(需熟悉xUnit模式) | 低(語法簡潔) | 高(需掌握關鍵字和語法) |
| BDD支持 | 不支持 | 支持(通過pytest-bdd插件) | 支持(通過robotframework-bdd) |
| 適用場景 | 簡單項目或遺留系統(tǒng)維護 | 復雜項目、高擴展性需求 | 團隊協(xié)作、非技術人員參與 |
二、安裝
安裝命令:
pip install pytest

安裝成功驗證:
安裝完成后,可通過pip list命令查看當前項目下pytest包是否安裝成功。同時需確認PyCharm中Python解釋器已更新,安裝pytest前后的代碼運行差異如下:
- 未安裝pytest:需編寫main函數(shù)手動調用測試用例;
- 安裝pytest:測試方法名前會出現(xiàn)直接運行標志,無需手動編寫調用代碼。

三、用例運行規(guī)則
要讓pytest自動發(fā)現(xiàn)并運行測試用例,需遵循以下命名規(guī)則:
- 文件名必須以
test_開頭或者_test結尾; - 測試類必須以
Test開頭,并且不能有_ _init_ _方法; - 測試方法必須以
test開頭。
運行示例:
滿足規(guī)則后,可通過命令行執(zhí)行pytest命令直接運行符合條件的用例:

注意事項:
Python測試類中不可添加__init__方法,否則pytest會拋出pytest_collectionWarning警告,無法收集該測試類。原因是pytest采用自動發(fā)現(xiàn)機制收集測試用例,會自動實例化測試類并調用其test開頭的方法,若存在__init__方法,可能掩蓋測試邏輯并引入額外副作用,影響測試結果準確性。
若測試類需初始化操作,可使用setUp()和tearDown()方法、類屬性或fixture函數(shù)替代。
四、pytest命令參數(shù)
4.1 常見參數(shù)
pytest提供豐富的命令行選項控制測試執(zhí)行,常用參數(shù)及說明如下:
| 命令 | 描述 | 備注 |
|---|---|---|
| pytest | 在當前目錄及其子目錄中搜索并運行測試 | - |
| pytest -v | 增加輸出的詳細程度 | - |
| pytest -s | 顯示測試中的print語句 | - |
| pytest test_module.py | 運行指定的測試模塊 | - |
| pytest test_dir/ | 運行指定目錄下的所有測試 | - |
| pytest -k | 只運行測試名包含指定關鍵字的測試 | - |
| pytest -m | 只運行標記為指定標記的測試 | - |
| pytest -q | 減少輸出的詳細程度 | - |
| pytest --html=report.html | 生成HTML格式的測試報告 | 需要安裝pytest-html插件 |
| pytest --cov | 測量測試覆蓋率 | 需要安裝pytest-cov插件 |
4.2 命令使用示例
運行符合規(guī)則的用例(不顯示print內容):

詳細打印并顯示print內容(-s和-v可連寫為-sv):

指定文件/測試用例運行:

五、pytest配置文件
當需要頻繁使用復雜命令參數(shù)時,可將配置統(tǒng)一寫入pytest.ini文件(項目根目錄下創(chuàng)建),避免重復輸入。
5.1 常見配置選項
| 參數(shù) | 解釋 |
|---|---|
| addopts | 指定在命令行中默認包含的選項 |
| testpaths | 指定搜索測試的目錄 |
| python_files | 指定發(fā)現(xiàn)測試模塊時使用的文件匹配模式 |
| python_classes | 指定發(fā)現(xiàn)測試類時使用的類名前綴或模式 |
| python_functions | 指定發(fā)現(xiàn)測試函數(shù)和方法時使用的函數(shù)名前綴或模式 |
| norecursedirs | 指定在搜索測試時應該避免遞歸進入的目錄模式 |
| markers | 定義測試標記,用于標記測試用例 |
5.2 配置示例
配置pytest.ini文件,實現(xiàn)詳細輸出cases包下文件名以test_開頭、類名以Test開頭的所有用例:
[pytest] addopts = -vs testpaths = cases python_files = test03.py
配置完成后,命令行直接執(zhí)行pytest命令即可,無需額外指定參數(shù),運行結果如下:

六、前后置操作
前后置操作用于在測試用例執(zhí)行前后完成環(huán)境設置、數(shù)據準備、資源清理等工作,pytest提供三種實現(xiàn)方式:
6.1 setup_method 和 teardown_method
用于類中每個測試方法的前置和后置操作,每個測試方法執(zhí)行前都會觸發(fā)setup_method,執(zhí)行后觸發(fā)teardown_method。
示例代碼:
import pytest
class TestExample:
def setup_method(self):
print("Setup: Before each test")
def teardown_method(self):
print("Teardown: After each test")
def test_example1(self):
print("Running test_example1")
def test_example2(self):
print("Running test_example2")運行結果:

6.2.setup_class 和 teardown_class
用于整個測試類的前置和后置操作,測試類中所有方法執(zhí)行前觸發(fā)一次setup_class,所有方法執(zhí)行后觸發(fā)一次teardown_class。
示例代碼:
class TestExample:
def setup_class(self):
print("Setup: Before all test")
def teardown_class(self):
print("Teardown: After all test")
def test_example1(self):
print("Running test_example1")
def test_example2(self):
print("Running test_example2")運行結果:

七、斷言
斷言(assert)是?種調試輔助工具,用于檢查程序狀態(tài)是否符合預期,若斷言失敗(條件為假),Python解釋器會拋出AssertionError異常。pytest支持使用標準Pythonassert語句驗證預期值與實際值。
基本語法:
assert 條件, 錯誤信息
- 條件:必須是布爾表達式;
- 錯誤信息:條件為假時顯示的提示信息(可選)。
斷言示例:
7.1 基本數(shù)據類型斷言:
# 斷言整數(shù) a = 1 b = 2 assert a == b, "a和b不相等" # 斷言字符串 str = "hello" assert "hello" == str
7.2 數(shù)據結構斷言:
def test():
# 斷言列表
expect_list = [1, 'apple', 3.14]
actual_list = [1, 'apple', 3.14]
# 斷言元組
expect_tuple = (1, 'apple', 3.14)
actual_tuple = (1, 'apple', 3.14)
# 斷言字典
expect_dict = {'name': 'Alice', 'age': 25}
actual_dict = {'name': 'Alice', 'age': 25}
# 斷言集合
expect_set = {1, 2, 3, 'apple'}
actual_set = {1, 2, 3, 'apple'}
assert expect_list == actual_list
assert expect_tuple == actual_tuple
assert expect_dict == actual_dict
assert expect_set == actual_set7.3 函數(shù)斷言:
def divide(a, b):
assert b != 0, "除數(shù)不能為0"
return a / b
# 正常情況
print(divide(10, 2)) # 輸出 5.0
# 觸發(fā)斷言
print(divide(10, 0)) # 拋出 AssertionError: 除數(shù)不能為07.4 接口返回值斷言:
import requests
from jsonschema.validators import validate
# 斷言接口返回值完整字段和值
def test1():
url = "http://jsonplaceholder.typicode.com/posts/1"
r = requests.get(url=url)
expect_data = {
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
print(r.json())
assert r.json() == expect_data
assert r.json()['userId'] == 1
# 斷言接口返回值重要字段
def test2():
url = "http://jsonplaceholder.typicode.com/comments?postId=1"
r = requests.get(url=url)
print(r.json())
assert r.json()[1]['id'] == 1
# 斷言接口HTML返回值
def test3():
url = "http://jsonplaceholder.typicode.com/"
r = requests.get(url=url)
assert "Use your own data" in r.text八、參數(shù)化
參數(shù)化設計可讓測試用例通過不同參數(shù)多次運行,提高測試效率和覆蓋度,pytest通過@pytest.mark.parametrize裝飾器實現(xiàn)參數(shù)化,支持在測試函數(shù)、類、模塊級別使用。
8.1 測試函數(shù)參數(shù)化
示例代碼:
import pytest
@pytest.mark.parametrize("test_input, expected", [("3+5", 8), ("2+4", 6), ("6*9", 42)])
def test_eval(test_input, expected):
assert eval(test_input) == expected裝飾器定義了三組(test_input, expected)元組,test_eval函數(shù)會依次使用每組參數(shù)運行三次。
8.2 測試類參數(shù)化
示例代碼:
import pytest
@pytest.mark.parametrize("n, expected", [(1, 2), (3, 4)])
class TestClass:
def test_simple_case(self, n, expected):
assert n + 1 == expected
def test_weird_simple_case(self, n, expected):
assert (n * 1) + 1 == expected參數(shù)集將作用于類中所有測試方法,每個方法都會使用每組參數(shù)運行。
8.3 模塊級別參數(shù)化
通過給pytestmark全局變量賦值,實現(xiàn)模塊內所有測試的參數(shù)化:
import pytest
pytestmark = pytest.mark.parametrize("n, expected", [(1, 2), (3, 4)])
class TestClass:
def test_simple_case(self, n, expected):
assert n + 1 == expected
def test_weird_simple_case(self, n, expected):
assert (n * 1) + 1 == expected8.4 自定義參數(shù)化數(shù)據源
示例代碼:
def data_provider():
return ["a", "b"]
# 定義測試函數(shù),依賴自定義數(shù)據源
@pytest.mark.parametrize("data", data_provider())
def test_data(data):
assert data is not None
print(f"Testing with data provider: {data}")除了使用 @parametrize 添加參數(shù)外,pytest.fixture() 允許對 fixture 函數(shù)進行參數(shù)化,詳情參考下一篇文章。
到此這篇關于Python pytest 框架通關指南:自動化測試不再難的文章就介紹到這了,更多相關Python pytest 框架內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Python用Flask和PyMySQL實現(xiàn)MySQL數(shù)據庫的增刪改查API
Web開發(fā)中,API常需與數(shù)據庫交互以實現(xiàn)數(shù)據的持久化存儲,MySQL作為主流關系型數(shù)據庫,廣泛用于各類項目,本文基于Flask框架,結合PyMySQL庫,實現(xiàn)對MySQL數(shù)據庫的增刪改查(CRUD)API,適合有基礎Flask知識和MySQL基礎的開發(fā)者,完整覆蓋環(huán)境搭建、數(shù)據庫設計、API開發(fā)及測試2025-09-09
Pandas中的 transform()結合 groupby()用法示例詳解
這篇文章主要介紹了Pandas中的 transform() 結合 groupby() 用法示例,本文通過一個餐廳數(shù)據集給大家分享解決方案,示例代碼簡單易懂,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2021-09-09

