pytest: error: unrecognized arguments: --allure=./report
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pytest: error: unrecognized arguments: --allure=./report相关的知识,希望对你有一定的参考价值。
参考技术A ERROR: usage: pytest [options] [file_or_dir] [file_or_dir] [...]pytest: error: unrecognized arguments: --allure=./report
inifile: None
rootdir: /home/deploy/test_dir/test_cases/back-one/test_collection
证明pytest 传参错误,需要你 --allure=./report的./report传递一个具体路径
pytest --alluredir=/home/deploy/test_dir/test_cases/back-one/test_collection/report
如何使用 pytest 检查没有引发错误
【中文标题】如何使用 pytest 检查没有引发错误【英文标题】:How to use pytest to check that Error is NOT raised 【发布时间】:2013-12-15 00:20:42 【问题描述】:假设我们有这样的东西:
import py, pytest
ERROR1 = ' --- Error : value < 5! ---'
ERROR2 = ' --- Error : value > 10! ---'
class MyError(Exception):
def __init__(self, m):
self.m = m
def __str__(self):
return self.m
def foo(i):
if i < 5:
raise MyError(ERROR1)
elif i > 10:
raise MyError(ERROR2)
return i
# ---------------------- TESTS -------------------------
def test_foo1():
with pytest.raises(MyError) as e:
foo(3)
assert ERROR1 in str(e)
def test_foo2():
with pytest.raises(MyError) as e:
foo(11)
assert ERROR2 in str(e)
def test_foo3():
....
foo(7)
....
问:如何让 test_foo3() 进行测试,不会引发 MyError? 很明显,我可以测试一下:
def test_foo3():
assert foo(7) == 7
但我想通过 pytest.raises() 进行测试。有可能吗? 例如:在某种情况下,函数“foo”根本没有返回值,
def foo(i):
if i < 5:
raise MyError(ERROR1)
elif i > 10:
raise MyError(ERROR2)
以这种方式进行测试可能有意义,恕我直言。
【问题讨论】:
好像在找问题,代码测试foo(7)
就可以了。您将收到正确的消息,并且使用所有 pytest 输出进行调试会更容易。您从@Faruk ('Unexpected error...'
) 强制提出的建议没有说明该错误,您将陷入困境。你唯一能做的就是说明你的意图,比如test_foo3_works_on_integers_within_range()
。
相关:Python unittest - opposite of assertRaises?
这能回答你的问题吗? Python unittest - opposite of assertRaises?
【参考方案1】:
如果引发任何类型的意外异常,测试将失败。您可以只调用 foo(7) 并且您将测试没有引发 MyError。所以,以下就足够了:
def test_foo3():
foo(7)
如果您想明确并为此编写断言语句,您可以这样做:
def test_foo3():
try:
foo(7)
except MyError:
pytest.fail("Unexpected MyError ..")
【讨论】:
谢谢,它可以工作,但它似乎更像是一个 hack,而不是一个干净的解决方案。例如,测试 foo(4) 会失败,但不是因为断言错误。 对 foo(4) 的测试将失败,因为它会抛出一个意外的异常。另一种方法是将其包装在 try catch 块中并失败并显示特定消息。我会更新我的答案。 如果你有很多这样的情况,把它写成一个简单的函数可能会很有用:``` def not_raises(error_class, func, *args, **kwargs): ... ``` 或者你可以像 pytest 那样写一个类似 with 的方法。如果你这样做,我建议你用这个写一个 PR 来造福所有人。 :)(存储库位于bitbucket)。 @paraklet - pytest 的主要标语是"no-boilerplate testing"。 pytest 的精神是让您能够像 Faruk 的第一个示例中那样编写测试,而 pytest 会为您处理细节。对我来说,第一个例子是“干净的解决方案”,第二个似乎不必要地冗长。 我喜欢可读的代码。如果我看到pytest.notRaises()
我清楚地看到测试的目的是检查是否没有抛出异常。如果我只是执行代码并且没有断言遵循我的第一个想法是“这里缺少一些东西......”。是的,我可以为此写评论,但我更喜欢代码是自我解释的,而不是 cmets。【参考方案2】:
在 Oisin 提到的基础上构建..
您可以创建一个简单的not_raises
函数,其作用类似于pytest 的raises
:
from contextlib import contextmanager
@contextmanager
def not_raises(exception):
try:
yield
except exception:
raise pytest.fail("DID RAISE 0".format(exception))
如果您想坚持让raises
有一个对应项,那么这很好,因此您的测试更具可读性。但是从本质上讲,您实际上不需要任何东西,只需要在自己的行上运行要测试的代码块 - 一旦该块引发错误,pytest 无论如何都会失败。
【讨论】:
我希望这是内置到 py.test 中的;在某些情况下,它会使测试更具可读性。尤其是与@pytest.mark.parametrize
结合使用。
我非常欣赏这种方法的代码可读性!
这应该是公认的答案。可惜pytest
还没有这样的东西(afaik)。【参考方案3】:
自从回答了这个问题以来,pytest 文档已经更新了关于这个主题的信息,这里值得一提。
https://docs.pytest.org/en/6.2.x/example/parametrize.html#parametrizing-conditional-raising
它与其他一些答案类似,但使用 parametrize
和更新的内置 nullcontext
使解决方案非常干净。
一个潜在的 Python3.7+only 示例如下所示:
from contextlib import nullcontext as does_not_raise
import pytest
@pytest.mark.parametrize(
"example_input,expectation",
[
(3, does_not_raise()),
(2, does_not_raise()),
(1, does_not_raise()),
(0, pytest.raises(ZeroDivisionError)),
],
)
def test_division(example_input, expectation):
"""Test how much I know division."""
with expectation:
assert (6 / example_input) is not None
使用parametrize
这种方式可以组合OP的测试用例,比如:
@pytest.mark.parametrize(
"example_input,expectation,message",
[
(3, pytest.raises(MyError), ERROR1),
(11, pytest.raises(MyError), ERROR2),
(7, does_not_raise(), None),
],
)
def test_foo(example_input, expectation, message):
with expectation as e:
foo(example_input)
assert message is None or message in str(e)
这样做可以让您测试它没有引发任何异常。 nullcontext
是作为可选上下文管理器的替代品(在这种情况下为pytest.raises
)。它实际上并没有做任何事情,所以如果您想测试它没有引发特定异常,您应该看到其他答案之一。
【讨论】:
这特别介绍了如何将pytest.raises
换成pytest.parametrize
;它本身并不能真正回答一般问题。 nullcontext
为您提供的所有内容都可以与 with
语句一起使用,但不会单独执行任何操作。
@MartijnPieters 暗示您可以像这样使用它来回答一般问题:with does_not_raise(): foo(7)
。在我看来,这可以防止人们在阅读像 foo(7)
这样的无期望测试时出现停顿。
@MartijnPieters 当我看到问题中的原始 3 个测试时,使用 parametrize
看起来很有意义——我应该提到这一点。我进行了一些编辑以将其与问题联系起来。【参考方案4】:
我很想知道 not_raises 是否可行。对此的快速测试是 (test_notraises.py):
from contextlib import contextmanager
@contextmanager
def not_raises(ExpectedException):
try:
yield
except ExpectedException, err:
raise AssertionError(
"Did raise exception 0 when it should not!".format(
repr(ExpectedException)
)
)
except Exception, err:
raise AssertionError(
"An unexpected exception 0 raised.".format(repr(err))
)
def good_func():
print "hello"
def bad_func():
raise ValueError("BOOM!")
def ugly_func():
raise IndexError("UNEXPECTED BOOM!")
def test_ok():
with not_raises(ValueError):
good_func()
def test_bad():
with not_raises(ValueError):
bad_func()
def test_ugly():
with not_raises(ValueError):
ugly_func()
它似乎确实有效。但是我不确定它是否真的读得很好 测试。
【讨论】:
为python3更新gist.github.com/oisinmulvihill/45c14271fad7794a4a52516ecb784e69 虽然这增加了测试的可读性,但在我看来,“try-except”并没有提供附加值,因为如果引发该异常,测试仍然会出错而不是失败。在其他答案中使用nullcontext
或pytest.fail
似乎更好。以上是关于pytest: error: unrecognized arguments: --allure=./report的主要内容,如果未能解决你的问题,请参考以下文章
pytest-22-fixture详细介绍-error和failed区别
Pytest mocker patch Attribute:Error 'function' object has no attribute 'patch'
pytest文档22-fixture详细介绍-作为参数传入,error和failed区别
pytest文档22-fixture详细介绍-作为参数传入,error和failed区别