-
安裝
pip install pytest
用例可以是函數也可以是類中的方法
def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc = 12345 @pytest.mark.api def test_str(self):res = add('1', '2')assert res == '12'def test_int(self):res = add(1, 2)assert res == 3def test_list(self):res = add([1, 2], [3, 4])assert res == [1, 2, 3, 4]
-
啟動測試
- 命令行輸入 pytest 會自動檢索項目中所有的用例去執行 參數 -k “xx” 模糊匹配文件執行
- 根目錄新建 main.py 文件 右鍵運行腳本
main.py import pytest pytest.main()
-
用戶自定義標記
可以根據不同類型的用例分成不同的種類.在用例多的情況下可以根據需求執行部分種類測試日志.
配置
創建配置文件,我這邊創建在項目的根目錄下 pytest.ini[pytest] markers =api : 接口測試ui : UI測試ut : 重試login : 登錄測試ddt: 數據驅動測試
在 markers 中key:value 形式的就是自定義的標記,名稱:注釋
打標記
@pytest.mark.標記名稱來使用.@pytest.mark.tt def test_func():print()
使用
- 命令行
pytest -m 標記名稱
- 添加到配置文件中 pytest.ini 在配置文件中添加參數后.在命令行直接執行 pytest 會自動攜帶addopts中的參數
[pytest] addopts = -m 標記名稱
-
內置標記
- skip 無條件跳過
- skipif 滿足條件跳過
- xfail 預期失敗
- xfailif 滿足條件預期失敗
- parametrize 參數化
使用@pytest.mark.parametrize標記.參數1為字段,參數 2 為函數解析出來的嵌套列表@pytest.mark.parametrize('a, b, c', read_csv('/Users/nieminghua/Desktop/pycode/pythonProject/Apytest/data.csv')) def test_ddt(a, b, c):assert int(a) + int(b) == int(c)
-
夾具-fixture
我把fixture 理解成用例執行的前置操作和后置操作(鉤子函數)
比如,在對 web 網站進行測試時,前置必要條件需要先打開瀏覽器.測試完畢后關閉瀏覽器.- fixture 可以被 fixture 調用
- 在fixture中的yield關鍵字可以返回值,只能返回 1 個值
- 在使用 fixture 中參數scope可以控制夾具的作用范圍
- function 默認值, 每個用例都會執行一遍
- class 每個類執行一遍
- module 每個模塊執行一遍
- session 每個會話執行一遍
- package 每個包執行一遍
如果不指定作用域,則每個用例執行都會單獨去執行 fixture @pytest.fixture() def func2():# 前置操作print(datetime.now(), "func2用例開始執行")yield [1, 2, 3]# 后置操作print(datetime.now(), "func2用例執行結束")@pytest.mark.usefixtures("func",'func2') def test_1():print('test1')@pytest.mark.usefixtures("func",'func2') def test_2():print('test2')>>> Apytest/test_fixture.py::test_1 2025-06-05 18:32:58.075634 func1用例開始執行 2025-06-05 18:32:58.077104 func2用例開始執行 test1 PASSED2025-06-05 18:32:58.078129 func2用例執行結束 2025-06-05 18:32:58.078950 func1用例執行結束Apytest/test_fixture.py::test_2 2025-06-05 18:32:58.080741 func1用例開始執行 2025-06-05 18:32:58.080920 func2用例開始執行 test2 PASSED2025-06-05 18:32:58.081668 func2用例執行結束 2025-06-05 18:32:58.082254 func1用例執行結束
指定作用域給 fixture 添加scope=“session”
@pytest.fixture(scope='session') def func():# 前置操作print(datetime.now(), "func1用例開始執行")yield# 后置操作print(datetime.now(), "func1用例執行結束")@pytest.fixture(scope='session') def func2():# 前置操作print(datetime.now(), "func2用例開始執行")yield [1, 2, 3]# 后置操作print(datetime.now(), "func2用例執行結束")@pytest.mark.usefixtures("func",'func2') def test_1():print('test1')@pytest.mark.usefixtures("func",'func2') def test_2():print('test2')>>> Apytest/test_fixture.py::test_1 2025-06-06 14:54:55.729863 func1用例開始執行 2025-06-06 14:54:55.730163 func2用例開始執行 test1 PASSED Apytest/test_fixture.py::test_2 test2 PASSED2025-06-06 14:54:55.733253 func2用例執行結束 2025-06-06 14:54:55.733882 func1用例執行結束
對于一些更通用的 fixture 可以定義在conftest.py 文件中.給 fixture添加 autouse=True 參數,和 scope 指定作用域,這樣所有的用例在作用域范圍內都會自動關聯到 fixture.(fixture同樣可以嵌套使用)
conftest.py 在 func2 方法中調用了 func 所以即使 func 并沒有 autouse=True,一樣會被調用. @pytest.fixture(scope='session') def func():# 前置操作print(datetime.now(), "conftest_func1用例開始執行")yield# 后置操作print(datetime.now(), "conftest_func1用例執行結束")@pytest.fixture(autouse=True, scope='session') def func2(func):# 前置操作print(datetime.now(), "conftest_func2用例開始執行")yield [1, 2, 3]# 后置操作print(datetime.now(), "conftest_func2用例執行結束")>>>> Apytest/test_fixture.py::test_1 2025-06-06 16:29:25.996684 conftest_func1用例開始執行 2025-06-06 16:29:25.997059 conftest_func2用例開始執行 test1 PASSED Apytest/test_fixture.py::test_2 test2 PASSED2025-06-06 16:29:26.000212 conftest_func2用例執行結束 2025-06-06 16:29:26.001231 conftest_func1用例執行結束
-
測試報告
這里用到第三方插件allure
pip install allure-pytest
allure下載地址官網
添加啟動命令
pytest.ini [pytest] addopts = --alluredir=allure-results --clean-alluredir
加上這條命令后執行完會生成一個allure-results文件,里邊放著 json 格式的測試日志.
之后在執行allure generate allure-results -o allure-report --clean命令. -o 參數為報告輸出路徑
之后打開目錄里的 index.html 就可以看到報告
可以在 main.py 文件中通過 os 模塊來執行生成的動作,這樣每次執行完用例會自動生成報告
import pytest import ospytest.main()os.system("allure generate allure-results -o allure-report --clean")
用例分類
在報告中按功能給用例分類.- @allure.epic 項目名稱
- @allure.feature 模塊名稱
- @allure.story 業務場景名稱
- @allure.title 標題
- @allure.description 描述
- @allure.setup 環境信息
- @allure.testcase 測試用例鏈接
- @allure.issue 缺陷鏈接
- @allure.link 鏈接
@allure.epic("hil測試") @allure.feature("故障注入") @allure.story("CVD") @allure.title("HTO") @allure.description("描述 11") @allure.testcase("https://www.baidu.com", "用例鏈接") @allure.issue("https://www.sogou.com", "缺陷鏈接", ) @allure.link("鏈接") @pytest.mark.ut def test_01():assert 1 == 1@allure.epic("hil測試") @allure.feature("故障注入") @allure.story("CVD") @allure.title("低壓") @allure.description("描述 11") @allure.testcase("www.baidu.com", "用例鏈接") @allure.issue("www.sogou.com", "缺陷鏈接", ) @pytest.mark.ut def test_02():assert 1 == 2@allure.epic("hil測試") @allure.feature("故障注入") @allure.story("HTO") @allure.description("描述 11") @allure.testcase("www.baidu.com", "用例鏈接") @allure.issue("www.sogou.com", "缺陷鏈接", ) @pytest.mark.ut def test_03():assert 1 == 1