================
pytest-reportlog
================
|python| |version| |anaconda| |ci| |black|
.. |version| image:: http://img.shields.io/pypi/v/pytest-reportlog.svg
:target: https://pypi.python.org/pypi/pytest-reportlog
.. |anaconda| image:: https://img.shields.io/conda/vn/conda-forge/pytest-reportlog.svg
:target: https://anaconda.org/conda-forge/pytest-reportlog
.. |ci| image:: https://github.com/pytest-dev/pytest-reportlog/workflows/test/badge.svg
:target: https://github.com/pytest-dev/pytest-reportlog/actions
.. |python| image:: https://img.shields.io/pypi/pyversions/pytest-reportlog.svg
:target: https://pypi.python.org/pypi/pytest-reportlog/
.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/ambv/black
Replacement for the ``--resultlog`` option, focused in simplicity and extensibility.
.. note::
This plugin was created so developers can try out the candidate to replace the
`deprecated --resultlog <https://docs.pytest.org/en/latest/deprecations.html#result-log-result-log>`__ option.
If you use ``--resultlog``, please try out ``--report-log`` and provide feedback.
Usage
=====
Install ``pytest-reportlog`` as a test requirement in your test environment.
The ``--report-log=FILE`` option writes a file in `JSON lines <https://jsonlines.org/>`__ format as the test session executes.
Each line of the report log contains a self contained JSON object corresponding to a testing event,
such as a collection or a test result report. The file is guaranteed to be flushed after writing
each line, so systems can read and process events in real-time.
Each JSON object contains a special key ``$report_type``, which contains a unique identifier for
that kind of report object. For future compatibility, consumers of the file should ignore reports
they don't recognize, as well as ignore unknown properties/keys in JSON objects that they do know,
as future pytest versions might enrich the objects with more properties/keys.
Compression
===========
Common compression suffixes like `.gz`, `.bz2` and `.xz` will automatically use the requested compression format.
The implementations from the python stdlib are used and must be enabled in the python builds.
Example
-------
Consider this file:
.. code-block:: python
# content of test_report_example.py
def test_ok():
assert 5 + 5 == 10
def test_fail():
assert 4 + 4 == 1
::
$ pytest test_report_example.py -q --report-log=log.jsonl
.F [100%]
================================= FAILURES =================================
________________________________ test_fail _________________________________
def test_fail():
> assert 4 + 4 == 1
E assert (4 + 4) == 1
test_report_example.py:8: AssertionError
------------------- generated report log file: log.jsonl --------------------
1 failed, 1 passed in 0.12s
The generated ``log.jsonl`` will contain a JSON object per line:
::
$ cat log.jsonl
{"pytest_version": "5.2.2", "$report_type": "SessionStart"}
{"nodeid": "", "outcome": "passed", "longrepr": null, "result": null, "sections": [], "$report_type": "CollectReport"}
{"nodeid": "test_report_example.py", "outcome": "passed", "longrepr": null, "result": null, "sections": [], "$report_type": "CollectReport"}
{"nodeid": "test_report_example.py::test_ok", "location": ["test_report_example.py", 0, "test_ok"], "keywords": {"test_ok": 1, "pytest-reportlog": 1, "test_report_example.py": 1}, "outcome": "passed", "longrepr": null, "when": "setup", "user_properties": [], "sections": [], "duration": 0.0, "$report_type": "TestReport"}
{"nodeid": "test_report_example.py::test_ok", "location": ["test_report_example.py", 0, "test_ok"], "keywords": {"test_ok": 1, "pytest-reportlog": 1, "test_report_example.py": 1}, "outcome": "passed", "longrepr": null, "when": "call", "user_properties": [], "sections": [], "duration": 0.0, "$report_type": "TestReport"}
{"nodeid": "test_report_example.py::test_ok", "location": ["test_report_example.py", 0, "test_ok"], "keywords": {"test_ok": 1, "pytest-reportlog": 1, "test_report_example.py": 1}, "outcome": "passed", "longrepr": null, "when": "teardown", "user_properties": [], "sections": [], "duration": 0.00099945068359375, "$report_type": "TestReport"}
{"nodeid": "test_report_example.py::test_fail", "location": ["test_report_example.py", 4, "test_fail"], "keywords": {"test_fail": 1, "pytest-reportlog": 1, "test_report_example.py": 1}, "outcome": "passed", "longrepr": null, "when": "setup", "user_properties": [], "sections": [], "duration": 0.0, "$report_type": "TestReport"}
{"nodeid": "test_report_example.py::test_fail", "location": ["test_report_example.py", 4, "test_fail"], "keywords": {"test_fail": 1, "pytest-reportlog": 1, "test_report_example.py": 1}, "outcome": "failed", "longrepr": {"reprcrash": {"path": "D:\\projects\\pytest-reportlog\\test_report_example.py", "lineno": 6, "message": "assert (4 + 4) == 1"}, "reprtraceback": {"reprentries": [{"type": "ReprEntry", "data": {"lines": [" def test_fail():", "> assert 4 + 4 == 1", "E assert (4 + 4) == 1"], "reprfuncargs": {"args": []}, "reprlocals": null, "reprfileloc": {"path": "test_report_example.py", "lineno": 6, "message": "AssertionError"}, "style": "long"}}], "extraline": null, "style": "long"}, "sections": [], "chain": [[{"reprentries": [{"type": "ReprEntry", "data": {"lines": [" def test_fail():", "> assert 4 + 4 == 1", "E assert (4 + 4) == 1"], "reprfuncargs": {"args": []}, "reprlocals": null, "reprfileloc": {"path": "test_report_example.py", "lineno": 6, "message": "AssertionError"}, "style": "long"}}], "extraline": null, "style": "long"}, {"path": "D:\\projects\\pytest-reportlog\\test_report_example.py", "lineno": 6, "message": "assert (4 + 4) == 1"}, null]]}, "when": "call", "user_properties": [], "sections": [], "duration": 0.0009992122650146484, "$report_type": "TestReport"}
{"nodeid": "test_report_example.py::test_fail", "location": ["test_report_example.py", 4, "test_fail"], "keywords": {"test_fail": 1, "pytest-reportlog": 1, "test_report_example.py": 1}, "outcome": "passed", "longrepr": null, "when": "teardown", "user_properties": [], "sections": [], "duration": 0.0, "$report_type": "TestReport"}
{"exitstatus": 1, "$report_type": "SessionFinish"}
record_property
---------------
The ``record_property`` fixture allows to log additional information for a test, just like with JUnitXML format.
Consider this test file:
.. code-block:: python
def test_function(record_property):
record_property("price", 12.34)
record_property("fruit", "banana")
assert True
This information will be recorded in the report JSON objects under the ``user_properties`` key as follows::
..., "user_properties": [["price", 12.34], ["fruit", "banana"]], ...
Note that this nested list construct is just the JSON representation
of a list of tuples (name-value pairs).
Raw data
{
"_id": null,
"home_page": "https://github.com/pytest-dev/pytest-reportlog",
"name": "pytest-reportlog",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "",
"keywords": "pytest",
"author": "Bruno Oliveira",
"author_email": "nicoddemus@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/da/a0/d1372b23d415a0766389480633a676fb1530e94ae8f6ea84619cae0ac215/pytest-reportlog-0.4.0.tar.gz",
"platform": "any",
"description": "================\npytest-reportlog\n================\n\n|python| |version| |anaconda| |ci| |black|\n\n.. |version| image:: http://img.shields.io/pypi/v/pytest-reportlog.svg\n :target: https://pypi.python.org/pypi/pytest-reportlog\n\n.. |anaconda| image:: https://img.shields.io/conda/vn/conda-forge/pytest-reportlog.svg\n :target: https://anaconda.org/conda-forge/pytest-reportlog\n\n.. |ci| image:: https://github.com/pytest-dev/pytest-reportlog/workflows/test/badge.svg\n :target: https://github.com/pytest-dev/pytest-reportlog/actions\n\n.. |python| image:: https://img.shields.io/pypi/pyversions/pytest-reportlog.svg\n :target: https://pypi.python.org/pypi/pytest-reportlog/\n\n.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg\n :target: https://github.com/ambv/black\n\nReplacement for the ``--resultlog`` option, focused in simplicity and extensibility.\n\n.. note::\n This plugin was created so developers can try out the candidate to replace the\n `deprecated --resultlog <https://docs.pytest.org/en/latest/deprecations.html#result-log-result-log>`__ option.\n\n If you use ``--resultlog``, please try out ``--report-log`` and provide feedback.\n\nUsage\n=====\n\nInstall ``pytest-reportlog`` as a test requirement in your test environment.\n\nThe ``--report-log=FILE`` option writes a file in `JSON lines <https://jsonlines.org/>`__ format as the test session executes.\n\nEach line of the report log contains a self contained JSON object corresponding to a testing event,\nsuch as a collection or a test result report. The file is guaranteed to be flushed after writing\neach line, so systems can read and process events in real-time.\n\nEach JSON object contains a special key ``$report_type``, which contains a unique identifier for\nthat kind of report object. For future compatibility, consumers of the file should ignore reports\nthey don't recognize, as well as ignore unknown properties/keys in JSON objects that they do know,\nas future pytest versions might enrich the objects with more properties/keys.\n\nCompression\n===========\n\nCommon compression suffixes like `.gz`, `.bz2` and `.xz` will automatically use the requested compression format.\nThe implementations from the python stdlib are used and must be enabled in the python builds.\n\nExample\n-------\n\nConsider this file:\n\n.. code-block:: python\n\n # content of test_report_example.py\n\n\n def test_ok():\n assert 5 + 5 == 10\n\n\n def test_fail():\n assert 4 + 4 == 1\n\n\n::\n\n $ pytest test_report_example.py -q --report-log=log.jsonl\n .F [100%]\n ================================= FAILURES =================================\n ________________________________ test_fail _________________________________\n\n def test_fail():\n > assert 4 + 4 == 1\n E assert (4 + 4) == 1\n\n test_report_example.py:8: AssertionError\n ------------------- generated report log file: log.jsonl --------------------\n 1 failed, 1 passed in 0.12s\n\nThe generated ``log.jsonl`` will contain a JSON object per line:\n\n::\n\n $ cat log.jsonl\n {\"pytest_version\": \"5.2.2\", \"$report_type\": \"SessionStart\"}\n {\"nodeid\": \"\", \"outcome\": \"passed\", \"longrepr\": null, \"result\": null, \"sections\": [], \"$report_type\": \"CollectReport\"}\n {\"nodeid\": \"test_report_example.py\", \"outcome\": \"passed\", \"longrepr\": null, \"result\": null, \"sections\": [], \"$report_type\": \"CollectReport\"}\n {\"nodeid\": \"test_report_example.py::test_ok\", \"location\": [\"test_report_example.py\", 0, \"test_ok\"], \"keywords\": {\"test_ok\": 1, \"pytest-reportlog\": 1, \"test_report_example.py\": 1}, \"outcome\": \"passed\", \"longrepr\": null, \"when\": \"setup\", \"user_properties\": [], \"sections\": [], \"duration\": 0.0, \"$report_type\": \"TestReport\"}\n {\"nodeid\": \"test_report_example.py::test_ok\", \"location\": [\"test_report_example.py\", 0, \"test_ok\"], \"keywords\": {\"test_ok\": 1, \"pytest-reportlog\": 1, \"test_report_example.py\": 1}, \"outcome\": \"passed\", \"longrepr\": null, \"when\": \"call\", \"user_properties\": [], \"sections\": [], \"duration\": 0.0, \"$report_type\": \"TestReport\"}\n {\"nodeid\": \"test_report_example.py::test_ok\", \"location\": [\"test_report_example.py\", 0, \"test_ok\"], \"keywords\": {\"test_ok\": 1, \"pytest-reportlog\": 1, \"test_report_example.py\": 1}, \"outcome\": \"passed\", \"longrepr\": null, \"when\": \"teardown\", \"user_properties\": [], \"sections\": [], \"duration\": 0.00099945068359375, \"$report_type\": \"TestReport\"}\n {\"nodeid\": \"test_report_example.py::test_fail\", \"location\": [\"test_report_example.py\", 4, \"test_fail\"], \"keywords\": {\"test_fail\": 1, \"pytest-reportlog\": 1, \"test_report_example.py\": 1}, \"outcome\": \"passed\", \"longrepr\": null, \"when\": \"setup\", \"user_properties\": [], \"sections\": [], \"duration\": 0.0, \"$report_type\": \"TestReport\"}\n {\"nodeid\": \"test_report_example.py::test_fail\", \"location\": [\"test_report_example.py\", 4, \"test_fail\"], \"keywords\": {\"test_fail\": 1, \"pytest-reportlog\": 1, \"test_report_example.py\": 1}, \"outcome\": \"failed\", \"longrepr\": {\"reprcrash\": {\"path\": \"D:\\\\projects\\\\pytest-reportlog\\\\test_report_example.py\", \"lineno\": 6, \"message\": \"assert (4 + 4) == 1\"}, \"reprtraceback\": {\"reprentries\": [{\"type\": \"ReprEntry\", \"data\": {\"lines\": [\" def test_fail():\", \"> assert 4 + 4 == 1\", \"E assert (4 + 4) == 1\"], \"reprfuncargs\": {\"args\": []}, \"reprlocals\": null, \"reprfileloc\": {\"path\": \"test_report_example.py\", \"lineno\": 6, \"message\": \"AssertionError\"}, \"style\": \"long\"}}], \"extraline\": null, \"style\": \"long\"}, \"sections\": [], \"chain\": [[{\"reprentries\": [{\"type\": \"ReprEntry\", \"data\": {\"lines\": [\" def test_fail():\", \"> assert 4 + 4 == 1\", \"E assert (4 + 4) == 1\"], \"reprfuncargs\": {\"args\": []}, \"reprlocals\": null, \"reprfileloc\": {\"path\": \"test_report_example.py\", \"lineno\": 6, \"message\": \"AssertionError\"}, \"style\": \"long\"}}], \"extraline\": null, \"style\": \"long\"}, {\"path\": \"D:\\\\projects\\\\pytest-reportlog\\\\test_report_example.py\", \"lineno\": 6, \"message\": \"assert (4 + 4) == 1\"}, null]]}, \"when\": \"call\", \"user_properties\": [], \"sections\": [], \"duration\": 0.0009992122650146484, \"$report_type\": \"TestReport\"}\n {\"nodeid\": \"test_report_example.py::test_fail\", \"location\": [\"test_report_example.py\", 4, \"test_fail\"], \"keywords\": {\"test_fail\": 1, \"pytest-reportlog\": 1, \"test_report_example.py\": 1}, \"outcome\": \"passed\", \"longrepr\": null, \"when\": \"teardown\", \"user_properties\": [], \"sections\": [], \"duration\": 0.0, \"$report_type\": \"TestReport\"}\n {\"exitstatus\": 1, \"$report_type\": \"SessionFinish\"}\n\n\nrecord_property\n---------------\n\nThe ``record_property`` fixture allows to log additional information for a test, just like with JUnitXML format.\nConsider this test file:\n\n.. code-block:: python\n\n def test_function(record_property):\n record_property(\"price\", 12.34)\n record_property(\"fruit\", \"banana\")\n assert True\n\nThis information will be recorded in the report JSON objects under the ``user_properties`` key as follows::\n\n ..., \"user_properties\": [[\"price\", 12.34], [\"fruit\", \"banana\"]], ...\n\nNote that this nested list construct is just the JSON representation\nof a list of tuples (name-value pairs).\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Replacement for the --resultlog option, focused in simplicity and extensibility",
"version": "0.4.0",
"project_urls": {
"Homepage": "https://github.com/pytest-dev/pytest-reportlog"
},
"split_keywords": [
"pytest"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "cf856c7ae08dc1a45f1252591f2824ff7a6a89c57f7ee61e69d5670611eb0bd4",
"md5": "58bf0392f9f26883ab290d5a6a3c21c1",
"sha256": "5db4d00586546d8c6b95c66466629f1e913440c36d97795a673d2e19c5cedd5c"
},
"downloads": -1,
"filename": "pytest_reportlog-0.4.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "58bf0392f9f26883ab290d5a6a3c21c1",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 6443,
"upload_time": "2023-05-22T14:53:33",
"upload_time_iso_8601": "2023-05-22T14:53:33.647748Z",
"url": "https://files.pythonhosted.org/packages/cf/85/6c7ae08dc1a45f1252591f2824ff7a6a89c57f7ee61e69d5670611eb0bd4/pytest_reportlog-0.4.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "daa0d1372b23d415a0766389480633a676fb1530e94ae8f6ea84619cae0ac215",
"md5": "29f720999f61608dc427dd735f96b1b8",
"sha256": "c9f2079504ee51f776d3118dcf5e4730f163d3dcf26ebc8f600c1fa307bf638c"
},
"downloads": -1,
"filename": "pytest-reportlog-0.4.0.tar.gz",
"has_sig": false,
"md5_digest": "29f720999f61608dc427dd735f96b1b8",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 10442,
"upload_time": "2023-05-22T14:53:34",
"upload_time_iso_8601": "2023-05-22T14:53:34.647234Z",
"url": "https://files.pythonhosted.org/packages/da/a0/d1372b23d415a0766389480633a676fb1530e94ae8f6ea84619cae0ac215/pytest-reportlog-0.4.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-05-22 14:53:34",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "pytest-dev",
"github_project": "pytest-reportlog",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "pytest-reportlog"
}