pytest實(shí)戰(zhàn)技巧之參數(shù)化基本用法和多種方式
pytest是Python中最流行的測(cè)試框架之一。它提供了豐富的功能,可以幫助我們編寫高效、可靠的測(cè)試用例。其中一個(gè)重要的功能就是參數(shù)化,它可以讓我們用不同的數(shù)據(jù)組合來(lái)運(yùn)行同一個(gè)測(cè)試用例,從而 提高測(cè)試覆蓋率和效率。本文將介紹pytest參數(shù)化的基本用法和一些高級(jí)技巧,幫助讀者更好地使用這個(gè)功能。
01、基本用法
pytest參數(shù)化的基本用法非常簡(jiǎn)單,只需要在測(cè)試函數(shù)上添加一個(gè)裝飾器@pytest.mark.parametrize, 然后指定參數(shù)名稱和參數(shù)值列表即可。例如,我們有一個(gè)測(cè)試函數(shù)test_add,用來(lái)測(cè)試兩個(gè)數(shù)相加的結(jié)果是否正確:
def test_add(): assert add(2, 3) == 5 assert add(-1, 1) == 0
現(xiàn)在我們想用多組數(shù)據(jù)來(lái)運(yùn)行這個(gè)測(cè)試函數(shù),可以這樣做:
import pytest @pytest.mark.parametrize("a, b, expected", [ (2, 3, 5), (-1, 1, 0), (0, 0, 0), (100, -100, 0), ]) def test_add(a, b, expected): assert add(a, b) == expected
這里我們定義了一個(gè)參數(shù)化裝飾器,指定了三個(gè)參數(shù)名稱a、b和expected,以及一個(gè)參數(shù)值列表,其中每個(gè)元素都是一個(gè)包含三個(gè)值的元組,分別代表兩個(gè)數(shù)和它們的和。這樣,pytest就會(huì)根據(jù)這個(gè)參數(shù)值列表,自動(dòng)運(yùn)行測(cè)試函數(shù)四次,每次用一個(gè)元組中的數(shù)據(jù)來(lái)替換a、b和expected參數(shù),然后執(zhí)行斷言操作,最后輸出測(cè)試結(jié)果。
02、參數(shù)化的多種方式
除了上面的方式,pytest還支持多種參數(shù)化的方式,可以根據(jù)實(shí)際情況選擇最合適的一種。
參數(shù)值列表
我們已經(jīng)看到了最簡(jiǎn)單的參數(shù)化方式,就是將多組參數(shù)值放在一個(gè)列表中,然后傳給裝飾器。這種方式適用于參數(shù)比較少、每個(gè)參數(shù)值都比較獨(dú)立的情況。如果參數(shù)值之間有一定的關(guān)聯(lián)性,或者參數(shù)比較 多,就不太適合使用這種方式了。
參數(shù)名稱列表
有時(shí)我們希望將參數(shù)值列表和參數(shù)名稱列表分開定義,這樣可以更清晰地表達(dá)參數(shù)之間的關(guān)系。例如, 我們有一個(gè)函數(shù)用來(lái)測(cè)試字符串是否包含某個(gè)子串,可以這樣寫:
@pytest.mark.parametrize("s, sub, expected", [ ("hello world", "hello", True), ("hello world", "world", True), ("hello world", "python", False), ]) def test_contains(s, sub, expected): assert (sub in s) == expected
這里我們將參數(shù)名稱s、sub和expected分別和參數(shù)值列表中的元組對(duì)應(yīng)起來(lái),這樣就可以更直觀地理解 每個(gè)參數(shù)的含義。
注意,參數(shù)名稱列表也可以是一個(gè)字符串,多個(gè)參數(shù)名稱之間用逗號(hào)隔開,例如:"a, b, expected"。
參數(shù)化裝飾器嵌套
有時(shí)我們需要對(duì)多個(gè)參數(shù)進(jìn)行組合,這時(shí)可以使用參數(shù)化裝飾器的嵌套。例如,我們有一個(gè)函數(shù)用來(lái)測(cè)試兩個(gè)字符串連接后的結(jié)果是否正確,可以這樣寫:
@pytest.mark.parametrize("s1", ["hello", "world"]) @pytest.mark.parametrize("s2", ["python", "pytest"]) def test_concat(s1, s2): assert concat(s1, s2) == s1 + s2
這里我們先用一個(gè)參數(shù)化裝飾器指定s1參數(shù)的取值范圍,然后在這個(gè)裝飾器內(nèi)部再嵌套一個(gè)參數(shù)化裝飾器,指定s2參數(shù)的取值范圍。這樣,pytest就會(huì)自動(dòng)運(yùn)行測(cè)試函數(shù)四次,每次用一個(gè)s1和一個(gè)s2的組合 來(lái)測(cè)試函數(shù)的正確性。
參數(shù)化函數(shù)
有時(shí)我們需要?jiǎng)討B(tài)生成參數(shù)值列表,這時(shí)可以使用參數(shù)化函數(shù)。例如,我們有一個(gè)函數(shù)用來(lái)測(cè)試一個(gè)整數(shù)是否為質(zhì)數(shù),可以這樣寫:
def is_prime(n): if n < 2: return False for i in range(2, int(n ** 0.5) + 1): if n % i == 0: return False return True @pytest.mark.parametrize("n", range(10)) def test_is_prime(n): assert is_prime(n) == (n in [2, 3, 5, 7])
這里我們使用了Python內(nèi)置的range函數(shù)來(lái)生成一個(gè)整數(shù)序列,然后將這個(gè)序列作為參數(shù)值列表傳給了參數(shù)化裝飾器。這樣,pytest就會(huì)自動(dòng)運(yùn)行測(cè)試函數(shù)十次,每次用一個(gè)整數(shù)來(lái)測(cè)試函數(shù)的正確性。
從文件讀取參數(shù)
有時(shí)我們需要從外部文件中讀取參數(shù)值列表,這時(shí)可以使用pytest的fixture機(jī)制。例如,我們有一個(gè)CSV文件,包含了多組數(shù)據(jù),每組數(shù)據(jù)都是一個(gè)整數(shù)和一個(gè)字符串,用逗號(hào)隔開。我們希望用這些數(shù)據(jù) 來(lái)測(cè)試一個(gè)函數(shù),可以這樣寫:
import csv import pytest @pytest.fixture(scope="module") def data(): with open("test_data.csv") as f: reader = csv.reader(f) return list(reader) @pytest.mark.parametrize("n, s", data()) def test_func(n, s): assert func(n, s) == ...
這里我們定義了一個(gè)fixture函數(shù)data,用來(lái)讀取CSV文件中的數(shù)據(jù),并返回一個(gè)列表,每個(gè)元素都是一 個(gè)包含兩個(gè)值的元組。然后在測(cè)試函數(shù)的參數(shù)化裝飾器中,使用data()來(lái)獲取這個(gè)列表,并將其中的元 組分別賦值給n和s兩個(gè)參數(shù)。這樣,pytest就會(huì)自動(dòng)運(yùn)行測(cè)試函數(shù)多次,每次用一個(gè)元組中的數(shù)據(jù)來(lái)測(cè) 試函數(shù)的正確性。
03、參數(shù)化的高級(jí)技巧
除了上面介紹的基本用法和多種方式,pytest參數(shù)化還有一些高級(jí)技巧,可以幫助我們更靈活地使用這個(gè)功能。
動(dòng)態(tài)生成參數(shù)名稱
有時(shí)我們需要?jiǎng)討B(tài)生成參數(shù)名稱,例如根據(jù)參數(shù)值來(lái)生成一個(gè)唯一的標(biāo)識(shí)符。這時(shí)可以使用pytest的ids 參數(shù),它可以指定每個(gè)參數(shù)值對(duì)應(yīng)的參數(shù)名稱。例如,我們有一個(gè)函數(shù)用來(lái)測(cè)試兩個(gè)字符串連接后的長(zhǎng)度是否正確,可以這樣寫:
@pytest.mark.parametrize("s1, s2, expected", [ ("hello", "world", 10), ("pytest", "is awesome", 15), ], ids=["case1", "case2"]) def test_len(s1, s2, expected): assert len(concat(s1, s2)) == expected
這里我們使用了ids參數(shù),將每個(gè)參數(shù)值對(duì)應(yīng)的參數(shù)名稱指定為了一個(gè)字符串,分別 是"case1"和"case2"。這樣,pytest就會(huì)在測(cè)試結(jié)果中顯示這些參數(shù)名稱,方便我們查看和分析測(cè)試結(jié)果。
參數(shù)化的組合
有時(shí)我們需要對(duì)多個(gè)參數(shù)進(jìn)行組合,例如測(cè)試一個(gè)函數(shù)在不同參數(shù)組合下的正確性。這時(shí)可以使用pytest的product參數(shù)化,它可以將多個(gè)參數(shù)值列表進(jìn)行組合,生成所有可能的參數(shù)組合。
例如,我們有一個(gè)函數(shù)用來(lái)測(cè)試兩個(gè)整數(shù)相乘的結(jié)果是否正確,可以這樣寫:
@pytest.mark.parametrize("a", [1, 2, 3]) @pytest.mark.parametrize("b", [4, 5, 6]) def test_mul(a, b): assert mul(a, b) == a * b @pytest.mark.parametrize("a, b", product([1, 2, 3], [4, 5, 6])) def test_mul2(a, b): assert mul(a, b) == a * b
這里我們先用兩個(gè)參數(shù)化裝飾器分別指定a和b的取值范圍,然后在測(cè)試函數(shù)中用a和b的乘積來(lái)進(jìn)行斷 言。這樣,pytest就會(huì)自動(dòng)運(yùn)行測(cè)試函數(shù)九次,每次用一個(gè)a和一個(gè)b的組合來(lái)測(cè)試函數(shù)的正確性。另 外,我們還可以使用product函數(shù)來(lái)完成同樣的功能,它可以將多個(gè)參數(shù)值列表進(jìn)行組合,并返回所有可能的參數(shù)組合。
動(dòng)態(tài)生成參數(shù)化裝飾器
有時(shí)我們需要根據(jù)某些條件動(dòng)態(tài)生成參數(shù)化裝飾器,例如根據(jù)某個(gè)配置文件中的參數(shù)來(lái)決定測(cè)試函數(shù)的參數(shù)取值范圍。這時(shí)可以使用pytest的fixture機(jī)制,動(dòng)態(tài)生成參數(shù)化裝飾器。
例如,我們有一個(gè)配置文件,包含了兩個(gè)參數(shù)s和n,分別表示一個(gè)字符串和一個(gè)整數(shù),我們希望用這些參數(shù)來(lái)測(cè)試一個(gè)函數(shù),可 以這樣寫:
import yaml import pytest @pytest.fixture(scope="module") def config(): with open("test_config.yaml") as f: return yaml.safe_load(f) @pytest.fixture(scope="module") def params(config): return [(s, n) for s in config["strings"] for n in config["numbers"]] def test_func(params): for s, n in params: assert func(s, n) == ...
這里我們定義了兩個(gè)fixture函數(shù),config和params。
- config用來(lái)讀取配置文件中的參數(shù)
- params用來(lái)根據(jù)這些參數(shù)動(dòng)態(tài)生成參數(shù)值列表
然后在測(cè)試函數(shù)中,使用params來(lái)獲取參數(shù)值列表,并將其中的元 組分別賦值給s和n兩個(gè)參數(shù)。這樣,pytest就會(huì)自動(dòng)運(yùn)行測(cè)試函數(shù)多次,每次用一個(gè)元組中的數(shù)據(jù)來(lái)測(cè)試函數(shù)的正確性。
04、總結(jié)
本文介紹了pytest參數(shù)化的基本用法和多種方式,幫助讀者更好地使用這個(gè)功能。同時(shí),還介紹了一些高級(jí)技巧,如動(dòng)態(tài)生成參數(shù)名稱、參數(shù)化的組合和動(dòng)態(tài)生成參數(shù)化裝飾器,幫助讀者更靈活地使用參數(shù) 化。通過(guò)學(xué)習(xí)本文,讀者可以更好地理解pytest參數(shù)化的原理和用法,從而編寫更高效、可靠的測(cè)試用例。
到此這篇關(guān)于pytest實(shí)戰(zhàn)技巧之參數(shù)化應(yīng)用的文章就介紹到這了,更多相關(guān)pytest參數(shù)化應(yīng)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python中pytest的參數(shù)化實(shí)例解析
- pytest使用@pytest.mark.parametrize()實(shí)現(xiàn)參數(shù)化的示例代碼
- pytest?fixtures函數(shù)及測(cè)試函數(shù)的參數(shù)化解讀
- pytest使用parametrize將參數(shù)化變量傳遞到fixture
- Python基礎(chǔ)教程之pytest參數(shù)化詳解
- pytest實(shí)現(xiàn)測(cè)試用例參數(shù)化
- Pytest單元測(cè)試框架如何實(shí)現(xiàn)參數(shù)化
- Pytest參數(shù)化parametrize使用代碼實(shí)例
- pytest參數(shù)化:@pytest.mark.parametrize詳解
相關(guān)文章
零基礎(chǔ)寫python爬蟲之使用Scrapy框架編寫爬蟲
前面的文章我們介紹了Python爬蟲框架Scrapy的安裝與配置等基本資料,本文我們就來(lái)看看如何使用Scrapy框架方便快捷的抓取一個(gè)網(wǎng)站的內(nèi)容,隨便選個(gè)小站(dmoz.org)來(lái)示例吧2014-11-11簡(jiǎn)單的Python的curses庫(kù)使用教程
這篇文章主要介紹了簡(jiǎn)單的Python的curses庫(kù)使用教程,來(lái)自IBM官方開發(fā)者技術(shù)文檔,需要的朋友可以參考下2015-04-04Python 實(shí)現(xiàn)簡(jiǎn)單的shell sed替換功能(實(shí)例講解)
下面小編就為大家?guī)?lái)一篇Python 實(shí)現(xiàn)簡(jiǎn)單的shell sed替換功能(實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09python+html實(shí)現(xiàn)免費(fèi)在線行為驗(yàn)證保護(hù)賬號(hào)安全
這篇文章主要為大家介紹了python+html免費(fèi)在線行為驗(yàn)證保護(hù)賬號(hào)安全實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09八個(gè)超級(jí)好用的Python自動(dòng)化腳本(小結(jié))
每天你都可能會(huì)執(zhí)行許多重復(fù)的任務(wù),例如閱讀新聞、發(fā)郵件、查看天氣、打開書簽、清理文件夾等等,本文主要介紹了Python自動(dòng)化腳本,具有一定的參考價(jià)值,感興趣的可以了解一下2022-07-07Python基于time模塊求程序運(yùn)行時(shí)間的方法
這篇文章主要介紹了Python基于time模塊求程序運(yùn)行時(shí)間的方法,涉及Python time模塊的使用及數(shù)值運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下2017-09-09