一、前言
為了提高代碼的復用性,我們在寫用例的時候,會用到函數,然后不同的用例去調用這個函數。
比如登錄操作,大部分用例都會先登錄,那就需要把登錄單獨抽出來寫一個函數,其他用例全部都調用這個登錄函數就行。
但是登錄的賬號不能寫死,有時候我想用賬號1去登錄,執行用例1,用賬號2去登錄執行用例2,所以需要對函數傳參。
二、登錄函數傳參
把登錄單獨成立,寫一個函數,傳2個參數user和psw,寫用例的時候調用登錄函數,輸入幾組user,psw參數化登錄用例。
測試用例傳參需要用裝飾器@pytest.mark.parametrize,里面寫兩個參數。
第一個參數是字符串,多個參數中間用逗號隔開;
第二個參數是list,多組數據用元組類型。
import pytest # 測試登錄數據 test_login_data = [("admin","111111"),("admin","")] def login(user,psw): """普通登錄函數""" print("登錄賬號:%s"%user) print("登錄密碼:%s"%psw) if psw: return True else: return False @pytest.mark.parametrize("user,psw",test_login_data) def test_login(user,psw): """登錄用例""" result = login(user,psw) assert result == True,"失敗原因:密碼為空" if __name__ == "__main__": pytest.main(["-s","test_login.py"])
運行結果:
三、request參數
如果想把登錄插座放在前置操作里,也就是用到@pytest.fixture裝飾器,傳參就用默認的request參數。
user = request.param這一步是接收傳入的參數,本案例是傳一個參數情況。
import pytest # 測試賬號數據 test_user_data = ["admin1","admin2"] @pytest.fixture(scope="module") def login(request): user = request.param print("登錄賬號:%s"%user) return user @pytest.mark.parametrize("login",test_user_data,indirect=True) def test_login(login): """登錄用例""" a = login print("測試用例中login的返回值:%s"%a) assert a != "" if __name__ == "__main__": pytest.main(["-s","test_login2.py"])
運行結果:
添加indirect = True參數是為了把login當成一個函數去執行,而不是一個參數。
四、request傳兩個參數
如果用到@pytest.fixture,里面用2個參數情況,可以把多個參數用一個字段去存儲,這樣最終還只傳一個參數。
不同的參數再從字典里面取對應key值就行,如:user = request.param["user"]
import pytest # 測試賬號數據 test_user_data = [{"user":"admin1","psw":"1111111"}, {"user":"admin2","psw":""}] @pytest.fixture(scope="module") def login(request): user = request.param["user"] psw = request.param["psw"] print("登錄用戶:%s"%user) print("登錄密碼:%s"%psw) if psw: return True else: return False # indirect = True 聲明login是個函數 @pytest.mark.parametrize("login",test_user_data,indirect=True) def test_login(login): """登錄用例""" a = login print("測試用例中login的返回值:%s"%a) assert a,"失敗原因:密碼為空" if __name__=="__main__": pytest.main(["-s","test_login3.py"])
運行結果:
E AssertionError: 失敗原因:密碼為空
E assert False
如果要用到login里面的返回值,def test_login(login)時,傳入login參數,函數返回值就是login了。
五、多個fixture
用例上面是可以同時放多個fixture的,也就是多個前置操作,可以支持修飾器疊加,使用parametrize裝飾器疊加時,用例組合是2個參數個數相乘。
import pytest # 測試賬號數據 test_user = ["admin1","admin2"] test_psw = ["111111","222222"] @pytest.fixture(scope="module") def input_user(request): user = request.param print("登錄用戶:%s"%user) return user @pytest.fixture(scope="module") def input_psw(request): psw = request.param print("登錄密碼:%s"%psw) return psw @pytest.mark.parametrize("input_user",test_user,indirect=True) @pytest.mark.parametrize("input_psw",test_psw,indirect=True) def test_login(input_user,input_psw): """登錄用例""" a = input_user b = input_psw print("測試數據a-> %s,b-> %s"%(a,b)) assert b if __name__=="__main__": pytest.main(["-s","test_login4.py"])
運行結果:
如果參數user有2個數據,參數psw有2個數據,那么組合起來的案例是兩個相乘,也就是組合2*2=4個用例。