浅谈Pytest中的warning处理

没有处理warning

  • 我们写一个简单的测试
import pytest

def test_demo():
    import warnings
    warnings.warn('test warn',DeprecationWarning)
    assert True


if __name__ == '__main__':
    pytest.main(['-sv',__file__])
  • 你运行的话会有如下提示
============================= test session starts =============================
platform win32 -- Python 3.9.6, pytest-7.1.2, pluggy-1.0.0 -- D:\Python39\python.exe
cachedir: .pytest_cache
metadata: ...
rootdir: D:\pythonProject\AutoTest\PytestTemp, configfile: pytest.ini
plugins: ...
collecting ... collected 1 item

test_demo.py::test_demo PASSED

============================== warnings summary ===============================
testCases/test_demo.py::test_demo
  test_demo.py:5: DeprecationWarning: test warn
    warnings.warn('test warn',DeprecationWarning)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
======================== 1 passed, 1 warning in 0.05s =========================

进程已结束,退出代码为 0

  • warning在pytest3.1之后会在执行期间捕获,初学者多见于mark漏了标记,可以参考浅谈Pytest中的marker

-W 命令行及处理

  • pytest提供了一个命令行参数-W

    -W PYTHONWARNINGS, --pythonwarnings=PYTHONWARNINGS   
       含义:  set which warnings to report, see -W option of python itself.
    
  • python的-W

    -W arg : warning control; arg is action:message:category:module:lineno  also PYTHONWARNINGS=arg
    

    https://docs.python.org/3/library/warnings.html#warning-filter

  • 关于格式说明

    • action is one of the following strings:

      ValueDisposition
      "default"print the first occurrence of matching warnings for each location (module + line number) where the warning is issued
      "error"turn matching warnings into exceptions
      "ignore"never print matching warnings
      "always"always print matching warnings
      "module"print the first occurrence of matching warnings for each module where the warning is issued (regardless of line number)
      "once"print only the first occurrence of matching warnings, regardless of location
    • message is a string containing a regular expression that the start of the warning message must match, case-insensitively. In -W and PYTHONWARNINGS, message is a literal string that the start of the warning message must contain (case-insensitively), ignoring any whitespace at the start or end of message.

    • category is a class (a subclass of Warning) of which the warning category must be a subclass in order to match.

    • module is a string containing a regular expression that the start of the fully qualified module name must match, case-sensitively. In -W and PYTHONWARNINGS, module is a literal string that the fully qualified module name must be equal to (case-sensitively), ignoring any whitespace at the start or end of module.

    • lineno is an integer that the line number where the warning occurred must match, or 0 to match all line numbers.


  • 增加命令行处理

    # action:message:category:module:lineno   # 注意格式
    -W error::DeprecationWarning  # 意思是看到DeprecationWarning就把它当做是一个error
    
    ================================== FAILURES ===================================
    __________________________________ test_demo __________________________________
    
        def test_demo():
            import warnings
    >       warnings.warn('test warn',DeprecationWarning)
    E       DeprecationWarning: test warn
    
    test_demo.py:5: DeprecationWarning
    =========================== short test summary info ===========================
    FAILED test_demo.py::test_demo - DeprecationWarning: test warn
    ============================== 1 failed in 0.09s ==============================
    
    
  • 可以看到case变成了failed


  • 换一下,改为ignore,case就PASSED了

    pytest.main(['-sv','-W ignore::DeprecationWarning',__file__])
    
    ============================== 1 passed in 0.07s ==============================
    

等价的装饰器pytest.mark.filterwarnings

  • 命令行的做法也可以等价到装饰器的写法,跟大多数的插件类似,命令行是针对所有的,装饰器是针对某个case的

    @pytest.mark.filterwarnings('ignore::DeprecationWarning')  # 装饰在被测函数上即可
    
    @pytest.mark.filterwarnings('error::DeprecationWarning')
    
    

等价的pytest.ini中的filterwarnings

  • 你也可以这样写一个pytest.ini

    [pytest]
    filterwarnings:
        ignore::DeprecationWarning
    
    
  • 或者这样

    [pytest]
    filterwarnings:
        error::DeprecationWarning
    
    

  • 还可以这样

    [pytest]
    filterwarnings:
        error
        ignore::DeprecationWarning
    
    

    这个意思是,所有的warning都被处理成error,但忽略DeprecationWarning。

    注意:当警告与列表中的多个选项匹配时,将执行最后一个匹配选项的操作。

关于warning的其他

  • –disable-warnings命令行选项可以禁用warning summary

    ============================== warnings summary ===============================
    testCases/test_demo.py::test_demo
      test_demo.py:5: DeprecationWarning: test warn
        warnings.warn('test warn',DeprecationWarning)
    
    -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
    
    
  • 上面的warning加了命令行之后就没了

  • 命令行的解释

      --disable-warnings, --disable-pytest-warnings  : disable warnings summary
                            
    
    

  • 还有一个命令行-pno:warnings,完全禁用警告捕获

    pytest.main(['-sv','-pno:warnings',__file__])
    
    
  • 实测-pno:warnings的pno要挨在一起,这有点…

  • 命令行的解释

      -p name               early-load given plugin module name or
                            entry point (multi-allowed).
                            To avoid loading of plugins, use the
                            `no:` prefix, e.g. `no:doctest`.
    
    
  • 如果你放在pytest.ini中的pno就可分可合(离谱)

    [pytest]
    addopts = -p no:warnings # -pno:warnings
    
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wuxianfeng023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值