Introduce --report-log #5980
Conversation
RonnyPfannschmidt
left a comment
There was a problem hiding this comment.
Overall good start, and believe it is already better than resultlog
Cool. Any comments about points 1, 2, and 3 that I posted? |
|
Another point that occurred to me:
|
|
wrt reporttype public/nonpublic - we we should use wrt creating folders - i believe we shouldn't create them, as that may hide user errors (imagine a typo in the path and the reports end in nirvana instead of a report folder wrt multiple log paths, i'd rather see a report stream hook that for the report log plug-in serializes, and ides would either use serialize as well, or directly use the richer objects wrt more events, happily as follow-up and as pytest serialize/de-serialize supports them we should have a header telling the pytest version and supported serialization types |
|
Hi @RonnyPfannschmidt, thanks for the feedback!
Hmm why
I disagree; the same reasoning could be made by the user mistyping the filename ( If the report ends up in a different place, the user will notice and correct it, facts of life. 😁
I see, but I was thinking more along the lines of system where they couldn't write hooks (say implemented in a language other than Python). Otherwise, they could just implement hooks directly and capture the events there.
Sure. 👍
Something like: {"pytest-version": "5.3.0", "serialized-types": ["Header", "CollectReport", "TestReport"], "report_type": "Header"}? |
the type is not part of the serialized objects normal namespace, the $ simply prevents of ever having to account for a name conflict on that level
i still disagree, but i can make do with this setup
making a small local plug-in the environment invokes is trivial and done by many systems not implemented in python already, what would be interesting is having the log report as stdout stream instead of the normal io then pytest could be invoked by the system and just report details directly
exactly
|
|
btw, i can imagine something like pytest-dbus, where pytest would report events to dbus -> or an api |
d1129cf to
d8cbc62
Compare
|
This should be now ready for final review. |
d8cbc62 to
46e7b0f
Compare
doc/en/usage.rst
Outdated
|
|
||
| .. warning:: | ||
|
|
||
| This option is rarely used and is scheduled for removal in 5.0. |
|
Thanks @RonnyPfannschmidt I think it is a good idea to add a "finish" entry as well including the exit code: {"$report_type": "SessionFinish", "exitstatus": 0}Besides including the exit status, it also allows systems to determine that pytest has finished cleanly. What do you think @RonnyPfannschmidt? If this is to be added, I think we should rename "Header" to "SessionStart" for consistency too. |
|
i like it |
e2a7012 to
e98bf32
Compare
e98bf32 to
09096f7
Compare
EDIT:
This should now be ready for final review.
OLD:
Started working on this, before progressing further I want to gather opinions if the direction is right.
Given this simple test file:
Here is the file produced:
{"nodeid": "", "outcome": "passed", "longrepr": null, "result": null, "sections": [], "_report_type": "CollectReport"} {"nodeid": "test_foo.py", "outcome": "passed", "longrepr": null, "result": null, "sections": [], "_report_type": "CollectReport"} {"nodeid": "test_foo.py::test_ok", "location": ["test_foo.py", 0, "test_ok"], "keywords": {"test_ok": 1, "test_foo.py": 1, ".tmp": 1}, "outcome": "passed", "longrepr": null, "when": "setup", "user_properties": [], "sections": [], "duration": 0.000990152359008789, "_report_type": "TestReport"} {"nodeid": "test_foo.py::test_ok", "location": ["test_foo.py", 0, "test_ok"], "keywords": {"test_ok": 1, "test_foo.py": 1, ".tmp": 1}, "outcome": "passed", "longrepr": null, "when": "call", "user_properties": [], "sections": [], "duration": 0.0, "_report_type": "TestReport"} {"nodeid": "test_foo.py::test_ok", "location": ["test_foo.py", 0, "test_ok"], "keywords": {"test_ok": 1, "test_foo.py": 1, ".tmp": 1}, "outcome": "passed", "longrepr": null, "when": "teardown", "user_properties": [], "sections": [], "duration": 0.0010075569152832031, "_report_type": "TestReport"} {"nodeid": "test_foo.py::test_failure", "location": ["test_foo.py", 8, "test_failure"], "keywords": {"test_foo.py": 1, "test_failure": 1, ".tmp": 1}, "outcome": "passed", "longrepr": null, "when": "setup", "user_properties": [], "sections": [], "duration": 0.0, "_report_type": "TestReport"} {"nodeid": "test_foo.py::test_failure", "location": ["test_foo.py", 8, "test_failure"], "keywords": {"test_foo.py": 1, "test_failure": 1, ".tmp": 1}, "outcome": "failed", "longrepr": {"reprcrash": {"path": "D:\\projects\\pytest\\.tmp\\test_foo.py", "lineno": 6, "message": "assert 0"}, "reprtraceback": {"reprentries": [{"type": "ReprEntry", "data": {"lines": [" def test_failure():", "> fail()"], "reprfuncargs": {"args": []}, "reprlocals": null, "reprfileloc": {"path": "test_foo.py", "lineno": 10, "message": ""}, "style": "long"}}, {"type": "ReprEntry", "data": {"lines": [" def fail():", "> assert 0", "E assert 0"], "reprfuncargs": {"args": []}, "reprlocals": null, "reprfileloc": {"path": "test_foo.py", "lineno": 6, "message": "AssertionError"}, "style": "long"}}], "extraline": null, "style": "long"}, "sections": [], "chain": [[{"reprentries": [{"type": "ReprEntry", "data": {"lines": [" def test_failure():", "> fail()"], "reprfuncargs": {"args": []}, "reprlocals": null, "reprfileloc": {"path": "test_foo.py", "lineno": 10, "message": ""}, "style": "long"}}, {"type": "ReprEntry", "data": {"lines": [" def fail():", "> assert 0", "E assert 0"], "reprfuncargs": {"args": []}, "reprlocals": null, "reprfileloc": {"path": "test_foo.py", "lineno": 6, "message": "AssertionError"}, "style": "long"}}], "extraline": null, "style": "long"}, {"path": "D:\\projects\\pytest\\.tmp\\test_foo.py", "lineno": 6, "message": "assert 0"}, null]]}, "when": "call", "user_properties": [], "sections": [], "duration": 0.0009996891021728516, "_report_type": "TestReport"} {"nodeid": "test_foo.py::test_failure", "location": ["test_foo.py", 8, "test_failure"], "keywords": {"test_foo.py": 1, "test_failure": 1, ".tmp": 1}, "outcome": "passed", "longrepr": null, "when": "teardown", "user_properties": [], "sections": [], "duration": 0.0, "_report_type": "TestReport"}Some things I believe can be improved:
"_report_type"is currently private, I think it should be promoted to public as"report_type".We could add more events:
It might make sense to accept multiple log paths, so tools could consume the log while allowing users to use
--report-logthemselves. For example, an IDE might want to use--report-logto update its UI, passing a file it owns to--report-log, without affecting users that might also be using--report-log.