【Pytest官方文檔翻譯及學習】2.2 如何在測試中編寫和報告斷言

目錄

2.2 如何在測試中編寫和報告斷言

2.2.1 使用assert語句斷言

2.2.2 關于預期異常的斷言

2.2.3 關于預期警告的斷言

2.2.4 應用上下文相關的比較

2.2.5 為失敗的斷言定義自己的解釋

2.2.6 斷言內省細節


2.2 如何在測試中編寫和報告斷言

2.2.1 使用assert語句斷言

pytest允許您使用標準的Python斷言來驗證Python測試中的期望值和值。例如,您可以編寫以下內容:

# content of test_assert1.py 
def f(): return 3 
def test_function(): assert f() == 4

斷言您的函數返回某個值。如果此斷言失敗,您將看到函數調用的返回值:

$ pytest test_assert1.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
collected 1 item
test_assert1.py F [100%]
================================= FAILURES =================================test_function _
def test_function():assert f() == 4
E assert 3 == 4
E + where 3 = f()
test_assert1.py:6: AssertionError
========================= short test summary info ==========================
FAILED test_assert1.py::test_function - assert 3 == 4
============================ 1 failed in 0.12s =============================

pytest支持顯示最常見的子表達式的值,包括調用、屬性、比較以及二進制和一元運算符。(請參閱使用pytest演示Python故障報告Demo of Python failure reports with pytest)。這允許您在不丟失內省信息的情況下使用慣用的python構造,而不需要樣板代碼。

但是,如果您指定一條消息,并使用以下斷言:

assert a % 2 == 0, "value was odd, should be even"

那么根本不進行斷言內省,消息將簡單地顯示在回溯中。

有關斷言內省的更多信息,請參閱Assertion introspection details

2.2.2 關于預期異常的斷言

為了編寫關于引發異常的斷言,可以使用pytest.reses()作為上下文管理器,如下所示:

import pytest 
def test_zero_division(): with pytest.raises(ZeroDivisionError): 1 / 0

如果您需要訪問實際的異常信息,您可以使用:

def test_recursion_depth(): with pytest.raises(RuntimeError) as excinfo: def f(): f() f() assert "maximum recursion" in str(excinfo.value)

excinfo是一個ExceptionInfo實例,它是引發實際異常的包裝器。感興趣的主要屬性是.type、.value和.traceback。

您可以將match關鍵字參數傳遞給上下文管理器,以測試正則表達式在異常的字符串表示形式上是否匹配(類似于unittest中的TestCase.assertRailesRegex方法):

import pytest def myfunc(): raise ValueError("Exception 123 raised") def test_match(): with pytest.raises(ValueError, match=r".* 123 .*"): myfunc()

match方法的regexp參數與re.search函數匹配,因此在上面的示例中,match='123'也會起作用。

pytest.raises()函數的另一種形式是,您可以傳遞一個將使用給定的*args和**kwargs執行的函數,并斷言引發了給定的異常:

pytest.raises(ExpectedException, func, *args, **kwargs)

在出現諸如無異常或錯誤異常之類的故障時,報告器將為您提供有用的輸出。

請注意,也可以為pytest.mark.xfail指定一個“raises”參數,該參數檢查測試是否以引發任何異常更具體的方式失敗:

@pytest.mark.xfail(raises=IndexError) 
def test_f(): f()

使用pytest.reises()可能更適合于測試自己的代碼故意引發的異常的情況,而使用帶有check函數的@pytest.mark.xfail可能更適合記錄未修復的錯誤(測試描述了“應該”發生什么)或依賴關系中的錯誤。

2.2.3 關于預期警告的斷言

您可以使用pytest.warns檢查代碼是否引發特定警告。

2.2.4 應用上下文相關的比較

pytest對在遇到比較時提供上下文相關的信息提供了豐富的支持。例如:

# content of test_assert2.py 
def test_set_comparison(): set1 = set("1308") set2 = set("8035") assert set1 == set2

如果運行此模塊:

