Python測試框架Pytest的參數化

上篇博文介紹過,Pytest是目前比較成熟功能齊全的測試框架,使用率肯定也不斷攀升。

在實際工作中,許多測試用例都是類似的重復,一個個寫最后代碼會顯得很冗余。這里,我們來了解一下@pytest.mark.parametrize裝飾器,可以很好解決上述問題。

源代碼分析

def parametrize(self,argnames, argvalues, indirect=False, ids=None, scope=None):""" Add new invocations to the underlying test function using the listof argvalues for the given argnames. Parametrization is performedduring the collection phase. If you need to setup expensive resourcessee about setting indirect to do it rather at test setup time.  # 使用給定argnames的argValue列表向基礎測試函數添加新的調用,在收集階段執行參數化。:arg argnames: a comma-separated string denoting one or more argumentnames, or a list/tuple of argument strings.  # 參數名:使用逗號分隔的字符串,列表或元祖,表示一個或多個參數名:arg argvalues: The list of argvalues determines how often atest is invoked with different argument values. If only oneargname was specified argvalues is a list of values. If Nargnames were specified, argvalues must be a list of N-tuples,where each tuple-element specifies a value for its respectiveargname.  # 參數值:只有一個argnames,argvalues則是值列表。有N個argnames時,每個元祖對應一組argnames,所有元祖組合成一個列表:arg indirect: The list of argnames or boolean. A list of arguments'names (self,subset of argnames). If True the list contains all names fromthe argnames. Each argvalue corresponding to an argname in this list willbe passed as request.param to its respective argname fixturefunction so that it can perform more expensive setups during thesetup phase of a test rather than at collection time.:arg ids: list of string ids, or a callable.If strings, each is corresponding to the argvalues so that they arepart of the test id. If None is given as id of specific test, theautomatically generated id for that argument will be used.If callable, it should take one argument (self,a single argvalue) and returna string or return None. If None, the automatically generated id for thatargument will be used.If no ids are provided they will be generated automatically fromthe argvalues.  # ids:字符串列表,可以理解成標題,與用例個數保持一致:arg scope: if specified it denotes the scope of the parameters.The scope is used for grouping tests by parameter instances.It will also override any fixture-function defined scope, allowingto set a dynamic scope using test context or configuration.  # 如果指定,則表示參數的范圍。作用域用于按參數實例對測試進行分組。它還將覆蓋任何fixture函數定義的范圍,允許使用測試上下文或配置設置動態范圍。"""

argnames

釋義:參數名稱。

格式:字符串"arg1,arg2,arg3"。

aegvalues

釋義:參數值列表。

格式:必須是列表,如[val1,val2,val3]。

  • 單個參數,里面是值的列表,如@pytest.mark.parametrize("name",["Jack","Locus","Bill"]);
  • 多個參數,需要用元祖來存放值,一個元祖對應一組參數的值,如@pytest.mark.parametrize("user,age",[("user1",15),("user2",24),("user3",25)])。

ids

釋義:可以理解為用例的id。

格式:字符串列表,如["case1","case2","case3"]。

indirect

釋義:當indirect=True時,若傳入的argnames是fixture函數名,此時fixture函數名將成為一個可執行的函數,argvalues作為fixture的參數,執行fixture函數,最終結果再存入request.param。

當indirect=False時,fixture函數只作為一個參數名給測試收集階段調用。

備注:這里可以將the setup phase(測試設置階段)理解為配置 conftest.py 階段,將the collection phase(測試收集階段)理解為用例執行階段。

裝飾測試類

import pytestdata = [(2,2,4),(3,4,12)]def add(a,b):return a * b@pytest.mark.parametrize('a,b,expect',data)class TestParametrize(object):def test_parametrize_1(self,a,b,expect):print('\n測試函數1測試數據為\n{}-{}'.format(a,b))assert add(a,b) == expectdef test_parametrize_2(self,a,b,expect):print('\n測試函數2測試數據為\n{}-{}'.format(a,b))assert add(a,b) == expectif __name__ == "__main__":pytest.main(["-s","test_07.py"])
============================= test session starts =============================platform win32 -- Python 3.8.0, pytest-6.2.5, py-1.11.0, pluggy-1.0.0rootdir: D:\AutoCodeplugins: html-3.1.1, metadata-1.11.0collecting ... collected 4 itemstest_07.py::TestParametrize::test_parametrize_1[2-2-4]測試函數1測試數據為2-2PASSEDtest_07.py::TestParametrize::test_parametrize_1[3-4-12]測試函數1測試數據為3-4PASSEDtest_07.py::TestParametrize::test_parametrize_2[2-2-4]測試函數2測試數據為2-2PASSEDtest_07.py::TestParametrize::test_parametrize_2[3-4-12]測試函數2測試數據為3-4PASSED============================== 4 passed in 0.12s ==============================Process finished with exit code 0

