pytest-rerunfailures:優化測試穩定性的失敗重試工具

筆者在執行自動化測試用例時,會發現有時候用例失敗并非代碼問題,而是由于服務正在發版,導致請求失敗,從而降低了自動化用例的穩定性,最后還要花時間定位到底是自身case的原因還是業務邏輯問題,還是其他原因,增加了定位成本。增加容錯機制,失敗重試,會解決大部分由于網絡原因、服務重啟等原因造成的case失敗問題。那該如何增加失敗重試機制呢?帶著問題我們一起探索。

02 pytest-rerunfailures 插件

先給出答案,我們將使用?pytest-rerunfailures?插件來實現失敗重試功能。

什么是?pytest-rerunfailures??

pytest-rerunfailures?是一個基于 pytest 框架的插件,它允許我們對測試用例進行失敗重試。當一個測試用例失敗時,插件會自動重新運行失敗的測試用例,直到達到預定的重試次數或測試用例通過為止。這樣可以增加用例的穩定性,并減少因為偶發性問題導致的測試失敗。

如何使用?pytest-rerunfailures??

  • 方式一

首先,確保已經安裝了 pytest-rerunfailures 插件。可以使用以下命令進行安裝:

pip install pytest-rerunfailures

安裝完成后,在項目中使用 pytest 運行測試用例時,pytest-rerunfailures 插件會自動生效。

接下來,在編寫測試用例時,可以通過添加?@pytest.mark.flaky?裝飾器將需要重試的測試用例標記起來。例如:

test_demo.py

 
  1. import pytest

  2. @pytest.mark.flaky(reruns=3, reruns_delay=2)

  3. def test_case():

  4. ? ?assert 1 == 2

在上述示例中,我們使用了?@pytest.mark.flaky?裝飾器來標記測試用例?test_case?為可重試的。參數?reruns?指定了重試次數,而?reruns_delay?則指定了每次重試之間的延遲時間(以秒為單位)。

我們來運行case,看一下執行結果:

執行命令:pytest -s -v test_demo.py::test_case,會看到如下結果:

 
  1. RERUN

  2. test_dir/test_demo.py::test_case RERUN

  3. test_dir/test_demo.py::test_case RERUN

  4. test_dir/test_demo.py::test_case?FAILED

可以看到,重試了3次,最終結果為失敗。

注意:如果你是在pycharm中點擊綠色三角形直接運行是不生效的

總結一下:

當運行測試時,如果測試用例失敗,pytest-rerunfailures 插件會根據我們配置的重試次數和延遲時間自動重新運行該測試用例,直到達到最大重試次數或測試通過為止。

  • 方式二

除了使用裝飾器來標記測試用例外,pytest-rerunfailures 還支持使用命令行選項和配置文件的方式進行配置。

命令行執行的話,可以這樣寫:

pytest?-s?-v?--reruns?3?--reruns-delay?2?test_demo.py::test_case

或者代碼運行的話,可以這樣寫:

pytest.main(["-s",?"-v",?"--reruns",?"3",?"--reruns-delay",?"2",?"test_demo.py::test_case"])

03 運行機制

到這里,應該會使用了。我們簡單概括一下它的運行機制:

1、pytest 通過插件系統加載 pytest-rerunfailures 插件,并啟用其功能。

2、當 pytest 運行測試時,對每個測試用例的執行進行監控。

3、如果一個測試用例執行失敗,pytest-rerunfailures 插件會捕獲該失敗,并判斷是否需要進行重試。

4、如果該測試用例被標記為可重試(使用了?@pytest.mark.flaky?裝飾器),插件會根據配置的重試次數和延遲時間重新運行該測試用例。

5、在每次重試之前,插件會根據設置的延遲時間暫停一段時間。

6、如果測試用例在重試次數達到上限之前通過了,即成功執行,則插件會將該測試用例標記為通過。

7、如果測試用例在達到最大重試次數后仍然失敗,則插件會返回最后一次失敗的結果作為最終的結果。

