2016-06-30 41 views
3

我们在一个不是测试模块的单独python文件中定义了所有的定制断言。如何让pytest重写在非测试模块中断言

例如: custom_asserts.py

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

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

的直接使用断言测试输出:

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

但我们发现,如果我们所说的,我们在不同的模块定义的断言方法,额外的信息将不会显示。运行测试后

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文档:Advanced assertion introspection

pytest仅重写它的测试 采集过程中直接发现的测试模块,所以断言在支持不是 的模块本身,测试模块将不会被重写。

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

回答

4

更新:

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

原来的答复:

它是一种连接到回答自己的问题,但我想我找到了解决方案,并希望分享。

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

例如,在我的情况,我所有的自定义断言模块“断言”结束,所以我pytest.ini是:

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

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

所以在我的conftest。PY,我必须做的事情,如:

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

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

+0

[回答你自己的问题很好,甚至鼓励!](http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/)网络用户界面甚至建议您可能希望编写问题并立即回答问题,就像记录和分享在开发软件时发现的重要事项的方法一样。 – clacke