簡體   English   中英

在單個測試中禁用pytest警告捕獲

[英]Disable pytest warnings capture in a single test

我一般喜歡pytest警告捕獲鈎子,因為我可以使用它來強制我的測試套件沒有觸發任何警告。 但是,我有一個測試需要警告正確打印到stderr工作。

如何禁用僅針對一個測試的警告捕獲?

例如,像

def test_warning():
    mystderr = StringIO()
    sys.stderr = mystderr
    warnings.warn('warning')
    assert 'UserWarning: warning' in mystderr.getvalue()

(我知道我可以使用capsys ,我只是想表明基本的想法)

由於討論范圍的縮小,我認為問題可能更好地標題為“在pytest中,如何在單個測試中捕獲警告及其標准錯誤輸出?”。 鑒於建議的重寫,我認為答案是“它不能,你需要一個單獨的測試”。

如果沒有標准的錯誤捕獲要求,您應該可以使用@pytest.mark.filterwarnings注釋。

@pytest.mark.filterwarnings("ignore")
def test_one():
    assert api_v1() == 1

來自: https//docs.pytest.org/en/latest/warnings.html#pytest-mark-filterwarnings

@wim在評論中指出這不會捕獲警告,但他提出的答案以標准方式捕獲和斷言警告。

如果有stderr輸出但沒有拋出Python警告,那么就像你說https://docs.pytest.org/en/latest/capture.html

由於pytest實現的性質,我不認為在pytest測試中同時進行這兩者都是有意義的。

如前所述,pytest將stderr等重定向到內部記錄器。 其次,它定義了自己的警告處理程序https://github.com/pytest-dev/pytest/blob/master/src/_pytest/warnings.py#L59

它與想法的答案類似: https//stackoverflow.com/a/5645133/5729872

我重新定義了warnings.showwarning() ,它在vanilla python中工作得很好,但是pytest也故意重新初始化它。

不會在pytest中工作,只能直接python - >

def func(x):
    warnings.warn('wwarn')
    print(warnings.showwarning.__doc__)
    # print('ewarn', file=sys.stderr)
    return x + 1

sworig = warnings.showwarning

def showwarning_wrapper(message, category, filename, lineno, file=None, line=None):
    """Local override for showwarning()"""
    print('swwrapper({})'.format(file) )
    sworig(message,category,filename,lineno,file,line)

warnings.showwarning = showwarning_wrapper

< - 將無法在pytest中工作,只能直接使用python

您可以在測試用例中添加一個警告處理程序,重新輸出到stderr ...但是那時對於被測試的代碼並沒有多少證據。

這是你的系統在一天結束時。 如果考慮到@wim提出的測試stderr這一點可能不太明顯,你決定你仍然需要它,我建議將Python警告對象(python調用者層)的測試和stderr的內容分開(調用shell)層)。 第一個測試只會查看Python警告對象。 新的第二個測試用例將通過popen()或類似方法將被測試的庫調用為腳本,並對生成的標准錯誤和輸出進行斷言。

我鼓勵你以不同的方式思考這個問題。

如果你想斷言你的某些代碼會觸發警告,你應該使用pytest.warns上下文。 使用match kwarg檢查警告消息,避免嘗試從stderr捕獲它的額外復雜性。

import re
import warnings

import pytest

def test_warning():
    expected_warning_message = "my warning"
    match = re.escape(expected_warning_message)
    with pytest.warns(UserWarning, match=match):
        warnings.warn("my warning", UserWarning)

這應該是您的測試責任的優勢。 測試警告本身會導致某些輸出打印在stderr上是沒有責任的,因為這種行為來自標准庫代碼,它應該由Python本身進行測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM