【问题标题】:Setting dynamic folder and report name in pytest在 pytest 中设置动态文件夹和报告名称
【发布时间】:2020-03-06 21:11:50
【问题描述】:

我在 Python 的 pytest 中动态设置报告名称和文件夹时遇到问题。 例如:我已经运行了所有 pytest 的测试 @ 2020-03-06 21:50,所以我想将我的报告存储在文件夹 20200306 中,名称为 report_2150.html。我希望它在测试完成后立即自动触发。

我在 VS Code 中工作,我的目标是与没有自动化经验的同事分享我的工作,所以我的目标是将其用作“点击测试开始”。

我的项目结构:

webtools/
|── .vscode/
|──── settings.json
|── drivers/
|── pages/
|── reports/
|── tests/
|──── __init__.py
|──── config.json
|──── conftest.py
|──── test_1.py
|──── test_2.py
|── setup.py

代码示例:

settings.json

{
    "python.linting.pylintEnabled": false,
    "python.linting.flake8Enabled": true,
    "python.linting.enabled": true,
    "python.pythonPath": "C:\\Users\\user\\envs\\webtools\\Scripts\\python.exe",
    "python.testing.pytestArgs": [
        "tests",
        "--self-contained-html",
        "--html=./reports/tmp_report.html" 
    ],
    "python.testing.unittestEnabled": false,
    "python.testing.nosetestsEnabled": false,
    "python.testing.pytestEnabled": true,
    "python.testing.unittestArgs": [
        "-v",
        "-s",
        "./tests",
        "-p",
        "test_*.py"
    ]
}

config.json

{
    "browser": "chrome",
    "wait_time": 10
}

conftest.py

import json
import pytest
from datetime import datetime
import time
import shutil
import os


from selenium import webdriver
from selenium.webdriver import Chrome

CONFIG_PATH = 'tests/config.json'
DEFAULT_WAIT_TIME = 10
SUPPORTED_BROWSERS = ['chrome', 'explorer']


@pytest.fixture(scope='session')
def config():
    # Read the JSON config file and returns it as a parsed dict
    with open(CONFIG_PATH) as config_file:
        data = json.load(config_file)
    return data


@pytest.fixture(scope='session')
def config_browser(config):
    # Validate and return the browser choice from the config data
    if 'browser' not in config:
        raise Exception('The config file does not contain "browser"')
    elif config['browser'] not in SUPPORTED_BROWSERS:
        raise Exception(f'"{config["browser"]}" is not a supported browser')
    return config['browser']


@pytest.fixture(scope='session')
def config_wait_time(config):
    # Validate and return the wait time from the config data
    return config['wait_time'] if 'wait_time' in config else DEFAULT_WAIT_TIME


@pytest.fixture
def browser(config_browser, config_wait_time):
    # Initialize WebDriver
    if config_browser == 'chrome':
        driver = webdriver.Chrome(r"./drivers/chromedriver.exe")
    elif config_browser == 'explorer':
        driver = webdriver.Ie(r"./drivers/IEDriverServer.exe")
    else:
        raise Exception(f'"{config_browser}" is not a supported browser')

    # Wait implicitly for elements to be ready before attempting interactions
    driver.implicitly_wait(config_wait_time)

    # Maximize window for test
    driver.maximize_window()

    # Return the driver object at the end of setup
    yield driver

    # For cleanup, quit the driver
    driver.quit()


@pytest.fixture(scope='session')
def cleanup_report():
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    os.chdir("./reports")
    os.mkdir(timestamp)

    yield

    shutil.move("./tmp_report.html", "./%s/test_report.html" % timestamp)

在当前情况下,报告在报告文件夹中创建为tmp_report.html,但我不知道如何在所有测试完成并且tmp_report.html 存在并在文件夹中完成后强制运行cleanup_report()。为了检查是否完整,我假设我必须验证所有 html 标签是否都有关闭(或至少 <html> 一个)。

有人可以帮我吗?如果您需要更多代码部分,我会尽快提供。

提前谢谢你!

【问题讨论】:

    标签: python python-3.x pytest pytest-html


    【解决方案1】:

    您可以在 pytest_configure 挂钩的自定义 impl 中自定义插件选项。将此示例代码放在项目根目录中的 conftest.py 文件中:

    from datetime import datetime
    from pathlib import Path
    import pytest
    
    
    @pytest.hookimpl(tryfirst=True)
    def pytest_configure(config):
        # set custom options only if none are provided from command line
        if not config.option.htmlpath:
            now = datetime.now()
            # create report target dir
            reports_dir = Path('reports', now.strftime('%Y%m%d'))
            reports_dir.mkdir(parents=True, exist_ok=True)
            # custom report file
            report = reports_dir / f"report_{now.strftime('%H%M')}.html"
            # adjust plugin options
            config.option.htmlpath = report
            config.option.self_contained_html = True
    

    如果您想完全忽略从命令行传递的内容,请删除 if not config.option.htmlpath: 条件。

    如果您想坚持使用当前的 impl,请注意在夹具拆卸时,pytest-html 尚未编写报告。将代码从 cleanup_report 移动到 pytest_sessionfinish 挂钩的自定义 impl 以确保 pytest-html 已经写入默认报告文件:

    @pytest.hookimpl(trylast=True)
    def pytest_sessionfinish(session, exitstatus):
        shutil.move(...)
    

    【讨论】:

    • 非常感谢您的帮助。我一直坚持第一个建议并删除了 if 条件。这完美无缺。
    • @MrTeatime 很高兴我能帮上忙!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-29
    • 1970-01-01
    相关资源
    最近更新 更多