【问题标题】:With pytest, why do inherited test methods not give proper assertion output?使用 pytest,为什么继承的测试方法不能给出正确的断言输出?
【发布时间】:2016-09-21 15:35:13
【问题描述】:

我正在开发一个具有命令行界面的应用程序,我想使用 pytest 对其进行测试。我的想法是定义测试类,如

class TestEchoCmd(Scenario):
    commands = [
        "echo foo"
    ]
    stdout = "foo\n"

然后使用带有测试方法的类进行实际测试。换句话说,不是在每个描述场景的类中定义测试方法——这总是相同的——(这将非常乏味),这些类从Scenario类继承测试方法:

class Scenario:
    commands = []
    stdout = ""

    def test_scenario(self, capsys):
        for cmd in self.commands:
            ret = my_app.execute_command(shlex.split(cmd))
            assert ret == 0
        stdout, stderr = capsys.readouterr()
        assert stdout == self.stdout

只要测试通过,它就可以正常工作。如果测试失败,那么 pytest 会简单地输出 AssertionError 而没有其他信息,这与未继承测试方法的情况不同,它非常详细地描述了 asserted 表达式。这会适得其反,因为无法准确说明断言失败的原因。

有没有办法让它工作?我真的很想让场景描述尽可能简洁。 (我知道@pytest.mark.parametrize,但我认为在这种情况下它不会产生非常可读的代码。)

(哦,顺便说一下,这是 Debian GNU/Linux 提供的 pytest 3.0.2。)

【问题讨论】:

    标签: python inheritance pytest


    【解决方案1】:

    自己找到了答案:Pytest 喜欢重写 Python AST 中的 assert 语句以添加更明确的输出。这种重写(在其他地方)发生在它认为包含测试方法的类中,即名称以Test 开头的类。如果一个测试方法是从一个不同模块中的类继承的,而该类在其他情况下不会被视为测试,assert 不会被重写,因此不会出现花哨的错误消息。

    根据 pytest 文档,解决方案是让 pytest 也重写该其他模块中的 assert 语句,使用

    pytest.register_assert_rewrite("module.name.goes.here")
    

    这必须在相关模块被导入之前完成。

    【讨论】:

      猜你喜欢
      • 2021-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多