当前位置: 首页 > 知识库问答 >
问题:

如何正确断言在pytest中引发异常?

海嘉赐
2023-03-14
# coding=utf-8
import pytest


def whatever():
    return 9/0

def test_whatever():
    try:
        whatever()
    except ZeroDivisionError as exc:
        pytest.fail(exc, pytrace=True)
================================ test session starts =================================
platform linux2 -- Python 2.7.3 -- py-1.4.20 -- pytest-2.5.2
plugins: django, cov
collected 1 items 

pytest_test.py F

====================================== FAILURES ======================================
___________________________________ test_whatever ____________________________________

    def test_whatever():
        try:
            whatever()
        except ZeroDivisionError as exc:
>           pytest.fail(exc, pytrace=True)
E           Failed: integer division or modulo by zero

pytest_test.py:12: Failed
============================== 1 failed in 1.16 seconds ==============================

如何使pytest打印回溯,所以我将看到在任何函数中的哪里引发了异常?

共有3个答案

甄永年
2023-03-14

在pytest中有两种方法来处理这类情况:

>

  • 使用pytest.raises函数

    使用pytest.mark.xfaildecorator

    正如文件所说:

    使用pytest.raises可能更好地用于测试您自己的代码故意引发的异常的情况,而使用带有检查函数的@pytest.mark.xfail可能更好地用于记录未修复的错误(测试描述“应该”发生什么)或依赖项中的错误。

    使用pytest.raises

    def whatever():
        return 9/0
    def test_whatever():
        with pytest.raises(ZeroDivisionError):
            whatever()
    

    pytest.mark.xfail的用法

    @pytest.mark.xfail(raises=ZeroDivisionError)
    def test_whatever():
        whatever()
    

    pytest.raises的输出

    ============================= test session starts ============================
    platform linux2 -- Python 2.7.10, pytest-3.2.3, py-1.4.34, pluggy-0.4.0 -- 
    /usr/local/python_2.7_10/bin/python
    cachedir: .cache
    rootdir: /home/user, inifile:
    collected 1 item
    
    test_fun.py::test_whatever PASSED
    
    
    ======================== 1 passed in 0.01 seconds =============================
    

    pytest.xfail标记的输出:

    ============================= test session starts ============================
    platform linux2 -- Python 2.7.10, pytest-3.2.3, py-1.4.34, pluggy-0.4.0 -- 
    /usr/local/python_2.7_10/bin/python
    cachedir: .cache
    rootdir: /home/user, inifile:
    collected 1 item
    
    test_fun.py::test_whatever xfail
    
    ======================== 1 xfailed in 0.03 seconds=============================
    

  • 马德厚
    2023-03-14

    你的意思是这样的:

    def test_raises():
        with pytest.raises(Exception) as execinfo:   
            raise Exception('some info')
        # these asserts are identical; you can use either one   
        assert execinfo.value.args[0] == 'some info'
        assert str(execinfo.value) == 'some info'
    
    梁丘俊材
    2023-03-14

    pytest.raises(例外)就是你需要的。

    代码

    import pytest
    
    def test_passes():
        with pytest.raises(Exception) as e_info:
            x = 1 / 0
    
    def test_passes_without_info():
        with pytest.raises(Exception):
            x = 1 / 0
    
    def test_fails():
        with pytest.raises(Exception) as e_info:
            x = 1 / 1
    
    def test_fails_without_info():
        with pytest.raises(Exception):
            x = 1 / 1
    
    # Don't do this. Assertions are caught as exceptions.
    def test_passes_but_should_not():
        try:
            x = 1 / 1
            assert False
        except Exception:
            assert True
    
    # Even if the appropriate exception is caught, it is bad style,
    # because the test result is less informative
    # than it would be with pytest.raises(e)
    # (it just says pass or fail.)
    
    def test_passes_but_bad_style():
        try:
            x = 1 / 0
            assert False
        except ZeroDivisionError:
            assert True
    
    def test_fails_but_bad_style():
        try:
            x = 1 / 1
            assert False
        except ZeroDivisionError:
            assert True
    

    输出

    ============================================================================================= test session starts ==============================================================================================
    platform linux2 -- Python 2.7.6 -- py-1.4.26 -- pytest-2.6.4
    collected 7 items 
    
    test.py ..FF..F
    
    =================================================================================================== FAILURES ===================================================================================================
    __________________________________________________________________________________________________ test_fails __________________________________________________________________________________________________
    
        def test_fails():
            with pytest.raises(Exception) as e_info:
    >           x = 1 / 1
    E           Failed: DID NOT RAISE
    
    test.py:13: Failed
    ___________________________________________________________________________________________ test_fails_without_info ____________________________________________________________________________________________
    
        def test_fails_without_info():
            with pytest.raises(Exception):
    >           x = 1 / 1
    E           Failed: DID NOT RAISE
    
    test.py:17: Failed
    ___________________________________________________________________________________________ test_fails_but_bad_style ___________________________________________________________________________________________
    
        def test_fails_but_bad_style():
            try:
                x = 1 / 1
    >           assert False
    E           assert False
    
    test.py:43: AssertionError
    ====================================================================================== 3 failed, 4 passed in 0.02 seconds ======================================================================================
    

    请注意,e_info保存异常对象,以便从中提取详细信息。例如,如果要检查异常调用堆栈或内部的另一个嵌套异常。

     类似资料:
    • 嘿,我有个问题要解决。我正在将selenium与纯java和test NG一起使用。在测试类中,我想调用一个方法,如果该方法引发异常,我想让测试失败。方法如下: 我想从测试类调用它,如果它(insert address2方法)抛出异常,我希望测试失败。 这是类测试断言语句 有人能告诉我什么是语法,以及如何测试insertAddress2方法中从不同类引发的异常吗

    • 如何正确断言呢?

    • 问题内容: 我抛出了异常而不是显示失败,这是我做错了,还是我应该在线程内没有断言? 堆栈跟踪 问题答案: JUnit框架仅捕获运行测试的主线程中的断言错误。它不知道新的派生线程中的异常。为了正确执行此操作,您应该将线程的终止状态传达给主线程。您应该正确同步线程,并使用某种共享变量来指示嵌套线程的结果。 编辑: 这是可以提供帮助的通用解决方案: 您应该在构造函数中将其传递给runnable,然后只需

    • 问题内容: 有谁知道是否存在可以测试被测代码中是否抛出异常的或类似东西? 问题答案:

    • 我想测试一个特定的方法是否可以毫无例外地处理一组字符串。因此,我想使用AssertJ的软断言,比如: 不幸的是,我必须坚持使用AssertJ 1。x分别是Java 6,所以我不能利用这一点: 有没有办法用AssertJ(或JUnit)做到这一点?

    • 版本: 我得到以下错误: