中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》
  • 首頁 > 
  • 教程 > 
  • 服務器 > 
  • 云計算 > 
  • 使用pytest-xdist分布式插件如何保證scope=session 的fixture在多進程運行情況下仍然能只運行一次

使用pytest-xdist分布式插件如何保證scope=session 的fixture在多進程運行情況下仍然能只運行一次

發布時間:2021-12-04 09:13:25 來源:億速云 閱讀:317 作者:柒染 欄目:云計算

這篇文章給大家介紹使用pytest-xdist分布式插件如何保證scope=session 的fixture在多進程運行情況下仍然能只運行一次,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

背景

  • 使用 pytest-xdist 分布式插件可以加快運行,充分利用機器多核 CPU 的優勢

  • 將常用功能放到 fixture,可以提高復用性和維護性

  • 做接口自動化測試的時候,通常我們會將登錄接口放到 fixture 里面,并且 scope 會設置為 session,讓他全局只運行一次

  • 但是當使用 pytest-xdist 的時候,scope=session 的 fixture 無法保證只運行一次,官方也通報了這一問題

官方描述

  • pytest-xdist 的設計使每個工作進程將執行自己的測試集合并執行所有測試子集,這意味著在不同的測試過程中,要求高級范圍的 fixture(如:session)將會被多次執行,這超出了預期,在某些情況下可能是不希望的

  • 盡管 pytest-xdist 沒有內置支持來確保  scope=session 的fixture 僅執行一次,但是可以通過使用鎖定文件進行進程間通信來實現

官方解決辦法(直接套用就行)

import jsonimport pytestfrom filelock import FileLock


@pytest.fixture(scope="session")def session_data(tmp_path_factory, worker_id):if worker_id == "master":# not executing in with multiple workers, just produce the data and let# pytest's fixture caching do its jobreturn produce_expensive_data()# get the temp directory shared by all workersroot_tmp_dir = tmp_path_factory.getbasetemp().parent

    fn = root_tmp_dir / "data.json"with FileLock(str(fn) + ".lock"):if fn.is_file():
            data = json.loads(fn.read_text())else:
            data = produce_expensive_data()
            fn.write_text(json.dumps(data))return data
  • 若某個 scope = session 的 fixture 需要確保只運行一次的話,可以用上面的方法,直接套用,然后改需要改的部分即可(這個后面詳細講解)

  • 官方原話:這項技術可能并非在每種情況下都適用,但對于許多情況下,它應該是一個起點,在這種情況下,對于 scope = session 的fixture 只執行一次很重要

后續栗子的代碼

項目結構
xdist+fixture(文件夾)
│  tmp(存放 allure 數據文件夾)
│  conftest.py
│  test_1.py
│  test_2.py
│  test_3.py
│ __init__.py │
test_1.py 代碼
import osdef test_1(test):print("os 環境變量",os.environ['token'])print("test1 測試用例", test)
test_2.py 代碼
import osdef test_2(test):print("os 環境變量",os.environ['token'])print("test2 測試用例", test)
test_3.py 代碼
import osdef test_3(test):print("os 環境變量",os.environ['token'])print("test3 測試用例", test)

未解決情況下的栗子

conftest.py 代碼
import osimport pytestfrom random import random


@pytest.fixture(scope="session")def test():
    token = str(random())print("fixture:請求登錄接口,獲取token", token)
    os.environ['token'] = tokenreturn token
運行命令
pytest -n 3 --alluredir=tmp
運行結果

使用pytest-xdist分布式插件如何保證scope=session 的fixture在多進程運行情況下仍然能只運行一次

使用pytest-xdist分布式插件如何保證scope=session 的fixture在多進程運行情況下仍然能只運行一次

使用pytest-xdist分布式插件如何保證scope=session 的fixture在多進程運行情況下仍然能只運行一次

scope=session 的 fixture 很明顯執行了三次,三個進程下的三個測試用例得到的數據不一樣,明顯不會是我們想要的結果

使用官方解決方法的栗子rt 

#!/usr/bin/env python# -*- coding: utf-8 -*-"""__title__  = 
__Time__   = 2021/4/27 11:28
__Author__ = 小菠蘿測試筆記
__Blog__   = https://www.cnblogs.com/poloyy/"""import jsonimport osimport pytestfrom random import randomfrom filelock import FileLock

@pytest.fixture(scope="session")def test(tmp_path_factory, worker_id):# 如果是單機運行 則運行這里的代碼塊【不可刪除、修改】if worker_id == "master":"""【自定義代碼塊】
        這里就寫你要本身應該要做的操作,比如:登錄請求、新增數據、清空數據庫歷史數據等等"""token = str(random())print("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 的代碼塊一樣就行"""token = str(random())print("fixture:請求登錄接口,獲取token", token)# 【不可刪除、修改】            fn.write_text(json.dumps(token))print(f"首次執行,token 是{token} ")# 最好將后續需要保留的數據存在某個地方,比如這里是 os 的環境變量os.environ['token'] = tokenreturn token
運行命令
pytest -n 3 --alluredir=tmp
運行結果

使用pytest-xdist分布式插件如何保證scope=session 的fixture在多進程運行情況下仍然能只運行一次

使用pytest-xdist分布式插件如何保證scope=session 的fixture在多進程運行情況下仍然能只運行一次

使用pytest-xdist分布式插件如何保證scope=session 的fixture在多進程運行情況下仍然能只運行一次

可以看到 fixture 只執行了一次,不同進程下的測試用例共享一個數據 token

重點
  • 讀取緩存文件并不是每個測試用例都會讀,它是按照進程來讀取的

  • 比如 -n 3 指定三個進程運行,那么有一個進程會執行一次 fixture(隨機),另外兩個進程會各讀一次緩存

  • 假設每個進程有很多個用例,那也只是讀一次緩存文件,而不會讀多次緩存文件

  • 所以最好要將從緩存文件讀出來的數據保存在特定的地方,比如上面代碼的 os.environ 可以將數據保存在環境變量中

兩個進程跑三個測試用例文件

還是上面栗子的代碼

運行命令
pytest -n 2 --alluredir=tmp
運行結果

使用pytest-xdist分布式插件如何保證scope=session 的fixture在多進程運行情況下仍然能只運行一次

使用pytest-xdist分布式插件如何保證scope=session 的fixture在多進程運行情況下仍然能只運行一次

使用pytest-xdist分布式插件如何保證scope=session 的fixture在多進程運行情況下仍然能只運行一次

可以看到 test_3 的測試用例就沒有讀緩存文件了,每個進程只會讀一次緩存文件,記住哦!

關于使用pytest-xdist分布式插件如何保證scope=session 的fixture在多進程運行情況下仍然能只運行一次就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

东海县| 南和县| 新乡县| 于田县| 甘泉县| 益阳市| 江华| 南昌市| 高邑县| 天等县| 慈溪市| 罗江县| 宁武县| 攀枝花市| 康乐县| 嘉禾县| 博湖县| 乌兰察布市| 济源市| 威信县| 类乌齐县| 成安县| 兴城市| 文安县| 柏乡县| 萨嘎县| 威信县| 龙泉市| 宜兰市| 那坡县| 将乐县| 高阳县| 宜宾县| 长海县| 老河口市| 龙南县| 德格县| 中阳县| 林州市| 同德县| 漠河县|