代码之家  ›  专栏  ›  技术社区  ›  WloHu

pytest-向所有或标记的测试函数添加断言

  •  2
  • WloHu  · 技术社区  · 7 年前

    我对一个固定装置(命名为 obj 这里)在大多数测试函数的末尾,比如:

    assert obj.is_empty
    assert obj.no_errors
    

    如何将这些步骤附加到每个测试函数中,或者只添加标记的步骤,以便:

    • 将与 pytest.mark.parametrize ,
    • 将报告 失败 (不是) 误差 )当常见的断言失败时?
    1 回复  |  直到 7 年前
        1
  •  1
  •   hoefling    7 年前

    尽管我个人不喜欢在测试中运行隐藏断言的想法( 显式优于隐式 )这肯定是可行的 pytest 通过实现自己的 pytest_runtest_call 钩子。一个简单的例子:

    # conftest.py
    import pytest
    
    
    class Obj:
    
        def __init__(self):
            self.is_empty = True
            self.no_errors = True
    
    
    @pytest.fixture
    def obj():
        return Obj()
    
    
    def pytest_runtest_call(item):
        item.runtest()
        try:
            obj = item.funcargs['obj']
            assert obj.is_empty
            assert obj.no_errors
        except KeyError:
            pass
    

    实例测试:

    import pytest
    
    
    def test_spam(obj):
        assert True
    
    def test_eggs(obj):
        obj.is_empty = False
        assert True
    
    def test_bacon(obj):
        obj.no_errors = False
        assert True
    
    @pytest.mark.parametrize('somearg', ['foo', 'bar', 'baz'])
    def test_parametrized(obj, somearg):
        assert True
    

    运行测试会产生:

    $ pytest -sv
    ================================== test session starts ==================================
    platform darwin -- Python 3.6.4, pytest-3.7.3, py-1.5.4, pluggy-0.7.1 -- 
    cachedir: .pytest_cache
    rootdir: /Users/hoefling/projects/private/stackoverflow, inifile:
    plugins: cov-2.5.1
    collected 3 items
    
    test_spam.py::test_spam PASSED
    test_spam.py::test_eggs FAILED
    test_spam.py::test_bacon FAILED
    test_spam.py::test_parametrized[foo] PASSED
    test_spam.py::test_parametrized[bar] PASSED
    test_spam.py::test_parametrized[baz] PASSED
    
    ======================================== FAILURES =======================================
    _______________________________________ test_eggs _______________________________________
    
    item = <Function 'test_eggs'>
    
        def pytest_runtest_call(item):
            item.runtest()
            try:
            obj = item.funcargs['obj']
    >           assert obj.is_empty
    E           assert False
    E            +  where False = <conftest.Obj object at 0x105854ba8>.is_empty
    
    conftest.py:20: AssertionError
    ______________________________________ test_bacon _______________________________________
    
    item = <Function 'test_bacon'>
    
        def pytest_runtest_call(item):
            item.runtest()
            try:
                obj = item.funcargs['obj']
                assert obj.is_empty
    >           assert obj.no_errors
    E           assert False
    E            +  where False = <conftest.Obj object at 0x105868198>.no_errors
    
    conftest.py:21: AssertionError
    ========================== 2 failed, 1 passed in 0.05 seconds ===========================