Pytest系列16 -分布式測試插件之pytest-xdist的詳細使用

一、前言

平常我們功能測試用例非常多時,比如有1千條用例,假設每個用例執行需要1分鐘,如果單個測試人員執行需要1000分鐘才能跑完
當項目非常緊急時,會需要協調多個測試資源來把任務分成兩部分,于是執行時間縮短一半,如果有10個小伙伴,那么執行時間就會變成十分之一,大大節省了測試時間
為了節省項目測試時間,10個測試同時并行測試,這就是一種分布式場景
同樣道理,當我們自動化測試用例排常多的時候, 一條條按順序執行會非常慢,pytest-xdist的出現就是為了讓自動化測試用例可以分布式執行,從而節省自動化測試時間
pytest-xdist是屬于進程級別的并發

二、分布式執行用例的設計原則(重要)
  • 用例之間是獨立的,用例之間沒有依賴關系,用例可以完全獨立運行【獨立運行】
  • 用例執行沒有順序,隨機順序都能正常執行【隨機執行】
  • 每個用例都能重復運行,運行結果不會影響其他用例【不影響其他用例】
三、插件安裝

pip3 install pytest-xdist -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com

四、pytest-xdist通過一些獨特的測試執行模式擴展了pytest

測試運行并行化:如果有多個CPU或主機,則可以將它們用于組合的測試運行。 這樣可以加快開發速度或使用遠程計算機的特殊資源。
--looponfail:在子進程中重復運行測試。 每次運行之后,pytest都會等到項目中的文件更改后再運行之前失敗的測試。 重復此過程,直到所有測試通過,然后再次執行完整運行。
跨平臺覆蓋:您可以指定不同的Python解釋程序或不同的平臺,并在所有這些平臺上并行運行測試。

五、快速入門

這是運行代碼的包結構

14xdist是項目文件夾名稱
│  conftest.py
│  test_1.py
│  __init__.py
│              
├─test_51job
│  │  conftest.py
│  │  test_case1.py
│  │  __init__.py 
│          
├─test_toutiao
│  │  test_case2.py
│
├─test_weibo
│  │  conftest.py
│  │  test_case3.py
│  │  __init__.py 
│          

具體代碼
最外層的conftest.py

# 外層conftest.py

@pytest.fixture(scope="session")
def login():
    print("====登錄功能,返回賬號,token===")
    name = "testyy"
    token = "npoi213bn4"
    yield name, token
    print("====退出登錄!!!====")

最外層的test1.py

import pytest


@pytest.mark.parametrize("n", list(range(5)))
def test_get_info(login, n):
    sleep(1)
    name, token = login
    print("***基礎用例:獲取用戶個人信息***", n)
    print(f"用戶名:{name}, token:{token}")

test51job包下的conftest.py

import pytest


@pytest.fixture(scope="module")
def open_51(login):
    name, token = login
    print(f"###用戶 {name} 打開51job網站###")

test51job包下的test_case1.py

from time import sleep

import pytest


@pytest.mark.parametrize("n", list(range(5)))
def test_case2_01(open_51, n):
    sleep(1)
    print("51job,列出所有職位用例", n)


@pytest.mark.parametrize("n", list(range(5)))
def test_case2_02(open_51, n):
    sleep(1)
    print("51job,找出所有python崗位", n)

test_toutiao包下的test_case2.py

from time import sleep

import pytest


@pytest.mark.parametrize("n", list(range(5)))
def test_no_fixture(login, n):
    sleep(1)
    print("==沒有__init__測試用例,我進入頭條了==", login)

test_weibo包下的conftest.py

import pytest


@pytest.fixture(scope="function")
def open_weibo(login):
    name, token = login
    print(f"&&& 用戶 {name} 返回微博首頁 &&&")

test_weibo包下的test_case3.py

from time import sleep

import pytest


@pytest.mark.parametrize("n", list(range(5)))
class TestWeibo:
    def test_case1_01(self, open_weibo, n):
        sleep(1)
        print("查看微博熱搜", n)

    def test_case1_02(self, open_weibo, n):
        sleep(1)
        print("查看微博范冰冰", n)

不使用分布式測試的命令和所需執行時間

圖片.png

可以看到,執行一條用例大概1s(因為每個用例都加了 sleep(1) ),一共30條用例,總共運行30s;那么如果有1000條用例,執行時間就真的是1000s

使用分布式測試的命令和所需執行時間
pytest -s -n auto

圖片.png

可以看到,最終運行時間只需要6s,我的電腦是真6核,假12核
-n auto:可以自動檢測到系統的CPU核數;從測試結果來看,檢測到的是邏輯處理器的數量,即假12核
使用auto等于利用了所有CPU來跑用例,此時CPU占用率會特別高
可以指定多少個cpul來跑用例
命令:
pytest -s -n 2

圖片.png

pytest-xdist和pytest-html結合使用
命令:
pytest -s -n auto --html=report.html --self-contained-html
pytest-xdist按照一定的順序執行
pytest-xdist默認是無序執行的,可以通過 --dist 參數來控制順序
--dist=loadscope

  • 將按照同一個模塊module下的函數和同一個測試類class下的方法來分組,然后將每個測試組發給可以執行的worker,確保同一個組的測試用例在同一個進程中執行
  • 目前無法自定義分組,按類class分組優先于按模塊module分組

**--dist=loadfile **

  • 按照同一個文件名來分組,然后將每個測試組發給可以執行的worker,確保同一個組的測試用例在同一個進程中執行

如何讓scope=session的feature在test session中僅僅執行一次
pytest-xdist是讓每個worker進程執行屬于自己的測試用例集下的所有測試用例
這意味著在不同進程中,不同的測試用例可能會調用同一個scope范圍級別較高(例如session)的fixture,該fixture則會被執行多次,這不符合scope=session的預期

如何解決?
雖然pytest-xdist沒有內置的支持來確保會話范圍的夾具僅執行一次,但是可以通過使用鎖定文件進行進程間通信來實現。

例子
下面的示例只需要執行一次login(因為它是只需要執行一次來定義配置選項,等等)
當第一次請求這個fixture時,則會利用FileLock僅產生一次fixture數據
當其他進程再次請求這個fixture時,則會從文件中讀取數據

import pytest
from filelock import FileLock


@pytest.fixture(scope="session")
def login():
    print("====登錄功能,返回賬號,token===")
    with FileLock("session.lock"):
        name = "testyy"
        token = "npoi213bn4"
        # web ui自動化
        # 聲明一個driver,再返回

        # 接口自動化
        # 發起一個登錄請求,將token返回都可以這樣寫

    yield name, token
    print("====退出登錄!!!====")

參考鏈接
https://www.cnblogs.com/poloyy/p/12694861.html

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,460評論 6 538
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,067評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,467評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,468評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,184評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,582評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,616評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,794評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,343評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,096評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,291評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,863評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,513評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,941評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,190評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,026評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,253評論 2 375

推薦閱讀更多精彩內容