这几天为什么不在测试中使用python的assert语句?

wim*_*wim 12 python unit-testing nose pytest

在Python测试中,为什么要使用assert方法:

self.assertEqual(response.status_code, 200)
self.assertIn('key', my_dict)
self.assertIsNotNone(thing)
Run Code Online (Sandbox Code Playgroud)

与直接断言相反:

assert response.status_code == 200
assert 'key' in my_dict
assert thing is not None
Run Code Online (Sandbox Code Playgroud)

根据文件:

使用这些方法代替assert语句,以便测试运行器可以累积所有测试结果并生成报告

然而,这似乎是假的,测试运行员可以积累结果并生成报告,无论如何.在一篇相关文章中, unutbu已经表明,unittest将会提升AssertionError与断言语句相同的内容,而且这已经超过了7年,所以它也不是一个闪亮的新功能.

使用像pytest这样的现代测试运行器,断言助手方法生成的失败消息不再具有可读性(可以说,单元测试的camelCase风格不太可读).那么,为什么不在测试中使用assert语句呢? 有哪些缺点以及为什么CPython这样的重要项目没有从单位测试中移开呢?

Don*_*Mee 8

我不完全确定我理解这个问题。标题是“现在为什么不在测试中使用 pythons 断言语句”

\n

正如您所注意到的,事实上,如果您使用像 pytest 这样的测试框架,您可以使用简单的断言。然而pytest 做了一些非常特别的事情来让它工作。它在运行测试之前重写测试代码中的简单断言。

\n

请参阅https://docs.pytest.org/en/stable/writing_plugins.html#assertion-rewriting其中指出:

\n
\n

pytest 的主要功能之一是使用简单的断言语句以及在断言失败时对表达式进行详细的内省。这是由 \xe2\x80\x9cassertion rewriting\xe2\x80\x9d 提供的,它会在解析后的 AST 编译为字节码之前对其进行修改。

\n
\n

单元测试框架没有实现这种额外的复杂性。(这额外的复杂性。Pytest仅重写测试用例中的断言,它不会重写测试代码使用的其他Python库中的断言。所以有时你会发现pytest在你的测试用例中遇到断言错误测试代码,但没有关于断言失败原因的详细信息,因为它没有重写代码的那部分。因此,您只能得到一个简单的信息,而AssertionError没有任何关于失败原因的信息。)

\n

相反,unittest 提供了类似的方法,assertEqual以便它可以:

\n
    \n
  1. 知道这是一个失败的测试断言,而不是其他一些未处理/意外的异常;和
  2. \n
  3. 它可以提供有关断言为何不满足的信息。(Python 中的简单断言除了引发 AssertionError 之外什么也不做。它没有说,例如AssertionError because 1 != 2
  4. \n
\n

Pytest 在运行测试代码之前通过重写抽象语法树来完成第 1 点和第 2 点。Unittest 采用更传统的方法,要求开发人员使用特定方法。

\n

所以本质上答案是:这是测试框架之间的实现差异。换句话说,Python 的内置assert语句不提供有关失败原因的调试信息。因此,如果您想要更多信息,您需要决定如何实施它。

\n

Unittest 比 pytest 简单很多。Pytest 很棒,但也复杂得多。

\n


war*_*ia1 6

使用assert关键字或专用方法的关键区别在于输出报告.请注意,以下语句assert始终TrueFalse不能包含任何额外信息.

assert 3 == 4
Run Code Online (Sandbox Code Playgroud)

只会AssertionError在报告中显示一个.然而,

self.assertTrue(3 == 4)
Run Code Online (Sandbox Code Playgroud)

给出一些额外的信息:AssertionError: False is not true.不是很有帮助,但请考虑:

self.assertEqual(3, 4)
Run Code Online (Sandbox Code Playgroud)

它会告诉你,它会好得多AssertionError: 3 != 4.你阅读报告,你知道它是什么样的断言(相等测试)和涉及的价值.

假设你有一些函数,并想要断言它返回的值.你可以用两种方式做到:

# assert statement
assert your_function_to_test() == expected_result

# unittest style
self.assertEqual(your_function_to_test(), expected_result)
Run Code Online (Sandbox Code Playgroud)

如果出现错误,第一个没有给出除断言错误之外的信息,第二个告诉你什么是断言的类型(相等测试)以及涉及的值(返回和预期的值).

对于小型项目,我从不打扰单元测试风格,因为它的输入时间较长,但在大型项目中,您可能想要了解更多有关错误的信息.

  • 您可以在断言中添加任意字符串,以将其包含在引发的`AssertionError`中:`assert 3 == 4,“ 3!= 4”`。 (2认同)
  • 更重要的是,测试运行器/测试框架能够自动生成上下文。 (2认同)