在pytest中设置动态文件夹和报告名称
Setting dynamic folder and report name in pytest
我在 Python 的 pytest 中动态设置报告名称和文件夹时遇到问题。
例如:我 运行 所有 pytest 的测试 @ 2020-03-06 21:50 所以我想将我的报告存储在名称为 report_2150.html
的文件夹 20200306
中。我希望它在测试完成后立即自动触发。
我在 VS Code 工作,我的目标是与没有自动化经验的同事分享我的工作,所以我打算将它用作 "click test to start"。
我的项目结构:
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
,但我不知道如何在所有测试完成后强制 运行ning cleanup_report()
并且tmp_report.html
在文件夹中存在且完整。为了检查是否完整,我假设我必须验证所有 html 标签是否都有结束(或至少 <html>
一个)。
有人可以帮我吗?如果您需要更多代码部分,我会尽快提供。
提前致谢!
您可以在 pytest_configure
挂钩的自定义实现中自定义插件选项。将此示例代码放入项目根目录中的 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:
条件。
如果您想坚持当前的实现,请注意在固定装置拆卸时,pytest-html
尚未编写报告。将代码从 cleanup_report
移动到 pytest_sessionfinish
挂钩的自定义实现,以确保 pytest-html
已经写入默认报告文件:
@pytest.hookimpl(trylast=True)
def pytest_sessionfinish(session, exitstatus):
shutil.move(...)
我在 Python 的 pytest 中动态设置报告名称和文件夹时遇到问题。
例如:我 运行 所有 pytest 的测试 @ 2020-03-06 21:50 所以我想将我的报告存储在名称为 report_2150.html
的文件夹 20200306
中。我希望它在测试完成后立即自动触发。
我在 VS Code 工作,我的目标是与没有自动化经验的同事分享我的工作,所以我打算将它用作 "click test to start"。
我的项目结构:
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
,但我不知道如何在所有测试完成后强制 运行ning cleanup_report()
并且tmp_report.html
在文件夹中存在且完整。为了检查是否完整,我假设我必须验证所有 html 标签是否都有结束(或至少 <html>
一个)。
有人可以帮我吗?如果您需要更多代码部分,我会尽快提供。
提前致谢!
您可以在 pytest_configure
挂钩的自定义实现中自定义插件选项。将此示例代码放入项目根目录中的 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:
条件。
如果您想坚持当前的实现,请注意在固定装置拆卸时,pytest-html
尚未编写报告。将代码从 cleanup_report
移动到 pytest_sessionfinish
挂钩的自定义实现,以确保 pytest-html
已经写入默认报告文件:
@pytest.hookimpl(trylast=True)
def pytest_sessionfinish(session, exitstatus):
shutil.move(...)