由以上代碼可以看到,當裝飾器裝飾測試類時,定義的數據集合會被傳遞給類的所有方法。

裝飾測試函數

單個數據

import pytestdata = ["Rose","white"]@pytest.mark.parametrize("name",data)def test_parametrize(name):print('\n列表中的名字為\n{}'.format(name))if __name__ == "__main__":pytest.main(["-s","test_07.py"])
============================= test session starts =============================platform win32 -- Python 3.8.0, pytest-6.2.5, py-1.11.0, pluggy-1.0.0rootdir: D:\AutoCodeplugins: html-3.1.1, metadata-1.11.0collected 2 itemstest_07.py列表中的名字為Rose.列表中的名字為white.============================== 2 passed in 0.09s ==============================Process finished with exit code 0

當測試用例只需要一個參數時,我們存放數據的列表無序嵌套序列,@pytest.mark.parametrize("name", data) 裝飾器的第一個參數也只需要一個變量接收列表中的每個元素,第二個參數傳遞存儲數據的列表,那么測試用例需要使用同名的字符串接收測試數據(實例中的name)且列表有多少個元素就會生成并執行多少個測試用例。

一組數據

import pytestdata = [[1, 2, 3],[4, 5, 9]] # 列表嵌套列表# data_tuple = [# (1, 2, 3),# (4, 5, 9)# ] # 列表嵌套元組@pytest.mark.parametrize('a, b, expect', data)def test_parametrize_1(a, b, expect): # 一個參數接收一個數據print('\n測試數據為\n{},{},{}'.format(a, b, expect))actual = a + bassert actual == expect@pytest.mark.parametrize('value', data)def test_parametrize_2(value): # 一個參數接收一組數據print('\n測試數據為\n{}'.format(value))actual = value[0] + value[1]assert actual == value[2]if __name__ == "__main__":pytest.main(["-s","test_07.py"])
============================= test session starts =============================platform win32 -- Python 3.8.0, pytest-6.2.5, py-1.11.0, pluggy-1.0.0rootdir: D:\AutoCodeplugins: html-3.1.1, metadata-1.11.0collected 4 itemstest_07.py測試數據為1,2,3.測試數據為4,5,9.測試數據為[1, 2, 3].測試數據為[4, 5, 9].============================== 4 passed in 0.09s ==============================Process finished with exit code 0

當測試用例需要多個數據時,我們可以使用嵌套序列(嵌套元組&嵌套列表)的列表來存放測試數據。

裝飾器@pytest.mark.parametrize()可以使用單個變量接收數據,也可以使用多個變量接收,同樣,測試用例函數也需要與其保持一致。

當使用單個變量接收時,測試數據傳遞到測試函數內部時為列表中的每一個元素或者小列表,需要使用索引的方式取得每個數據。當使用多個變量接收數據時,那么每個變量分別接收小列表或元組中的每個元素列表嵌套多少個多組小列表或元組,測生成多少條測試用例。

組合數據

import pytestdata_1 = [1,2,3]data_2 = ['a','b']@pytest.mark.parametrize('a',data_1)@pytest.mark.parametrize('b',data_2)def test_parametrize_1(a,b):print(f'笛卡爾積測試結果為:{a},{b}')if __name__ == '__main__':pytest.main(["-vs","test_06.py"])

通過測試結果,我們不難分析,一個測試函數還可以同時被多個參數化裝飾器裝飾,那么多個裝飾器中的數據會進行交叉組合的方式傳遞給測試函數,進而生成n * n個測試用例。

標記用例

import pytest@pytest.mark.parametrize("test_input,expected",[("3+5",8),("2+4",6),pytest.param("6 * 9",42,marks=pytest.mark.xfail),pytest.param("6 * 6",42,marks=pytest.mark.skip)])def test_mark(test_input,expected):assert eval(test_input) == expectedif __name__ == '__main__':pytest.main(["-vs","test_06.py"])

輸出結果顯示收集到4個用例,兩個通過,一個被跳過,一個標記失敗:

  • 當我們不想執行某組測試數據時,我們可以標記skip或skipif;
  • 當我們預期某組數據會執行失敗時,我們可以標記為xfail等。

嵌套字典

import pytestdata = ({'user': "name1",'pwd': 123},{'user': "name2",'pwd': 456})@pytest.mark.parametrize('dic',data)def test_parametrize(dic):print('\n測試數據為\n{}'.format(dic))if __name__ == '__main__':pytest.main(["-vs","test_06.py"])

