01、聲明
在介紹pytest-xdist時,不講任何原理,需要看原理的請移至官方:https://pypi.org/project/pytest-xdist/
當我們自動化測試用例非常多的時候, 一條條按順序執行會非常慢,pytest-xdist的出現就是為了讓自動化測試用例可以分布式執行,從而節省自動化測試時間,pytest-xdist是屬于進程級別的并發。
pytest-xdist插件在測試過程中可以使我們的測試用例一起并行測試,運行情況是根據你運行環境存在多個CPU,運行過程中可以進行組合測試運行,從而縮短我們的測試時間。
1、pytest-xdist插件安裝
只需要在終端中運行如下命令:
pip install pytest-xdist
2、pytest-xdist執行用例的條件
需滿足以下條件:
-
每一條用例必須是獨立的。用例之間沒有依賴關系,用例可以完全獨立運行【獨立運行】
-
每一條用例沒有特定的執行順序,就是每條用例都要遵循隨機執行【隨機執行】
-
每條用例的測試結果不能影響到其他的測試用例。【不影響其他用例】
pytest-sdist?與?pytest-parallel的小區別
-
pytest-xdist在win中調用的是多進程,而parallel在win中調用的是多線程,win中只有單進程
-
pytest-xdist調用時,會使session執行多次,算是一個win的bug,但是官方給出的解決方案是,使用filelock鎖
-
使用parallel時,在win中調用多線程,但是allure報告不支持多線程,allure是集成報告,根據session來集成,所以就是出現一個線程一個報告
3、pytest-xdist使用方法
pytest
-n
x
n:表示使用并行參數
x:表示需要啟動多少個分布式,也即使用CPU的個數
-
n auto:可以自動檢測到系統的CPU核數;從測試結果來看,檢測到的是邏輯處理器的數量
-
使用auto等于利用了所有CPU來跑用例,此時CPU占用率會特別高
說明:建議最多使用1/2的CPU個數來進行執行,消耗資源太多,導致電腦太卡
接下來看實例:
在終端中分別輸入并執行:pytest -vs、pytest -vs -n 2
從結果可以看出,不是用分布式運行測試用例,總共用時10.71秒
?
那么接下來我們使用分布式進行運行用例,看看他運行的時間:
可以看出使用分布式運行用例,同時有2個線程進行執行用例,時間為6.08秒,縮短了很多的時間。
4、pytest-xdist自定義執行模式
按照同一個作用域方法來分組,然后將每個測試組發給可以執行的worker,確保同一個組的測試用例在同一個進程中執行:
--dist=loadscope
#每個worker按類執行
示例:pytest
-v
-n
3
--dist
=
loadscope test_demo.py
按照同一個文件名來分組,然后將每個測試組發給可以執行的worker,確保同一個組的測試用例在同一個進程中執行:
--dist=loadfile
#每個worker按文件執行
示例:pytest
-v
-n
3
--dist
=
loadfile test_xdist.py
test_xdist_02.py test_xdist_03.py
將每個用例,分別發給所有的執行器worker,相當于開了幾個執行器worker,同一個用例就執行幾遍:
--dist=each
示例:
pytest
-v
-n
3
--dist
=
each test_xdist.p
將待運行的用例隨機發給可用的執行器worker,用例執行順序隨機的,目前默認采用這種方式:
--dist=load 和
--dist==no
示例:
pytest
-v
-n
3
-
-dist
=
load test_xdist.py
5、如何讓scope=session的fixture在test session中僅僅執行一次
pytest-xdist是讓每個worker進程執行屬于自己的測試用例集下的所有測試用例,這意味著在不同進程中,不同的測試用例可能會調用同一個scope范圍級別較高(例如session)的fixture,該fixture則會被執行多次,這不符scope=session的預期。
雖然pytest-xdist沒有內置的支持來確保會話范圍的夾具僅執行一次,但是可以通過使用鎖定文件進行進程間通信來實現。
import pytestfrom filelock import FileLock@pytest.fixture(scope="session",autouse=True)def login(tmp_path_factory, worker_id):# 如果是單機運行 則運行這里的代碼塊【不可刪除、修改】if worker_id == "master":"""【自定義代碼塊】這里就寫你要本身應該要做的操作,比如:登錄請求、新增數據、清空數據庫歷史數據等等"""uuid_value = uuid.uuid1()token = uuid_value.hexprint("fixture:請求登錄接口,獲取token", token)os.environ['token'] = token# 如果測試用例有需要,可以返回對應的數據,比如 tokenreturn token# 如果是分布式運行# 獲取所有子節點共享的臨時目錄,無需修改【不可刪除、修改】root_tmp_dir = tmp_path_factory.getbasetemp().parent# 【不可刪除、修改】fn = root_tmp_dir / "data.json"# 【不可刪除、修改】with FileLock(str(fn) + ".lock"):# 【不可刪除、修改】if fn.is_file():# 緩存文件中讀取數據,像登錄操作的話就是 token 【不可刪除、修改】token = json.loads(fn.read_text())print(f"讀取緩存文件,token 是{token} ")else:"""【自定義代碼塊】跟上面 if 的代碼塊一樣就行"""uuid_value = uuid.uuid1()token = uuid_value.hexprint("fixture:請求登錄接口,獲取token", token)# 【不可刪除、修改】fn.write_text(json.dumps(token))print(f"首次執行,token 是{token} ")# 最好將后續需要保留的數據存在某個地方,比如這里是 os 的環境變量os.environ['token'] = tokenreturn token
-
示例只需要執行一次login(因為它是只需要執行一次來定義配置選項,等等)
-
當第一次請求這個fixture時,則會利用FileLock僅產生一次fixture數據
-
當其他進程再次請求這個fixture時,則會從文件中讀取數據
最后感謝每一個認真閱讀我文章的人,看著粉絲一路的上漲和關注,禮尚往來總是要有的,雖然不是什么很值錢的東西,如果你用得到的話可以直接拿走!
軟件測試面試文檔
我們學習必然是為了找到高薪的工作,下面這些面試題是來自阿里、騰訊、字節等一線互聯網大廠最新的面試資料,并且有字節大佬給出了權威的解答,刷完這一套面試資料相信大家都能找到滿意的工作。