【问题标题】:Pytest HTML report: how to get the name of the report file?Pytest HTML 报告:如何获取报告文件的名称?
【发布时间】:2017-10-13 12:40:20
【问题描述】:

我正在使用带有pytest-html 模块的pytest 来生成HTML 测试报告。

在拆解阶段,我使用webbrowser.open('file:///path_to_report.html') 自动在浏览器中打开生成的 HTML 报告——这工作正常,但我正在使用不同的参数运行测试,并且为每组参数设置不同的报告文件通过命令行参数:

pytest -v mytest.py::TestClassName --html=report_localhost.html

我的拆解代码如下所示:

@pytest.fixture(scope='class')
def config(request):
    claz = request.cls
    claz.host = request.config.getoption("--host", default=HOST_DEFAULT)
    ...

    def teardown_env():
        print('destroying test harness')
        webbrowser.open("file:///path_to_report_localhost.html")

    request.addfinalizer(teardown_env)

    return "prepare_env"

问题是如何从测试中的拆卸挂钩访问报告文件名,这样我就可以使用作为命令行参数传入的任何路径,而不是硬编码,即--html=report_for_host_xyz.html?

⚠️ 更新

使用类范围的夹具来显示生成的 HTML 不是正确的方法,因为pytest-html 将报告生成挂钩到会话终结器范围,这意味着在调用类终结器时报告仍未生成,并且您可能需要刷新浏览器页面才能真正看到报告。如果它似乎可以工作,那只是因为浏览器窗口可能需要一些额外的时间才能打开,这可能会在文件加载到浏览器中时完成报告生成。

this answer 中解释了正确的方法,归结为使用 pytest_unconfigure 钩子。

【问题讨论】:

    标签: python pytest pytest-html


    【解决方案1】:

    您可以在夹具中放置一个断点,然后查看 request.config.option 对象 — 这是 pytest 放置所有 argparsed 键的地方。

    你要找的是request.config.option.htmlpath。

    @pytest.fixture(scope='class')
    def config(request):
        claz = request.cls
        claz.host = request.config.getoption("--host", default=HOST_DEFAULT)
    
        yield 100   # a value of the fixture for the tests
    
        print('destroying test harness')
        webbrowser.open("file:///{}".format(request.config.option.htmlpath))
    

    或者您可以对--host 键执行相同的操作:

    @pytest.fixture(scope='class')
    def config(request):
        claz = request.cls
        claz.host = request.config.getoption("--host", default=HOST_DEFAULT)
    
        yield 100   # a value of the fixture for the tests
    
        print('destroying test harness')
        webbrowser.open("file:///{}".format(request.config.getoption("--html")))
    

    【讨论】:

    • 非常感谢!因为我只在命令行上传递了一个相对路径 (--html=report_localhost.html),所以我必须在绝对文件夹前面加上:html_report_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), request.config.option.htmlpath); webbrowser.open("file://{path}".format(path=html_report_path))
    • @ccpizza 在这种情况下,您可能需要os.path.join(request.config.invocation_dir, filename)。在极少数情况下,os.path.join(request.config.rootdir, filename)。但是根目录是所有找到的测试的共同父目录,而调用目录是您启动 pytest 进程的位置。考虑:cd ~/proj; pytest ./some/dir1/ ./some/dir2/t.py — 调用目录将是 ~/proj,但根目录将是 ~/proj/some。
    • 这样干净多了!非常感激! ?
    • UPD:糟糕。我有点错。根目录是 pytest 检测项目的根目录的地方,通常是通过setup.py、setup.cfg、pytest.cfg 和类似文件的存在。如果找不到它们,则它是调用目录。如果测试在调用目录之上,那么最常见的父目录。因此,您可以使用os.path.join(request.config.rootdir, filename),以防您希望路径相对于项目根目录。但是作为基本目录的调用(又名当前)目录仍然更自然,并且是用户所期望的。
    • 我的设置很简单,所以invocation_dir 和rootdir 指向同一个路径。但很高兴知道两者之间的区别。顺便说一句,它们都返回 LocalPath 对象而不是字符串,因此应该用作 request.config.rootdir.strpath。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多