增加測試結果可讀性

參數化裝飾器有一個額外的參數ids,可以標識每一個測試用例,自定義測試數據結果的顯示,為了增加可讀性,我們可以標記每一個測試用例使用的測試數據是什么,適當的增加一些說明。

在使用前你需要知道,ids參數應該是一個字符串列表,必須和數據對象列表的長度保持一致。

import pytestdata_1 = [(1, 2, 3),(4, 5, 9)]ids = ["a:{} + b:{} = expect:{}".format(a, b, expect) for a, b, expect in data_1]def add(a, b):return a + b@pytest.mark.parametrize('a, b, expect', data_1, ids=ids)class TestParametrize(object):def test_parametrize_1(self, a, b, expect):print('\n測試函數1測試數據為\n{}-{}'.format(a, b))assert add(a, b) == expectdef test_parametrize_2(self, a, b, expect):print('\n測試函數2數據為\n{}-{}'.format(a, b))assert add(a, b) == expectif __name__ == '__main__':pytest.main(["-v","test_06.py"])

不加ids參數的返回結果:

加ids參數的返回結果:

我們可以看到帶ids參數的返回結果中的用例都被一個列表明確的標記了,而且通過這種標記可以更加直觀的看出來,每個測試用例使用的數據名稱及測試內容。

同時,在這我為大家準備了一份軟件測試視頻教程(含面試、接口、自動化、性能測試等),就在下方,需要的可以直接去觀看。

【2025最新版】字節大牛講的最全最細的自動化測試全套教程!永久白嫖,拿走不謝,全程干貨無廢話!逼自己15天內學完,從軟件測試基礎到項目實戰一套全通關!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/896951.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/896951.shtml
英文地址,請注明出處:http://en.pswp.cn/news/896951.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

開發博客系統

前言 準備工作 數據庫表分為實體表和關系表 第一,建數據庫表 然后導入前端頁面 創建公共模塊 就是統一返回值,異常那些東西 自己造一個自定義異常 普通類 mapper 獲取全部博客 我們只需要返回id,title,content,us…

【Spring Boot 應用開發】-05 命令行參數

Spring Boot 常用命令行參數 Spring Boot 支持多種命令行參數,這些參數可以在啟動應用時通過命令行直接傳遞。以下是一些常用的命令行參數及其詳細說明: 1. 基本配置參數 --server.port端口號 指定應用程序運行的HTTP端口,默認為8080。 jav…

20250304學習記錄

第一部分,先來了解一下各種論文期刊吧,畢竟也是這把歲數了,還什么都不懂呢 國際期刊: EI收集的主要有兩種, JA:EI源刊 CA:EI會議 CPCI也叫 ISTP 常說的SCI分區是指,JCR的一區、…

2024 年 MySQL 8.0.40 安裝配置、Workbench漢化教程最簡易(保姆級)

首先到官網上下載安裝包:http://www.mysql.com 點擊下載,拉到最下面,點擊社區版下載 windows用戶點擊下面適用于windows的安裝程序 點擊下載,網絡條件好可以點第一個,怕下著下著斷了點第二個離線下載 雙擊下載好的安裝…

網絡安全檢查漏洞內容回復 網絡安全的漏洞

網絡安全的核心目標是保障業務系統的可持續性和數據的安全性,而這兩點的主要威脅來自于蠕蟲的暴發、黑客的攻擊、拒絕服務攻擊、木馬。蠕蟲、黑客攻擊問題都和漏洞緊密聯系在一起,一旦有重大安全漏洞出現,整個互聯網就會面臨一次重大挑戰。雖…

汽車智能鑰匙中PKE低頻天線的作用

PKE(Passive Keyless Entry)即被動式無鑰匙進入系統,汽車智能鑰匙中PKE低頻天線在現代汽車的智能功能和安全保障方面發揮著關鍵作用,以下是其具體作用: 信號交互與身份認證 低頻信號接收:當車主靠近車輛時…

uiautomatorviewer定位元素報Unexpected ... UI hierarchy

發現問題 借鑒博客 Unexpected error while obtaining UI hierarchy android app UI自動化-元素定位輔助工具 Unexpected error while obtaining UI hierarchy:使用uiautomatorviewer定位元素報錯 最近在做安卓自動化,安卓自動化主要工作之一就是獲取UI樹 app端獲…

通俗的方式解釋“零錢兌換”問題

“零錢兌換”是一道經典的算法題目,其主要問題是:給定不同面額的硬幣和一個總金額,求出湊成總金額所需的最少硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回-1。 解題思路 動態規劃:使用動態規劃是解決零錢兌…

GBT32960 協議編解碼器的設計與實現

