如果有其他人可能有类似的需求,我会分享我所做的事情。
首先,已经有一个出色的
pytest-json-report 来导出JSON结果。然而,我制作了一个更简单、功能更少的插件,直接使用
pytest_report_to_serializable:
import json
from socket import gethostname
def pytest_addoption(parser, pluginmanager):
parser.addoption(
'--report-file', default='%s.json' % gethostname(), help='path to JSON report'
)
def pytest_configure(config):
plugin = JsonTestsExporter(config=config)
config._json_report = plugin
config.pluginmanager.register(plugin)
def pytest_unconfigure(config):
plugin = getattr(config, '_json_report', None)
if plugin is not None:
del config._json_report
config.pluginmanager.unregister(plugin)
print('Report saved in: %s' % config.getoption('--report-file'))
class JsonTestsExporter(object):
def __init__(self, config):
self._config = config
self._export_data = {'collected': 0, 'results': []}
def pytest_report_collectionfinish(self, config, start_path, startdir, items):
self._export_data['collected'] = len(items)
def pytest_runtest_logreport(self, report):
data = self._config.hook.pytest_report_to_serializable(
config=self._config, report=report
)
self._export_data['results'].append(data)
def pytest_sessionfinish(self, session):
report_file = self._config.getoption('--report-file')
with open(report_file, 'w+') as fd:
fd.write(json.dumps(self._export_data))
原因是我想要使用
pytest_report_from_serializable导入结果。
简化的Dockerfile:
FROM debian:buster-slim AS builder
COPY [ "requirements.txt", "run.py", "/artifacts/" ]
COPY [ "json_tests_exporter", "/artifacts/json_tests_exporter/" ]
RUN apt-get update\
&& apt-get install --no-install-recommends -y python3-pip python3-setuptools\
&& pip3 install wheel\
&& sh -c 'cd /artifacts/json_tests_exporter && python3 setup.py bdist_wheel'
FROM debian:buster-slim
ARG USER_UID=1000
ARG USER_GID=${USER_UID}
COPY --from=builder --chown=${USER_UID}:${USER_GID} /artifacts /artifacts
RUN apt-get update\
&& apt-get install --no-install-recommends -y wget gpg openssl python3-pip\
&& groupadd -g ${USER_GID} pytest\
&& adduser --disabled-password --gecos "" --uid ${USER_UID} --gid ${USER_GID} pytest\
&& cp -p /artifacts/run.py /usr/local/bin/run.py\
&& su pytest -c "pip3 install -r /artifacts/requirements.txt"\
&& su pytest -c "pip3 install /artifacts/json_tests_exporter/dist/*.whl"\
&& su pytest -c "mkdir -p /home/pytest/tests /home/pytest/results"
VOLUME [ "/home/pytest/tests", "/home/pytest/results" ]
USER pytest
WORKDIR /home/pytest/tests
ENTRYPOINT [ "/usr/local/bin/run.py" ]
JSON导出插件位于与Dockerfile相同的文件夹中。
run.py非常简单:
import pytest
import sys
from socket import gethostname
def main():
if 1 == len(sys.argv):
args = [
'--report-file=/home/pytest/results/%s.json' % gethostname(),
'-qvs',
'/home/pytest/tests'
]
else:
args = sys.argv[1:]
try:
res = pytest.main(args)
except Exception as e:
print(e)
res = 1
return res
if __name__ == "__main__":
sys.exit(main())
requirements.txt 只包含:
python-gnupg==0.4.4
pytest>=7.1.2
基本上,我可以用以下方式运行所有东西:
docker build -t pytest-runner ./tests/docker/pytest_runner
docker run --rm -it -v $(pwd)/tests/results:/home/pytest/results -v $(pwd)/tests/fixtures:/home/pytest/tests pytest-runner
我可以帮您翻译成中文:
最后两行是我使用 Docker API 在 Python 中通过 pytest_sessionstart(session)
钩子程序自动运行的。
pytest
并知道它将在从您构建的镜像生成的容器内执行。然后,您可能希望拥有一个通用的entrypoint
,以便您可以像在shell中一样使用相同的命令(CMD
)。 - EDG956entrypoint
和cmd
应该能让你对我所说的有一些了解。 - EDG956docker run --rm --entrypoint=pytest <your_docker_image>
这样的东西。 - undefined