目錄:導讀
- 前言
- 一、Python編程入門到精通
- 二、接口自動化項目實戰
- 三、Web自動化項目實戰
- 四、App自動化項目實戰
- 五、一線大廠簡歷
- 六、測試開發DevOps體系
- 七、常用自動化測試工具
- 八、JMeter性能測試
- 九、總結(尾部小驚喜)
前言
參數化?
通俗點理解就是,定義一個測試類或測試函數,可以傳入不同測試用例對應的參數,從而執行多個測試用例。
例如:
對登錄接口進行測試,假設有3條用例,正確賬號正確密碼登錄、正確賬號錯誤密碼登錄、錯誤賬號正確密碼登錄,那么我們只需要定義一個登陸測試函數test_login(),然后使用這3條用例對應的參數去調用test_login()即可。
在unittest中可以使用ddt進行參數化,而pytest中也提供非常方便的參數化方式,即使用裝飾器@pytest.mark.parametrize()。
一般寫為pytest.mark.parametrize(“argnames”, argvalues)。
其中:
argnames為參數名稱,可以是單個或多個,多個寫法為"argname1, argname2, …";
argvalues為參數值,類型必須為list(單個參數時可以為元組,多個參數時必須為list,所以最好統一);
例如有下接口:
請求的登陸接口信息:
接口url:http://127.0.0.1:5000/login
請求方式:post
請求參數:
響應信息:
1、單個參數
只需要傳入一個參數時,示例如下:
# 待測試函數
def sum(a):return a+1# 單個參數
data = [1, 2, 3, 4]
@pytest.mark.parametrize("item", data)
def test_add(item):actual = sum(item)print("\n{}".format(actual))# assert actual == 3if __name__ == '__main__':pytest.main()
注意:
@pytest.mark.parametrize()中的第一個參數,必須以字符串的形式來標識測試函數的入參,如上述示例中,定義的測試函數test_login()中傳入的參數名為item,那么@pytest.mark.parametrize()的第一個參數則為"item"。
運行結果如下:
rootdir: E:\blog\python接口自動化\apiAutoTest, configfile: pytest.ini
plugins: html-2.1.1, metadata-1.10.0, ordering-0.6, rerunfailures-9.1.1
collecting ... collected 4 itemstest_case_2.py::test_add[1] PASSED [ 25%]
2test_case_2.py::test_add[2] PASSED [ 50%]
3test_case_2.py::test_add[3] PASSED [ 75%]
4test_case_2.py::test_add[4] PASSED [100%]
5============================== 4 passed in 0.02s ==============================
從結果可以看到,測試函數分別傳入了data中的參數,總共執行了5次。
2、多個參數
測試用例需傳入多個參數時,@pytest.mark.parametrize() 的第一個參數同樣是字符串, 對應用例的多個參數用逗號分隔。
示例:
import pytest
import requests
import json# 列表嵌套元組
data = [("lilei", "123456"), ("hanmeimei", "888888")]
# 列表嵌套列表
# data = [["lilei", "123456"], ["hanmeimei", "888888"]]@pytest.mark.parametrize("username, password", data)
def test_login(username, password):headers = {"Content-Type": "application/json;charset=utf8"}url = "http://127.0.0.1:5000/login"_data = {"username": username,"password": password}res = requests.post(url=url, headers=headers, json=_data).textres = json.loads(res)assert res['code'] == 1000if __name__ == '__main__':pytest.main()
需要注意:
代碼中data的格式,可以是列表嵌套列表,也可以是列表嵌套元組,列表中的每個列表或元組代表一組獨立的請求參數。
"username, password"不能寫成 “username”, “password”。
運行結果如下:
從結果中我們還可以看到每次執行傳入的參數,如下劃線所示部分。
這里所舉示例是2個參數,傳入3個或更多參數時,寫法也同樣如此,一定要注意它們之間一一對應的關系,如下圖:
3、對測試類參數化
上面所舉示例都是對測試函數進行參數化,那么對測試類怎么進行參數化呢?
其實,對測試類的參數化,就是對測試類中的測試方法進行參數化。
@pytest.mark.parametrize()中標識的參數個數,必須與類中的測試方法的參數一致。示例如下:
# 將登陸接口請求單獨進行了封裝,僅僅只是為了方便下面的示例
def login(username, password):headers = {"Content-Type": "application/json;charset=utf8"}url = "http://127.0.0.1:5000/login"_data = {"username": username,"password": password}res = requests.post(url=url, headers=headers, json=_data).textres = json.loads(res)return res# 測試類參數化
data = [("lilei", "123456"), ("hanmeimei", "888888")
]
@pytest.mark.parametrize("username, password", data)
class TestLogin:def test_login_01(self, username, password):res = login(username, password)assert res['code'] == 1000def test_login_02(self, username, password):res = login(username, password)assert res['msg'] == "登錄成功!"if __name__ == '__main__':pytest.main(["-s"])
運行結果如下:
從結果中可以看出來,總共執行了4次,測試類中的每個測試方法都執行了2次,即每個測試方法都將data中的每一組參數都執行了一次。
注意:
這里還是要強調參數對應的關系,即@pytest.mark.parametrize()中的第一個參數,需要與測試類下面的測試方法的參數一一對應。
4、參數組合
在編寫測試用例的過程中,有時候需要將參數組合進行接口請求,如示例的登錄接口中username有 lilei、hanmeimei,password有 123456、888888,進行組合的話有下列四種情況:
{"username": "lilei", "password": "123456"}
{"username": "lilei", "password": "888888"}
{"username": "hanmeimei", "password": "123456"}
{"username": "hanmeimei", "password": "888888"}
在@pytest.mark.parametrize()也提供了這樣的參數組合功能,編寫格式示例如下:
import pytest
import requests
import jsonusername = ["lilei", "hanmeimei"]
password = ["123456", "888888"]@pytest.mark.parametrize("password", password)
@pytest.mark.parametrize("username", username)
def test_login(username, password):headers = {"Content-Type": "application/json;charset=utf8"}url = "http://127.0.0.1:5000/login"_data = {"username": username,"password": password}res = requests.post(url=url, headers=headers, json=_data).textres = json.loads(res)assert res['code'] == 1000if __name__ == '__main__':pytest.main()
運行結果如下:
rootdir: E:\blog\python接口自動化\apiAutoTest, configfile: pytest.ini
plugins: html-2.1.1, metadata-1.10.0, ordering-0.6, rerunfailures-9.1.1
collecting ... collected 4 itemstest_case_5.py::test_login[lilei-123456] PASSED [ 25%]
test_case_5.py::test_login[lilei-888888] FAILED [ 50%]
test_case_5.py::test_login[hanmeimei-123456] FAILED [ 75%]
test_case_5.py::test_login[hanmeimei-888888] PASSED [100%]
=========================== short test summary info ===========================
FAILED test_case_5.py::test_login[lilei-888888] - assert 1001 == 1000
FAILED test_case_5.py::test_login[hanmeimei-123456] - assert 1001 == 1000
========================= 2 failed, 2 passed in 0.18s =========================
從結果可以看出來,2個username、2個password 有4中組合方式,總執行了4次。如果是3個username、2個password,那么就有6中參數組合方式,依此類推。
注意:
以上這些示例中的測試用例僅僅只是用于舉例,實際項目中的登錄接口測試腳本與測試數據會不一樣。
5、增加測試結果可讀性
從示例的運行結果中我們可以看到,為了區分參數化的運行結果,在結果中都會顯示由參數組合而成的執行用例名稱,很方便就能看出來執行了哪些參數組合的用例。
示例:
但這只是簡單的展示,如果參數多且復雜的話,僅僅這樣展示是不夠清晰的,需要添加一些說明才能一目了然。
因此,在@pytest.mark.parametrize()中有兩種方式來自定義上圖中劃線部分的顯示結果,即使用@pytest.mark.parametrize()提供的參數 ids 自定義,或者使用pytest.param()中的參數id自定義。
ids(推薦)
ids使用方法示例如下:
import pytest
import requests
import jsondata = [("lilei", "123456"), ("hanmeimei", "888888")]
ids = ["username:{}-password:{}".format(username, password) for username, password in data]
@pytest.mark.parametrize("username, password", data, ids=ids)
def test_login(username, password):headers = {"Content-Type": "application/json;charset=utf8"}url = "http://127.0.0.1:5000/login"_data = {"username": username,"password": password}res = requests.post(url=url, headers=headers, json=_data).textres = json.loads(res)assert res['code'] == 1000if __name__ == '__main__':pytest.main()
從編寫方式可以看出來,ids就是一個list,且它的長度與參數組合的分組數量一致。
運行結果如下:
比較上面個執行結果,我們能看出ids自定義執行結果與默認執行結果展示的區別。使用過程中,需要根據實際情況來自定義。
id
使用方式示例如下:
import pytest
import requests
import jsondata = [pytest.param("lilei", "123456", id="correct username and correct password"),pytest.param("lilei", "111111", id="correct user name and wrong password")
]@pytest.mark.parametrize("username, password", data)
def test_login(username, password):headers = {"Content-Type": "application/json;charset=utf8"}url = "http://127.0.0.1:5000/login"_data = {"username": username,"password": password}res = requests.post(url=url, headers=headers, json=_data).textres = json.loads(res)assert res['code'] == 1000if __name__ == '__main__':pytest.main()
運行結果如下:
下面是我整理的2023年最全的軟件測試工程師學習知識架構體系圖 |
一、Python編程入門到精通
二、接口自動化項目實戰
三、Web自動化項目實戰
四、App自動化項目實戰
五、一線大廠簡歷
六、測試開發DevOps體系
七、常用自動化測試工具
八、JMeter性能測試
九、總結(尾部小驚喜)
奮斗是一段漫長的旅程,痛苦與磨難只是通往成功的試煉。不懼困難,堅守信念,用汗水澆灌夢想的花朵。相信自己,勇往直前,你將創造屬于自己的輝煌,留下無悔的足跡!
執著的火焰燃燒內心,不屈的勇氣驅散黑暗。放下畏懼,迎接挑戰,奮斗的腳步不停歇。每一次努力鑄就堅韌,每一次拼搏開啟新篇章。勇往直前,追逐夢想。
人生的舞臺,唯有奮斗才能譜寫出絢麗的樂章。不要畏懼困難,要勇敢地迎接挑戰。堅持努力,永不放棄,相信自己的力量,你將創造出意想不到的精彩人生!