一、前言
Pytest測驗框架中的fixture,可以將自動化測驗用例中的前置、后置部分分離出來放入其中,然后在寫測驗用例的時候只需要寫測驗邏輯相關的代碼,提高代碼的復用性,同時也有利于代碼的維護,
本文重點介紹的是fixture引數化,關于fixture的基礎知識可以查看這個鏈接:https://www.cnblogs.com/zdx20/p/14948134.html
二、測驗場景介紹
我們以下面App自動化測驗,訂酒店的測驗場景為例,來說明:

上圖中有三個測驗場景:
1、編輯姓名;
2、編輯手機號;
3、編輯身份證,
這三個場景主要的測驗邏輯都在酒店的編輯訂單頁,通過fixture引數化功能可以很好的精簡測驗代碼,
三、fixture和fixture引數化
1、按照上面的流程撰寫自動化測驗用例:
import pytest
login_data = [{"user_name": "xiaowang", "pwd": 123456, "date": 1, "name": "小王"}]
@pytest.mark.parametrize("test_data", login_data)
def test_hotel(test_data):
# 登錄App
print("\n" + "1、登錄App, 賬號和密碼是:", test_data["user_name"], test_data["pwd"])
# 酒店首頁選擇入住日期
print("2、酒店首頁選擇日期:{}號".format(test_data["date"]))
# 酒店串列選擇酒店
print("3、選擇想要預訂的酒店和房型")
# 編輯酒店頁面,輸入入住人姓名
print("4、輸入入住人姓名:", test_data["name"])
# 斷言下單結果
print("5、恭喜,酒店預訂成功了!!!")
上面的用例就是沒有使用前置/后置分離代碼,雖然可以完成UI自動化測驗的一個測驗場景任務,但是后續用例多了維護會非常頭疼,而且不具有擴展性,
2、fixture的前置、后置
在每條用例中都需要登錄App,然后執行測驗程序,最后斷言測驗結果,我們可以將登錄,和測驗結果斷言剝離出來放在fixture當中,這樣同型別的測驗場景就可以直接呼叫,
import pytest
hotel_data = [{"date": 1, "name": "小王"}]
@pytest.fixture()
def fix_login():
# 登錄App
print("\n" + "1、前置條件--登錄App, 賬號和密碼是:", "xiaowang", 123456)
yield
# 斷言下單結果
print("5、后置條件--恭喜,酒店預訂成功了!!!")
@pytest.mark.parametrize("test_data", hotel_data) # 測驗資料的引數化
def test_hotel(test_data, fix_login):
# 酒店首頁選擇入住日期
print("2、酒店首頁選擇日期:{}號".format(test_data["date"]))
# 酒店串列選擇酒店
print("3、選擇想要預訂的酒店和房型")
# 編輯酒店頁面,輸入入住人姓名
print("4、輸入入住人姓名:", test_data["name"])
執行結果如下:
1、前置條件--登錄App, 賬號和密碼是: xiaowang 123456
2、酒店首頁選擇日期:1號
3、選擇想要預訂的酒店和房型
4、輸入入住人姓名: 小王
5、后置條件--恭喜,酒店預訂成功了!!!
上面的測驗用例方法中,測驗資料是通過@pytest.mark.parametrize()傳入的,有幾組測驗資料就會生成幾條測驗用例,詳細的使用方法可以查看“前言”部分提到的鏈接,
3、fixture引數化
通過fixture我們將用例的前置和后置條件摘出來了,但是前置條件登錄的資料是固定的,通用性不強,需要將fixture的測驗資料也引數化,
fixture引數化傳參的方法與用例的傳參是一樣的,也是使用@pytest.mark.parametrize()傳入,但是需要加一個引數:indirect=True,指定將引數傳入fixture測驗夾具中,fixture測驗夾具的方法中使用request接受傳入的引數,然后通過request.param使用具體的資料,
import pytest
login_data = [{"user_name": "xiaowang", "pwd": 1234}, {"user_name": "zhaosi", "pwd": 6789}]
test_data = [{"date": 1, "name": "小王"}]
@pytest.fixture()
def fix_login(request):
# 接收傳入的資料
test_info = request.param
# 登錄App
print("\n" + "1、前置條件--登錄App, 賬號和密碼是:", test_info["user_name"], test_info["pwd"])
yield
# 斷言下單結果
print("5、后置條件--恭喜,酒店預訂成功了!!!")
@pytest.mark.parametrize("fix_login", login_data, indirect=True) # fixture測驗夾具的引數化
@pytest.mark.parametrize("test_info", test_data) # 測驗用例的引數化
def test_hotel(test_info, fix_login):
# 酒店首頁選擇入住日期
print("2、酒店首頁選擇日期:{}號".format(test_info["date"]))
# 酒店串列選擇酒店
print("3、選擇想要預訂的酒店和房型")
# 編輯酒店頁面,輸入入住人姓名
print("4、輸入入住人姓名:", test_info["name"])
上面登錄的前置條件中,傳入了兩組賬號、密碼資料,那么在執行用例時,同一個用例場景會分別使用兩個賬號測驗一遍,
同時等到兩個執行結果:

