Pytest執行的順序
當pytest運行測試函數時,它會查看該測試函數中的參數,然后搜索與這些參數具有相同名稱的fixture。一旦pytest找到這些對象,它就會運行這些fixture
影響執行順序的因素
1. fixture方法的scope:fixture的使用范圍
2. dependencies:可能會存在fixture請求了別的fixture,所以產生了依賴關系
3. autouse:如果多個fixture,其中一個autouse=True,那么這個fixture先執行
執行順序:
單個fixture,先執行這個fixture,再執行測試用例
多個fixture,就要確定fixture的執行順序
1. fixture設置了autouse=True,這個autouse的fixture函數會比請求的其他fixture都要先執行。
2. Scope使用范圍大的fixture先執行:"session"> "package"> "module"> "class">"function"
3. 相同順序的fixture基於依賴項執行:當一個fixture函數請另一個fixture函數,另一個會先執行,參考:https://www.cnblogs.com/pingguo-softwaretesting/p/14698711.html
fixture引用方式
1. 一個fixture函數:A 請求另一個fixture:B,另一個B會先執行
2. 為了控制B的fixture先執行,也可以通過autouse設置,將autouse設置成True
3. 第三種方法,給先執行的fixture通過參數化,傳入參數,
調用方式
1. 通過將fixture聲明為參數來請求fixture,注意fixture名字不能寫錯
2. 通過pytest.mark.usefixtures,將fixture聲明作為參數傳入測試用例
!!!pytest收集到測試用例的執行順序
1. 判斷一下當前測試函數,是否有使用參數化,參數化里面有幾組的測試數據,有幾組的數據,決定了這條測試用例執行多少次
2. 有使用參數化,參數化有兩組的數據,分別執行兩次的測試用例
3. 測試用例執行前,會先查看該測試函數中的參數,然后搜索與函數名稱一樣的fixture,找到了這些fixture,先執行fixture,然后回到測試用例,繼續執行
運行 》 查找測試用例 》 找到測試用例 》 判斷當前有幾組參數化數據 》 開始執行 》 查看測試函數中的參數,與conftest中的fixture的名稱是否有一樣的 》 執行fixture 》 回到測試用例,開始執行測試用例
實際項目:
傳入測試用例的數據:
sucess_data_bak = [{"user_id": "${user_id}", "username": "${login_user}", "password": "123", "sku_code": "vivo00100015", "check": "第二個用戶登錄"}, {"user_id": "${user_id}", "username": "${login_user}", "password": "123", "case": "正常登錄", "check": "第一個用戶登錄"}]
測試用例
@pytest.mark.usefixtures("open_erp_url") # 使用fixture方法:open_erp_url @pytest.mark.usefixtures("preset_users_conditions") # 使用fixture方法:preset_users_conditions # 將參數傳遞給fixtures,命名為test_data,要使用這個參數的fixture的方法,傳入的參數名稱要和test_data一樣 @pytest.mark.parametrize("test_data", login_data.sucess_data) @pytest.mark.testlogin # open_erp_url,用到幾個fixtures、給fixtures傳參:就要傳幾個fixtures進來測試用例 def test_login(self, open_erp_url, preset_users_conditions, test_data): ''' :param open_erp_url: 前置條件打開瀏覽器,返回driver :param preset_users_conditions: 用戶前置條件,包含查詢用戶的數據,和更新用戶的數據 :param sucess_data: 參數化的測試用例的數據 :return: ''' # 調試fixtures的登錄方法 data = preset_users_conditions print("開始執行登錄成功的前置條件") loginpage(open_erp_url).Login(preset_users_conditions["username"], preset_users_conditions["password"]) time.sleep(2)
測試用例使用了參數化
@pytest.mark.parametrize("test_data", login_data.sucess_data),兩組數據,測試用例要執行兩遍,將這個參數傳到了fixture里面,根據參數化,先執行帶參數化的fixture
測試用例執行前,查看測試函數中的參數,與conftest中的fixture的名稱是否有一樣,一樣的先執行fixture
@pytest.mark.parametrize("test_data", login_data.sucess_data) @pytest.mark.testlogin # open_erp_url,用到幾個fixtures、給fixtures傳參:就要傳幾個fixtures進來測試用例 def test_login(self, open_erp_url, preset_users_conditions, test_data): loginpage(open_erp_url).Login(preset_users_conditions["username"], preset_users_conditions["password"])
@pytest.fixture(scope="function") def preset_users_conditions(test_data): ''' 用戶的前置條件,包含傳進來的test_case的數據,判斷查詢什么樣的用戶登錄、以及根據user_id更新用戶登錄的密碼、已經用戶的角色,分配給某個角色 :param test_data: test_login.py測試類中測試用例,通過參數化,命名的參數化的數據,名稱要和參數名聲明的保持一致, 如:@pytest.mark.parametrize("test_data", login_data.sucess_data) :return: ''' # 根據測試用例的數據,判斷要查詢的是什么用戶,用於登錄中台 res_data = datamanage.dynamic_replace_data(testdata=test_data) # 更新用戶的密碼為123 update_user_pwd(res_data["user_id"]) yield res_data
執行完fixture:preset_users_conditions,接着執行open_erp_url
@pytest.fixture(scope="function") def open_erp_url(): ''' 執行登錄操作前,先做打開瀏覽器,設置成最大化,然后再做登錄操作 :return: driver:將當前打開瀏覽器的driver,傳遞給后面使用 ''' MyLog().info("執行前置方法_open_erp_url,打開瀏覽器") driver = webdriver.Chrome() driver.maximize_window() MyLog().info("open_erp_url_打開登錄頁面") driver.get(DoInfo.host) # url登錄的地址 yield driver # 返回driver給后面的其他操作使用 driver.quit() # 后置條件:測試用例執行完畢,關閉瀏覽器
Fixture執行完畢之后,回到測試用例, 執行測試用例
loginpage(open_erp_url).Login(preset_users_conditions["username"], preset_users_conditions["password"])