【问题标题】:How can I display the test name *after* the test using pytest?如何在使用 pytest 的测试之后*显示测试名称?
【发布时间】:2021-05-13 19:57:17
【问题描述】:

大多数时候,当我使用 pytest 时,输出非常非常长。一百多行。很多时候我想要这个输出,我真的想要。 --tb=short 不是真的 一个非常好的方法。但我不想在我的 tmux 窗口中向后滚动 200 行来查找我的测试输出,因为这超级烦人。

我想要的是这样的:

______________________ >>test_my_test_with_a_lot_of_output _______________________
# imagine lots of test output here
______________________ <<test_my_test_with_a_lot_of_output _______________________

我可以在 py.test 中使用一些标志或设置来实现这种输出吗?

【问题讨论】:

    标签: python pytest


    【解决方案1】:

    运行测试时使用“pytest -rA”

    参见文档here

    【讨论】:

    • 链接已损坏。
    • 使用 pytest 6.2.4 我在交互式帮助中看不到“-A”。改名了吗?
    • @IainSamuelMcLeanElder 您可以在-r chars 下找到它(可以选择删除空格,这就是它变成-rA 的方式),其中A 代表“全部”。
    • 这对于某些重要的需求很有用,例如查看测试的执行顺序。但对我来说的问题是它不会“交错”提及测试名称与输出到 stdout 和 stderr (即当也使用 -s 开关时)
    【解决方案2】:

    您可以在主/根conftest.py 中添加一个夹具,该夹具将在每个测试用例之前和之后自动调用。喜欢

    @pytest.fixture(scope='function', autouse=True)
    def test_log(request):
        logging.info("Test '{}' STARTED".format(request.node.nodeid)) # Here logging is used, you can use whatever you want to use for logs
        def fin():
            logging.info("Test '{}' COMPLETED".format(request.node.nodeid))
        request.addfinalizer(fin)
    

    在这里,request.node.nodeid 为您提供了测试的名称。

    【讨论】:

    • 不错的方法。不过,一个小问题是STARTED 将在测试设置子句中打印,COMPLETED 在测试拆卸子句中打印:[captured stdout setup] Test abc STARTED; [captured stdout call] Long output here... [captured stdout teardown] Test abc COMPLETED 但这种方法仍然比我的优雅得多。
    【解决方案3】:

    我找不到使用钩子实现此目的的简单方法。但这是我将如何实现这一点。 不过,这不是一个理想的实现方式。

    # contest.py
    import pytest
    import _pytest
    
    class TerminalReporter(_pytest.terminal.TerminalReporter):
        def _gettestname(self, rep):
            # actually "rename" original method for clarity
            return super()._getfailureheadline(rep)
    
        def _getfailureheadline(self, rep):
            # instead of test name
            # (which is originally printed at the top of report)
            # return prefixed name
            return '>>' + self._gettestname(rep)
    
        def _outrep_summary(self, rep):
            super()._outrep_summary(rep)
            # after printing test report end, print out test name again
            # XXX: here we hard-code color, so red will be used even for passed tests
            # (if passes logging is enabled)
            # You can add some more logic with analyzing report status
            self.write_sep('_', '<<' + self._gettestname(rep), red=True)
    
    @pytest.hookimpl(trylast=True)
    def pytest_configure(config):
        # overwrite original TerminalReporter plugin with our subclass
        # we want this hook to be executed after all other implementations
        # to be able to unregister original plugin
        reporter = TerminalReporter(config)
        config.pluginmanager.unregister(name='terminalreporter')
        config.pluginmanager.register(reporter, 'terminalreporter')
    

    有关扩展此方法的灵感,请前往_pytest.terminal.TerinalReporter 类来源。

    【讨论】:

      猜你喜欢
      • 2019-07-21
      • 1970-01-01
      • 1970-01-01
      • 2017-12-17
      • 1970-01-01
      • 2016-11-21
      • 1970-01-01
      • 1970-01-01
      • 2021-06-12
      相关资源
      最近更新 更多