GBT32960 協議編解碼器的設計與實現 引言 在車聯網領域,GBT32960 是一個重要的國家標準協議,用于新能源汽車與監控平臺之間的數據交互。本文將詳細介紹如何使用 Rust 實現一個高效可靠的 GBT32960 協議編解碼器。 整體架構 編解碼器的核心由三個主要組…

Halcon 車牌識別-超精細教程

車牌示例 流程: 讀取圖片轉灰度圖閾值分割,找車牌內容將車牌位置設置變換區域形狀找到中心點和弧度利用仿射變換,斜切車牌旋轉轉正,把車牌摳出來利用形態學操作拼接車牌號數字訓練ocr開始識別中文車牌 本文章用到的算子(解析) Halcon 算子-承接車牌識別-CSDN博客 rgb1_to_gray…

UDP透傳程序

UDP透傳程序 本腳本用于在 設備 A 和 設備 B 之間建立 UDP 數據轉發橋梁,適用于 A 和 B 設備無法直接通信的情況。 流程: A --> 電腦 (中繼) --> B B --> 電腦 (中繼) --> A 需要修改參數: B_IP “192.168.1.123” # 設備 B 的…

Holtek HT82V42A深度解析:CCD/CIS信號處理的集成化解決方案

——簡化圖像采集系統設計的終極利器 一、HT82V42A核心參數與外設資源 HT82V42A是Holtek專為圖像傳感器信號處理設計的模擬前端芯片,集成CCD/CIS信號處理與LED驅動功能,關鍵參數如下: 參數類別規格說明信號處理通道單通道CCD/CIS模擬信號輸…

詳細分析KeepAlive的基本知識 并緩存路由(附Demo)

目錄 前言1. 基本知識2. Demo2.1 基本2.2 拓展2.3 終極 3. 實戰 前言 🤟 找工作,來萬碼優才:👉 #小程序://萬碼優才/r6rqmzDaXpYkJZF 基本知識推薦閱讀:KeepAlive知識點 從實戰中學習,源自實戰中vue路由的…

記一次誤禁用USB導致鍵盤鼠標失靈的修復過程

背景說明 在電腦上插入了一個USB hub,然后彈窗提示:“集線器端口上出現電涌”,點開讓選擇“重置”或者“關閉”,不小心點了關閉,結果這個usb口就被關了,再插任何東西都沒反應,找了很多辦法都恢…

小米手機如何錄制屏幕?手機、電腦屏幕錄制方法分享

大家最近有沒有遇到想記錄手機屏幕操作的情況? 比如精彩的游戲瞬間、有趣的視頻教程,或者需要錄制屏幕來制作演示材料。小米手機在這方面可是個好幫手,今天就來給你好好嘮嘮,小米手機如何錄制屏幕,以及后續如何處理這…

如何將JAR交由Systemctl管理?

AI越來越火了,我們想要不被淘汰就得主動擁抱。推薦一個人工智能學習網站,通俗易懂,風趣幽默,最重要的屌圖甚多,忍不住分享一下給大家。點擊跳轉到網站 廢話不多說,進入正題。下面開始說如何使用 systemctl…

chrome Vue.js devtools 提示不支持該擴展組件,移除

可能是版本不兼容,可以重新安裝,推薦網址極簡插件官網_Chrome插件下載_Chrome瀏覽器應用商店 直接搜索vue,下載舊版,vue2、vue3都支持,上面那個最新版本試了下,vue2的肯定是不能用

【RabbitMQ】RabbitMQ的核心概念與七大工作模式

🔥個人主頁: 中草藥 🔥專欄:【中間件】企業級中間件剖析 在現代分布式系統和微服務架構中,消息隊列(Message Queue) 是解決服務間通信、系統解耦和流量削峰的關鍵技術之一。而 RabbitMQ 作為一…

SQLAlchemy系列教程:理解SQLAlchemy元數據

SQLAlchemy是Python開發人員的強大ORM工具。SQLAlchemy中的元數據是對象-關系映射配置的集合,允許開發人員無縫地定義和使用數據庫模式。 使用元數據 SQLAlchemy中的元數據充當各種數據庫描述符(如表、列和索引)的容器。這使開發人員能夠通…

MacDroid for Mac v2.3 安卓手機文件傳輸助手 支持M、Intel芯片 4.7K

MacDroid 是Mac毒搜集到的一款安卓手機文件傳輸助手,在Mac和Android設備之間傳輸文件。您只需要將安卓手機使用 USB 連接到 Mac 電腦上即可將安卓設備掛載為本地磁盤,就像編輯mac磁盤上的文件一樣編輯安卓設備上的文件,MacDroid支持所有 Andr…