使用pytest,为什么继承的测试方法没有给出正确的断言输出?

时间:2016-09-21 15:35:13

标签: python inheritance pytest

我正在开发一个具有命令行界面的应用程序,我想使用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而没有其他信息,这与测试方法未被继承的情况不同,并且非常详细地描述了assert ed表达式。这是适得其反的,因为无法准确说出断言失败的原因。

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

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

1 个答案:

答案 0 :(得分:1)

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

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

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

必须在导入相关模块之前完成此操作。