如何运行所有 pytest 断言,即使其中一些断言失败?

问题描述 投票:0回答:4

我正在寻找一种方法来运行 PyTest 单元测试中的所有断言,即使其中一些断言失败。我知道必须有一个简单的方法来做到这一点。我检查了 CLI 选项,并浏览了此站点以查找类似的问题/答案,但没有看到任何内容。抱歉,如果这个问题已经得到回答。

例如,考虑以下代码片段,并附有 PyTest 代码:

def parrot(i):
    return i

def test_parrot():
    assert parrot(0) == 0
    assert parrot(1) == 1
    assert parrot(2) == 1
    assert parrot(2) == 2

默认情况下,执行在第一次失败时停止:

$ python -m pytest fail_me.py 
=================== test session starts ===================
platform linux2 -- Python 2.7.10, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: /home/npsrt/Documents/repo/codewars, inifile: 
collected 1 items 

fail_me.py F

=================== FAILURES ===================
___________________ test_parrot ___________________

    def test_parrot():
        assert parrot(0) == 0
        assert parrot(1) == 1
>       assert parrot(2) == 1
E       assert 2 == 1
E        +  where 2 = parrot(2)

fail_me.py:7: AssertionError
=================== 1 failed in 0.05 seconds ===================

我想做的是让代码在 PyTest 遇到第一次失败后继续执行。

python pytest
4个回答
28
投票

它运行了您的所有测试。您只编写了一个测试,并且该测试运行了!

如果您想要非致命断言,如果断言失败,测试将继续进行(如 Google Test 的 EXPECT 宏),请尝试 pytest-expect,它提供了该功能。这是他们网站给出的示例:

def test_func(expect):
    expect('a' == 'b')
    expect(1 != 1)
    a = 1
    b = 2
    expect(a == b, 'a:%s b:%s' % (a,b))

您可以看到期望失败不会停止测试,并且所有失败的期望都会被报告:

$ python -m pytest test_expect.py
================ test session starts =================
platform darwin -- Python 2.7.9 -- py-1.4.26 -- pytest-2.7.0
rootdir: /Users/okken/example, inifile: 
plugins: expect
collected 1 items 

test_expect.py F

====================== FAILURES ======================
_____________________ test_func ______________________
>    expect('a' == 'b')
test_expect.py:2
--------
>    expect(1 != 1)
test_expect.py:3
--------
>    expect(a == b, 'a:%s b:%s' % (a,b))
a:1 b:2
test_expect.py:6
--------
Failed Expectations:3
============== 1 failed in 0.01 seconds ==============

27
投票

正如其他人已经提到的,理想情况下,您应该编写多个测试,并且每个测试中只有一个断言(这不是硬性限制,而是一个很好的指南)。

@pytest.mark.parametrize
装饰器使这变得简单:

import pytest

def parrot(i):
    return i

@pytest.mark.parametrize('inp, expected', [(0, 0), (1, 1), (2, 1), (2, 2)])
def test_parrot(inp, expected):
    assert parrot(inp) == expected

使用

-v
运行时:

parrot.py::test_parrot[0-0] PASSED
parrot.py::test_parrot[1-1] PASSED
parrot.py::test_parrot[2-1] FAILED
parrot.py::test_parrot[2-2] PASSED

=================================== FAILURES ===================================
_______________________________ test_parrot[2-1] _______________________________

inp = 2, expected = 1

    @pytest.mark.parametrize('inp, expected', [(0, 0), (1, 1), (2, 1), (2, 2)])
    def test_parrot(inp, expected):
>       assert parrot(inp) == expected
E       assert 2 == 1
E        +  where 2 = parrot(2)

parrot.py:8: AssertionError
====================== 1 failed, 3 passed in 0.01 seconds ======================

26
投票

pytest 插件 pytest-check 是 pytest-expect 的重写(之前在这里推荐过,但已经过时了)。它会让你像这样做一个“软”断言:

来自 GitHub 存储库的示例:

import pytest_check as check

def test_example():
    a = 1
    b = 2
    c = [2, 4, 6]
    check.greater(a, b)
    check.less_equal(b, a)
    check.is_in(a, c, "Is 1 in the list")
    check.is_not_in(b, c, "make sure 2 isn't in list")

8
投票

您应该能够使用

--maxfail
参数来控制它。我相信默认设置是不会因失败而停止,因此我会检查您可能拥有的任何 py.test 配置文件,以查找覆盖它的位置。

© www.soinside.com 2019 - 2024. All rights reserved.