總結起來,pytest-rerunfailures 插件在測試執行失敗時,根據配置的重試次數和延遲時間重新運行測試用例,并根據重試結果判斷最終的測試結果。這樣可以提高測試用例的穩定性,并減少偶發性問題導致的測試失敗。

04 源碼解讀

使用階段,我們使用?mark?標記,那源碼中應該添加了該標記。

 
  1. def pytest_configure(config):

  2. ? ?# add flaky marker

  3. ? ?config.addinivalue_line(

  4. ? ? ? ?"markers",

  5. ? ? ? ?"flaky(reruns=1, reruns_delay=0): mark test to re-run up "

  6. ? ? ? ?"to 'reruns' times. Add a delay of 'reruns_delay' seconds "

  7. ? ? ? ?"between re-runs.",

  8. ? )

  9. ????......

簡單解釋一下:

  • pytest_configure(config)?是 pytest 的一個鉤子函數,用于在 pytest 配置階段對配置進行自定義操作。

  • config.addinivalue_line()?是 pytest 的配置方法,用于向配置中添加新的配置項或配置信息。

  • 在這段代碼中,通過?config.addinivalue_line()?方法,插件向 pytest 的配置中加入了一行字符串。

  • 這行字符串指定了標記名稱為 "flaky",并使用參數?reruns?和?reruns_delay?來說明重試次數和延遲時間的默認值。

  • 標記的含義是將被標記的測試用例重新運行最多 "reruns" 次,每次重試之間間隔 "reruns_delay" 秒。

通過這個自定義的標記,就可以使用?@pytest.mark.flaky?裝飾器來標記需要進行重試的測試用例,并且可以在裝飾器中指定具體的重試次數和延遲時間。

我們看看實現失敗重試的源碼,這才是重點。

 
  1. def pytest_runtest_protocol(item, nextitem):

  2. """

  3. Run the test protocol.

  4. Note: when teardown fails, two reports are generated for the case, one for

  5. the test case and the other for the teardown error.

  6. """

  7. reruns = get_reruns_count(item)

  8. if reruns is None:

  9. # global setting is not specified, and this test is not marked with

  10. # flaky

  11. return

  12. # while this doesn't need to be run with every item, it will fail on the

  13. # first item if necessary

  14. check_options(item.session.config)

  15. delay = get_reruns_delay(item)

  16. parallel = not is_master(item.config)

  17. db = item.session.config.failures_db

  18. item.execution_count = db.get_test_failures(item.nodeid)

  19. db.set_test_reruns(item.nodeid, reruns)

  20. if item.execution_count > reruns:

  21. return True

  22. need_to_run = True

  23. while need_to_run:

  24. item.execution_count += 1

  25. item.ihook.pytest_runtest_logstart(nodeid=item.nodeid, location=item.location)

  26. reports = runtestprotocol(item, nextitem=nextitem, log=False)

  27. for report in reports: # 3 reports: setup, call, teardown

  28. report.rerun = item.execution_count - 1

  29. if _should_not_rerun(item, report, reruns):

  30. # last run or no failure detected, log normally

  31. item.ihook.pytest_runtest_logreport(report=report)

  32. else:

  33. # failure detected and reruns not exhausted, since i < reruns

  34. report.outcome = "rerun"

  35. time.sleep(delay)

  36. if not parallel or works_with_current_xdist():

  37. # will rerun test, log intermediate result

  38. item.ihook.pytest_runtest_logreport(report=report)

  39. # cleanin item's cashed results from any level of setups

  40. _remove_cached_results_from_failed_fixtures(item)

  41. _remove_failed_setup_state_from_session(item)

  42. break # trigger rerun

  43. else:

  44. need_to_run = False

  45. item.ihook.pytest_runtest_logfinish(nodeid=item.nodeid, location=item.location)

  46. return True

簡單解釋一下:

首先,通過函數?get_reruns_count(item)?獲取當前測試用例需要重試的次數。如果沒有設置重試次數,則直接返回。

然后,檢查配置選項并獲取重試的延遲時間,并確定是否運行在并行模式下。還會獲取失敗記錄數據庫對象,并獲取當前測試用例已經執行的次數。

接下來,通過比較已執行次數和設定的重試次數,判斷是否需要進行重試。如果已執行次數大于等于設定的重試次數,則不再進行重試,直接返回。

如果需要重試,會進入一個循環,每次重試會增加已執行次數。在重試過程中,會調用?pytest_runtest_logstart?函數記錄測試用例開始執行的日志。

然后,通過調用?runtestprotocol?函數執行測試用例,并獲取測試結果。在這里,生成的報告會被標記為執行次數減一,以便區分原始執行和重試執行的報告。

接著,通過?_should_not_rerun?函數判斷當前報告是否滿足不需要重試的條件。如果滿足,則繼續執行后續操作。

如果報告表明需要重試,并且重試次數未達到設定的次數,會將報告的結果設置為 "rerun",并根據設定的延遲時間暫停一段時間。

然后,根據并行模式和當前使用的 xdist 版本,決定是否記錄中間結果。同時,會清除緩存的結果和執行狀態。

之后,重試循環會繼續,直到不滿足重試條件為止。最后,會調用?pytest_runtest_logfinish?函數記錄測試用例結束執行的日志。

最后,函數返回 True,表示已經實現重試機制。

總結起來,這段代碼通過循環執行測試用例,并在滿足重試條件時進行重試,直到滿足退出條件為止。在重試過程中,會記錄日志、生成報告,并根據設定的重試次數和延遲時間進行控制。

04 最后???????

失敗重試功能并不是解決所有測試問題的法寶,它應該被視為一種提高測試穩定性的輔助手段。在使用 pytest-rerunfailures 進行失敗重試時,我們應該仔細分析失敗的原因,確保重試次數和延遲時間設置合理,并與團隊成員共同討論和決定是否需要重試測試用例。

總結起來,pytest-rerunfailures 是一個非常有用的工具,可以提高測試用例的穩定性。通過使用它,我們可以輕松地實現失敗重試功能,并減少由于偶發性問題導致的測試失敗。

另外源碼中,看到了?pytest_runtest_logstart?等,可能有些同學不明白這是干嘛用的,之后我們專門寫一篇文章來介紹它的作用。

感謝每一個認真閱讀我文章的人,禮尚往來總是要有的,雖然不是什么很值錢的東西,如果你用得到的話可以直接拿走:

這些資料,對于【軟件測試】的朋友來說應該是最全面最完整的備戰倉庫,這個倉庫也陪伴上萬個測試工程師們走過最艱難的路程,希望也能幫助到你!有需要的小伙伴可以點擊下方小卡片領取???

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/40176.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/40176.shtml
英文地址,請注明出處:http://en.pswp.cn/web/40176.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

大數據面試題之Presto[Trino](3)

目錄 Presto如何處理數據的聚合操作&#xff1f; Presto支持哪些類型的JOIN操作&#xff1f; 如何在Presto中使用子查詢&#xff1f; 解釋Presto中的窗口函數。 Presto中的Page和Block是什么&#xff1f; 描述Presto如何處理列式存儲數據。 ORC和Parquet格式在Presto中的…

適合家居建材企業的CRM系統盤點(2024版)

當前&#xff0c;CRM市場上&#xff0c;國際巨頭的市場優勢正在逐漸減弱&#xff0c;國內CRM企業奮起追趕&#xff0c;呈現出強勁的崛起勢頭。因此&#xff0c;對于家居建材企業來講&#xff0c;在進行CRM選型時&#xff0c;如何選擇一款合適的系統是關乎企業高效發展的重要課題…

探索C嘎嘎的奇妙世界:第十九關---STL(list的模擬實現)

1. 基本框架 首先&#xff0c;我們先從節點的準備工作入手&#xff0c;請看示例&#xff1a; #pragma once #include<iostream> #include<assert.h> using namespace std; //節點 template<class T> struct ListNode {ListNode<T>* _next;Li…

矩陣鍵盤與密碼鎖

目錄 1.矩陣鍵盤介紹?編輯 2.掃描的概念 3.代碼演示&#xff08;讀取矩陣鍵盤鍵碼&#xff09; 4.矩陣鍵盤密碼鎖 1.矩陣鍵盤介紹 為了減少I/O口的占用&#xff0c;通常將按鍵排列成矩陣形式&#xff0c;采用逐行或逐列的 “掃描”&#xff0c;就可以讀出任何位置按鍵的狀態…

免殺筆記 ----> ShellCode Loader !!!

學了那么久的前置知識&#xff0c;終于到了能上線的地方了&#xff01;&#xff01;&#xff01; 不過這里還沒到免殺的部分&#xff0c;距離bypass一眾的殺毒軟件還有很長的路要走&#xff01;&#xff01; 目錄 1.ShellCode 2.ShellCode Loader的概念 3.可讀可寫可…

字符串函數5-9題(30 天 Pandas 挑戰)

字符串函數 1. 相關知識點1.5 字符串的長度條件判斷1.6 apply映射操作1.7 python大小寫轉換1.8 正則表達式匹配2.9 包含字符串查詢 2. 題目2.5 無效的推文2.6 計算特殊獎金2.7 修復表中的名字2.8 查找擁有有效郵箱的用戶2.9 患某種疾病的患者 1. 相關知識點 1.5 字符串的長度條…

代碼隨想錄算法訓練營第四十四天|188.買賣股票的最佳時機IV、309.最佳買賣股票時機含冷凍期、714.買賣股票的最佳時機含手續費

188.買賣股票的最佳時機IV 題目鏈接&#xff1a;188.買賣股票的最佳時機IV 文檔講解&#xff1a;代碼隨想錄 狀態&#xff1a;不會 思路&#xff1a; 在股票買賣1使用一維dp的基礎上&#xff0c;升級成二維的即可。 定義dp[k1][2]&#xff0c;其中 dp[j][0] 表示第j次交易后持…

虛擬ECU:純電動汽車發展下的新選擇

人類文明的進步是一個不斷自我否定、自我超越的過程。21世紀以來&#xff0c;隨著科技進步和經濟社會發展&#xff0c;能源和交通系統已從獨立于自然環境的孤立系統&#xff0c;轉變為與自然、技術、社會深度耦合的復雜系統。為實現可持續發展和應對氣候變化&#xff0c;世界各…

【居家養老實訓室】:無障礙設施建設與評估

本文圍繞居家養老實訓室中的無障礙設施建設與評估展開討論。首先闡述了無障礙設施對于居家養老的重要性&#xff0c;接著詳細介紹了常見的居家養老無障礙設施類型&#xff0c;包括出入口、通道、臥室、衛生間等區域的設施。然后重點探討了無障礙設施的評估方法和標準&#xff0…

【C++航海王:追尋羅杰的編程之路】關聯式容器的底層結構——AVL樹

目錄 1 -> 底層結構 2 -> AVL樹 2.1 -> AVL樹的概念 2.2 -> AVL樹節點的定義 2.3 -> AVL樹的插入 2.4 -> AVL樹的旋轉 2.5 -> AVL樹的驗證 2.6 -> AVL樹的性能 1 -> 底層結構 在上文中對對map/multimap/set/multiset進行了簡單的介紹&…

《簡歷寶典》02 - 如果你是HR,你會優先打開哪份簡歷?

現在的求職環境不必多說&#xff0c;其實我們大家都還是很清楚的。所以&#xff0c;在這個環境下&#xff0c;寫一份優秀的簡歷&#xff0c;目的與作用也不必多說。那么&#xff0c;這一小節呢&#xff0c;我們先從簡歷這份文檔的文檔名開始說起。 目錄 1 你覺得HR們刷簡歷的時…

【深度學習】圖形模型基礎(5):線性回歸模型第二部分:單變量線性回歸模型

1.引言 在統計學與機器學習的廣闊領域中&#xff0c;線性回歸作為一種基礎而強大的預測技術&#xff0c;其核心在于通過輸入變量&#xff08;或稱預測器、自變量&#xff09;來估計輸出變量&#xff08;響應變量、因變量&#xff09;的連續值。本章聚焦于線性回歸的一個基本但…

Spring-@Component和@Configuration的區別

前言 在Spring框架中&#xff0c;Configuration和Component注解都是用于組件掃描和管理Bean的生命周期&#xff0c;但它們有著不同的用途和應用場景 Component 注解 Component是一個通用的 stereotype 注解&#xff0c;表明一個Java類為Spring框架中的一個Bean組件。Spring會自…

【C++】相機標定源碼筆記- 立體視覺相機的校準和圖像矯正類

類主要用于雙目相機的標定和矯正。它包含了讀取和保存相機模型、計算標定參數以及矯正圖像的功能。通過這些功能&#xff0c;可以實現雙目相機的標定和矯正&#xff0c;從而提高雙目相機的精度和穩定性。 公有函數&#xff1a; 構造函數、帶參構造函數、析構函數、讀取雙目相機…

摩斯邀您參加“WAIC 2024世界人工智能大會”

2024世界人工智能大會暨人工智能全球治理高級別會議&#xff08;簡稱“WAIC 2024”&#xff09;將于7月在上海世博中心、世博展覽館舉行&#xff0c;論壇時間為7月4日-6日&#xff0c;展覽時間為7月5日-7日。大會展覽面積超5.2萬平方米&#xff0c;重點圍繞核心技術、智能終端、…

STM32要學到什么程度才算合格?

在開始前剛好我有一些資料&#xff0c;是我根據網友給的問題精心整理了一份「嵌入式的資料從專業入門到高級教程」&#xff0c; 點個關注在評論區回復“888”之后私信回復“888”&#xff0c;全部無償共享給大家&#xff01;&#xff01;&#xff01; STM32 這玩意兒要學到啥…

今天聊聊AI

AI是在幫助開發者還是取代他們&#xff1f; 在軟件開發領域&#xff0c;生成式人工智能&#xff08;AIGC&#xff09;正在改變開發者的工作方式。無論是代碼生成、錯誤檢測還是自動化測試&#xff0c;AI工具正在成為開發者的得力助手。然而&#xff0c;這也引發了對開發者職業…

vscode 前行復制到下一行

目錄 這個技巧也比較多 選擇 python解釋器 F1 Ctrl Shift P 跳轉上一次編輯 下一次編輯 Ctrl d 會把當前行復制到下一行 步驟1&#xff1a;打開鍵綁定設置 使用VS Code設置換行 這個技巧也比較多 VS Code技巧匯總_vs code反縮進-CSDN博客 選擇 python解釋器 F1 Ctrl Shi…

Java中如何使用 tesseract-ocr 進行圖片文字提取(tesseract、tesseract訓練自己的字庫)

tesseract下載鏈接&#xff1a; github&#xff1a;https://github.com/tesseract-ocr/ db&#xff1a;https://digi.bib.uni-mannheim.de/tesseract/ 文字識別技術在許多領域都有廣泛的應用&#xff0c;例如文檔處理、自動化辦公、移動設備上的文本輸入等。而Tesseract-OCR作…

Python推導式寫出簡潔高效的代碼方法詳解

概要 推導式是Python中一種非常強大的語法特性,允許你用簡潔的語法創建列表、字典、集合等數據結構。使用推導式不僅可以讓代碼更加簡潔和易讀,還能提高代碼的執行效率。本文將詳細介紹Python中的各種推導式,并提供相應的示例代碼,幫助全面掌握這一強大的工具。 列表推導式…