如何让 pytest 在非测试模块中重写断言 [英] How to let pytest rewrite assert in non-test modules

查看:81
本文介绍了如何让 pytest 在非测试模块中重写断言的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在一个单独的 python 文件中定义了所有自定义断言,该文件不是一个测试模块.

We defined all our custom assertions in a separate python file which is not a test module.

例如:custom_asserts.py

class CustomAsserts(object):
    def silly_assert(self, foo, bar):
        assert foo == bar , 'some error message'

如果我们在测试中直接使用assert,我们会得到关于AssertionError的额外信息,这非常有用.

If we use assert directly in tests, we will get extra info about the AssertionError, which is very useful.

在测试中直接使用 assert 的输出:

Output of directly use assert in tests:

>       assert 'foo' == 'bar', 'some error message'
E       AssertionError: some error message
E       assert 'foo' == 'bar'
E         - foo
E         + bar

但是我们发现,如果调用我们在单独模块中定义的断言方法,则不会显示额外信息.

But we found that if we call the assertion method we defined in separate module, extra info won't show.

from custom_asserts import CustomAsserts
asserts = CustomAsserts()
def test_silly():
    asserts.silly_assert('foo', 'bar')

运行测试后的输出:

>       assert 'foo' == 'bar', 'some error message'
E       AssertionError: some error message

我们也在 pytest 文档中发现了这一点:高级断言自省

And we also found this in pytest docs: Advanced assertion introspection

pytest 只重写其测试直接发现的测试模块收集过程,因此在支持的模块中断言不是自己的测试模块不会被重写.

pytest only rewrites test modules directly discovered by its test collection process, so asserts in supporting modules which are not themselves test modules will not be rewritten.

所以我的问题是,有没有办法让 pytest 像测试模块一样对其他模块进行相同的断言重写?或者有什么方法可以实现这一目标?

So my question is, is there a way to let pytest do the same assert rewriting to other modules just like test modules? Or is there any hacky way to achieve that?

推荐答案

更新:

Pytest 3.0 引入了一种新方法 register_assert_rewrite 来实现这一确切功能.如果您使用的是 pytest 3.0 或更高版本,请尝试此操作.register_assert_rewrite

Pytest 3.0 introduced a new method register_assert_rewrite to implement this exact feature. If you are using pytest 3.0 or later, please try this. register_assert_rewrite

原答案:

回答我自己的问题有点连贯,但我想我找到了解决方案并想分享.

It's kind of wired to answer my own question but I think I found the solution and want to share.

诀窍在于 pytest 如何收集测试模块.我们可以在pytest.ini中定义python_files,这样pytest会考虑更多的模块作为测试模块.

The trick is in how pytest collect test modules. We can define python_files in pytest.ini so that pytest will consider more modules as test modules.

例如,在我的例子中,我所有的自定义断言模块都以asserts"结尾,所以我的 pytest.ini 是:

For example, in my case, all my custom asserts module ends with 'asserts', so my pytest.ini is:

[pytest]
python_files = *asserts.py test_*.py *_test.py

另一个棘手的事情是在 conftest.py 中.看来我们必须避免在 conftest.py 中导入 asserts 模块.我的假设是看起来 pytest 用来重写断言的技术实际上是重写 .pyc 文件,并且由于 conftest.py 在收集之前加载,如果我们导入断言模块,采集前会生成模块的.pyc,可能导致pytest无法再次重写.pyc文件.

Another tricky thing is in conftest.py. It seems we have to avoid import the asserts module in conftest.py. My assumption is that it looks like the technology pytest uses to rewrite assert is actually rewrite .pyc file, and since conftest.py is loaded before collecting, if we import the asserts module, .pyc of the module would be generated before collecting, which may make pytest unable to rewrite the .pyc file again.

所以在我的 conftest.py 中,我必须做这样的事情:

So in my conftest.py, I have to do thing like:

@pytest.fixture(autouse=Ture)
def setup_asserts(request):
    from custom_asserts import CustomAsserts
    request.instance.asserts = CustomAsserts()

我会得到额外的错误信息,就像在测试脚本中直接使用关键字assert一样.

And I will get the extra error info just like using keyword assert directly in test script.

这篇关于如何让 pytest 在非测试模块中重写断言的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