$ pytest test_assert2.py 
=========================== test session starts ============================ 
platform linux -- Python 3.x.y, pytest-7.x.y, pluggy-1.x.y 
rootdir: /home/sweet/project 
collected 1 item 
test_assert2.py F [100%] 
================================= FAILURES ================================= 
___________________________ test_set_comparison ____________________________ 
def test_set_comparison(): 
set1 = set("1308") 
set2 = set("8035") 
> assert set1 == set2 
E AssertionError: assert {'0', '1', '3', '8'} == {'0', '3', '5', '8'} 
E Extra items in the left set: 
E '1' 
E Extra items in the right set: 
E '5' 
E Use -v to get more diff 
test_assert2.py:4: AssertionError 
========================= short test summary info ========================== 
FAILED test_assert2.py::test_set_comparison - AssertionError: assert {'0'... 
============================ 1 failed in 0.12s =============================

對一些情況進行了特別比較:

  • 比較長字符串:顯示上下文差異
  • 比較長序列:首次失敗指數
  • 比較dicts:不同條目

有關更多示例,請參閱reporting demo

2.2.5 為失敗的斷言定義自己的解釋

可以通過實現pytest_asserrepr_compare來添加您自己的詳細解釋。

pytest_asserrepr_compareconfig, op, left, right

返回失敗斷言表達式中的比較說明。

返回None表示沒有自定義解釋,否則返回字符串列表。字符串將由換行符連接,但字符串中的任何換行符都將被轉義。請注意,除第一行外的所有行都將略微縮進,目的是使第一行成為摘要

Parameters

? config (Config) – The pytest config object.

? op (str) – The operator, e.g. "==", "!=", "not in".

? left (object) – The left operand.

? right (object) – The right operand.

例如,考慮在conftest.py文件中添加以下,該文件為Foo對象提供了另一種解釋:

# content of conftest.py 
from test_foocompare import Foodef pytest_assertrepr_compare(op, left, right): if isinstance(left, Foo) and isinstance(right, Foo) and op == "==": return [ "Comparing Foo instances:", f"    vals: {left.val} != {right.val}", ]

現在,給定這個測試模塊:

# content of test_foocompare.py 
class Foo: def __init__(self, val): self.val = val def __eq__(self, other): return self.val == other.valdef test_compare(): f1 = Foo(1) f2 = Foo(2) assert f1 == f2

您可以運行測試模塊并獲得conftest文件中定義的自定義輸出:

$ pytest -q test_foocompare.py 
F [100%] 
================================= FAILURES ================================= 
_______________________________ test_compare _______________________________ 
def test_compare(): 
f1 = Foo(1) 
f2 = Foo(2) 
> assert f1 == f2 
E assert Comparing Foo instances: 
E vals: 1 != 2 
test_foocompare.py:12: AssertionError 
========================= short test summary info ========================== 
FAILED test_foocompare.py::test_compare - assert Comparing Foo instances: 
1 failed in 0.12s

2.2.6 斷言內省細節

關于失敗斷言的報告細節是通過在運行斷言語句之前重寫斷言語句來實現的。重寫斷言語句將自省信息放入斷言失敗消息中。pytest只重寫由其測試收集過程直接發現的測試模塊,因此支持模塊中的斷言(本身不是測試模塊)不會被重寫

您可以通過在導入模塊之前調用register_assert_rewrite來手動啟用導入模塊的斷言重寫(在根conftest.py中是一個很好的方法)。

為了獲得更多信息,Benjamin Peterson寫了《pytest新斷言重寫的幕后》(Behind the scenes of pytest’s new assertion rewriting)。

斷言重寫在磁盤上緩存文件

pytest會將重寫后的模塊寫回磁盤進行緩存。您可以通過將其添加到conftest.py文件的頂部來禁用此行為(例如,為了避免在大量移動文件的項目中留下過時的.pyc文件):

import sys 
sys.dont_write_bytecode = True

請注意,您仍然可以獲得斷言自省的好處,唯一的變化是.pyc文件不會緩存在磁盤上。

此外,如果重寫無法寫入新的.pyc文件,即在只讀文件系統或zipfile中,則重寫將自動跳過緩存。

禁用斷言重寫

pytest在導入時通過使用導入掛鉤寫入新的pyc文件來重寫測試模塊。大多數情況下,這是透明的。但是,如果您自己使用導入機器,則導入鉤子可能會干擾。

如果是這種情況,您有兩種選擇:

  • 通過將字符串PYTEST_DONT_REWRITE添加到其文檔字符串中,禁用對特定模塊的重寫。
  • 使用--assert=plain禁用所有模塊的重寫。

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

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

相關文章

6、架構-服務端緩存

為系統引入緩存之前,第一件事情是確認系統是否真的需要緩 存。從開發角度來說,引入緩存會提 高系統復雜度,因為你要考慮緩存的失效、更新、一致性等問題;從運維角度來說,緩存會掩蓋一些缺 陷,讓問題在更久的…

npm徹底清理緩存

在使用npm過程中,肯定會遇到清緩存的情況,網上的命令一般為 npm cache clear --force有時筆者在清理緩存之后npm install依然失敗,仔細發現,執行該命令之后npm報了一個警告 npm WARN using --force Recommended protections dis…

代碼隨想錄算法訓練營第27天|● 39. 組合總和● 40.組合總和II● 131.分割回文串

組合總和 題目鏈接 39. 組合總和 - 力扣&#xff08;LeetCode&#xff09; 代碼&#xff1a; class Solution {public List<List<Integer>> res new ArrayList<>();public List<Integer> list new ArrayList<>();public int sum 0;/**…

在nginx中配置反向代理

在nginx中配置反向代理&#xff0c;需要使用proxy_pass指令。以下是一個簡單的nginx反向代理配置示例&#xff1a; server {listen 80;server_name example.com;location / {proxy_pass http://backend_server;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote…

LoadRunner 錄制腳本時提示無Internet訪問/加載慢,如何解決?

LoadRunner 錄制腳本時提示無Internet訪問/加載慢&#xff0c;如何解決&#xff1f; 在使用LoadRunner 12.02 進行錄制腳本時提示無Internet訪問&#xff0c;這是如下圖&#xff1a; 翻譯中文如下&#xff1a; 這里&#xff0c;我認為大家應該都已經點過yes了&#xff0c;但是…

python結構化模式匹配switch-case,Python 3.10中引入,Python的模式匹配(pattern matching)語法

增加了采用模式加上相應動作的 match 語句 和 case 語句 的形式的結構化模式匹配。 模式由序列、映射、基本數據類型以及類實例構成。 模式匹配使得程序能夠從復雜的數據類型中提取信息、根據數據結構實現分支&#xff0c;并基于不同的數據形式應用特定的動作。 語法與操作 模…

Linux下配置Pytorch

1.Anaconda 1.1虛擬環境創建 2.Nvidia驅動 3.CUDA驅動安裝 4.Pytorch安裝 具體的步驟如上&#xff1a;可參考另一位博主的博客非常詳細&#xff1a; Linux服務器配置PythonPyTorchCUDA深度學習環境_linux cuda環境配置-CSDN博客https://blog.csdn.net/NSJim/article/detai…

極海APM32F072用Keil5燒錄失敗Error: Flash Download failed -“Cortex-MO+“

在用Keil5燒錄時&#xff0c;出現錯誤彈窗&#xff0c;大概長這樣&#xff1a; 檢查了一圈設置&#xff0c;都搞不好。 先用J-Flash&#xff0c;顯示讀寫保護&#xff08;未截圖&#xff09;&#xff0c;會跳出界面讓選擇是否解除讀寫保護&#xff1a; 1.點擊允許讀操作YES&am…

DNF手游攻略:0氪攻略,轉職技巧與避坑指南!

在DNF手游的冒險旅程中&#xff0c;角色的轉職是一次重要的成長經歷。通過轉職&#xff0c;玩家可以獲得全新的技能和屬性&#xff0c;提升自己在地下城中的戰斗力。本文將為您介紹轉職后的關鍵技巧和日常任務&#xff0c;幫助您更好地適應新的職業身份&#xff0c;成為地下城中…

Python從0到100(二十九):requests模塊處理cookie

1 爬蟲中使用cookie 為了能夠通過爬蟲獲取到登錄后的頁面&#xff0c;或者是解決通過cookie的反扒&#xff0c;需要使用request來處理cookie相關的請求 1.1 爬蟲中使用cookie的利弊 帶上cookie的好處 能夠訪問登錄后的頁面能夠實現部分反反爬 帶上cookie的壞處 一套cookie往往…

數據庫與低代碼開發:技術革新與應用實踐

在數字化時代&#xff0c;企業對軟件開發的需求日益增長&#xff0c;同時對開發效率和成本控制的要求也越來越高。在這樣的背景下&#xff0c;低代碼開發平臺應運而生&#xff0c;它允許開發者通過圖形界面和配置化操作&#xff0c;快速構建應用程序&#xff0c;而無需編寫大量…

【設計模式】JAVA Design Patterns——Monitor(監視器模式)

&#x1f50d;目的 主要目的是為多個線程或進程提供一種結構化和受控的方式來安全地訪問和操作共享資源&#xff0c;例如變量、數據結構或代碼的關鍵部分&#xff0c;而不會導致沖突或競爭條件。 &#x1f50d;解釋 通俗描述 監視器模式用于強制對數據進行單線程訪問。 一次只允…

Windows線程同步的四種方式和區別

1. Windows線程同步的四種方式 2. 區別 Critical Section更多強調的是保護&#xff0c;Event對象、Mutex對象與Semaphore對象更多的強調的是同步&#xff1b;Critical Section對象是無法設置等待超時的&#xff0c;而其他三個對象則可以設置等待超時&#xff0c;從這一點來講…

ROS2在RVIZ2中加載機器人urdf模型

參考ROS2-rviz2顯示模型 我這邊用的solid works生成的urdf以及meshes&#xff0c;比參考的方法多了meshes 問題一&#xff1a;Error retrieving file [package://rm_dcr_description/meshes/leftarm_link7.STL]: Package [rm_dcr_description] does not exist 這個是urdf模型中…

VisualStudio中:如果某個項目不顯示SVN的show log等,而其他項目都正常

VisualStudio中&#xff1a;如果某個項目不顯示SVN的show log等&#xff0c;而其他項目都正常。說明大概率是當前項目的問題&#xff0c;而不是VisualStudio的問題&#xff01; 1.這個項目內有一個“隱藏”文件夾.svn 》先刪除&#xff01; 2.如果外層文件夾有紅色感嘆號&…

2024-5-14——完成所有任務需要的最少輪數

2024-5-14 題目來源我的題解方法一 哈希表數學 題目來源 力扣每日一題&#xff1b;題序&#xff1a;2244 我的題解 方法一 哈希表數學 根據數學規律可以發現&#xff0c;除了只有1個任務時不能完成任務&#xff0c;其他的都可以完成。并且需要的輪數為&#xff1a; ?x/3? …

16、matlab求導、求偏導、求定積分、不定積分、數值積分和數值二重積分

1、matlab求導,diff()函數 1)一階導數 語法:diff(f(x)):求一階導數 //diff(f(x),n):求n階導數(n為具體正整數) 以函數(cos(x)+sin(x)-x^2)的一階導數為例 一階導數代碼: yms x;%聲明符號變量x f(x)=cos(x)+sin(x)-x^2;%定義原式子 dy=diff(f(x))%求一階導數dy =cos(…

機器學習-12-開源的機器學習可視化拖拉拽工具orange3的應用

參考orange3,一個無敵的 Python 庫! 參考orange3的GitHub地址 參考orange3的官方應用示例 參考下載Orange模塊,總是出錯? 參考Orange3入門(Orange3Dev) 參考工具|Orange 3:機器學習入門神器 1 orange3 數據科學和機器學習是當今科技領域的重要組成部分,而數據分析和建…

Csv--01--ExportUtil 寫文件

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 ExportUtil案例&#xff1a; ExportUtil.writeCsvFile ExportUtil import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists;import org.apache…

記錄request中上傳圖片接口的測試過程

F12抓取的接口地址如下&#xff1a; 入參&#xff1a; 注意圈出來的部分參數 apifox調試接口 python相關代碼&#xff1a; 接口調用相關文件&#xff1a; select_photo.py 輸出結果&#xff1a; 相關接口的一些封裝&#xff1a;