fixture引數化,需要注意接收引數的識別符號,用例中呼叫測驗夾具的識別符號,以及測驗夾具的方法名要一致,

現在測驗場景只寫了一個:編輯姓名,后面的編輯手機號、編輯身份證號兩個場景,直接套用現有的測驗用例即可,
4、拆分多個fixture
前面提到我們需要測驗的三個酒店場景,前面幾個步驟“酒店首頁”、“酒店串列頁”都是一樣的,而且后續還有其他用例也需要用到“酒店首頁”或者“酒店串列頁”,因此我們需要不同頁面的前置條件來滿足不同測驗場景,這就有了很多個測驗夾具,不利于代碼的維護,我們可以按照一個頁面一個前置夾具的方法來細分測驗場景,寫用例時按照順序去呼叫即可,
import pytest
login_data = [{"user_name": "xiaowang", "pwd": 1234}]
test_data = [{"date": 11, "name": "小王", "result_data": "通過"}]
@pytest.fixture()
def fix_login(request):
# 接收傳入的資料
test_info = request.param
# 登錄App
print("\n" + "1、前置條件--登錄App, 賬號和密碼是:", test_info["user_name"], test_info["pwd"])
@pytest.fixture()
def home_page(request):
# 接收傳入的資料
test_info = request.param
# 酒店首頁選擇入住日期
print("2、酒店首頁選擇日期:{}號".format(test_info["date"]))
@pytest.fixture()
def list_page():
# 酒店串列選擇酒店
print("3、選擇想要預訂的酒店和房型")
@pytest.fixture()
def result(request):
yield
# 接收傳入的資料
test_info = request.param
# 斷言下單結果
print("5、后置條件--恭喜,酒店預訂成功了,結果:{}!!!".format(test_info["result_data"]))
@pytest.mark.parametrize("result", test_data, indirect=True)
@pytest.mark.parametrize("home_page", test_data, indirect=True)
@pytest.mark.parametrize("fix_login", login_data, indirect=True)
@pytest.mark.parametrize("test_info", test_data)
def test_name(test_info, fix_login, home_page, list_page, result):
# 編輯酒店頁面,輸入入住人姓名
print("4、輸入入住人姓名:", test_info["name"])
執行結果如下:
1、前置條件--登錄App, 賬號和密碼是: xiaowang 1234
2、酒店首頁選擇日期:11號
3、選擇想要預訂的酒店和房型
4、輸入入住人姓名: 小王
5、后置條件--恭喜,酒店預訂成功了,結果:通過!!!
###注意:在測驗用例方法中同時呼叫多個fixture夾具時,一定要按照測驗邏輯順序來,執行用例時會按照測驗夾具呼叫先后順序執行,

4.1、fixture測驗夾具添加順序
測驗用例方法中呼叫測驗夾具時需要注意先后順序,不然測驗邏輯會混亂,如果你不想在呼叫時出現這個問題,可以在撰寫多個測驗夾具時,測驗夾具之間按照邏輯先后順序呼叫,這樣在寫用例時就不用考慮先后順序問題,而且不需要傳參的測驗夾具不用呼叫也能執行,

測驗用例方法呼叫:

四、fixture和fixture引數化
1、fixture的params引數
fixture測驗夾具的引數化除了上面用到的@pytest.mark.parametrize(),還有一種是直接在測驗夾具的fixture中傳參,使用params=即可,
import pytest
login_data = [{"user_name": "xiaowang", "pwd": 1234}, {"user_name": "zhaosi", "pwd": 6789}]
test_data = [{"date": 1, "name": "小王"}]
@pytest.fixture(params=login_data) # fixture測驗夾具的引數化
def fix_login(request):
# 接收傳入的資料
test_info = request.param
# 登錄App
print("\n" + "1、前置條件--登錄App, 賬號和密碼是:", test_info["user_name"], test_info["pwd"])
yield
# 斷言下單結果
print("5、后置條件--恭喜,酒店預訂成功了!!!")
@pytest.mark.parametrize("test_info", test_data) # 測驗用例的引數化
def test_hotel(test_info, fix_login):
# 酒店首頁選擇入住日期
print("2、酒店首頁選擇日期:{}號".format(test_info["date"]))
# 酒店串列選擇酒店
print("3、選擇想要預訂的酒店和房型")
# 編輯酒店頁面,輸入入住人姓名
print("4、輸入入住人姓名:", test_info["name"])
fixture的引數化就介紹到這里,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/296093.html
標籤:其他
