Renamed the fixture record_xml_property to record_property and adapted logic so that the properties are passed to the TestReport object and thus allow compatibility with pytest-xdist.
This commit is contained in:
parent
97bb6abcfa
commit
8b49ddfa58
1
AUTHORS
1
AUTHORS
|
@ -35,6 +35,7 @@ Brianna Laugher
|
|||
Bruno Oliveira
|
||||
Cal Leeming
|
||||
Carl Friedrich Bolz
|
||||
Carlos Jenkins
|
||||
Ceridwen
|
||||
Charles Cloud
|
||||
Charnjit SiNGH (CCSJ)
|
||||
|
|
|
@ -41,6 +41,12 @@ MARK_PARAMETERSET_UNPACKING = RemovedInPytest4Warning(
|
|||
"For more details, see: https://docs.pytest.org/en/latest/parametrize.html"
|
||||
)
|
||||
|
||||
RECORD_XML_PROPERTY = (
|
||||
'Fixture renamed from "record_xml_property" to "record_property" as user '
|
||||
'properties are now available to all reporters.\n'
|
||||
'"record_xml_property" is now deprecated.'
|
||||
)
|
||||
|
||||
COLLECTOR_MAKEITEM = RemovedInPytest4Warning(
|
||||
"pycollector makeitem was removed "
|
||||
"as it is an accidentially leaked internal api"
|
||||
|
|
|
@ -233,31 +233,41 @@ class _NodeReporter(object):
|
|||
|
||||
|
||||
@pytest.fixture
|
||||
def record_xml_property(request):
|
||||
"""Add extra xml properties to the tag for the calling test.
|
||||
The fixture is callable with ``(name, value)``, with value being automatically
|
||||
xml-encoded.
|
||||
def record_property(request):
|
||||
"""Add an extra properties the calling test.
|
||||
User properties become part of the test report and are available to the
|
||||
configured reporters, like JUnit XML.
|
||||
The fixture is callable with ``(name, value)``.
|
||||
"""
|
||||
request.node.warn(
|
||||
code='C3',
|
||||
message='record_xml_property is an experimental feature',
|
||||
message='record_property is an experimental feature',
|
||||
)
|
||||
xml = getattr(request.config, "_xml", None)
|
||||
if xml is not None:
|
||||
node_reporter = xml.node_reporter(request.node.nodeid)
|
||||
return node_reporter.add_property
|
||||
else:
|
||||
def add_property_noop(name, value):
|
||||
pass
|
||||
|
||||
return add_property_noop
|
||||
def append_property(name, value):
|
||||
request.node.user_properties.append((name, value))
|
||||
return append_property
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def record_xml_property(request):
|
||||
"""(Deprecated) use record_property."""
|
||||
import warnings
|
||||
from _pytest import deprecated
|
||||
warnings.warn(
|
||||
deprecated.RECORD_XML_PROPERTY,
|
||||
DeprecationWarning,
|
||||
stacklevel=2
|
||||
)
|
||||
|
||||
return record_property(request)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def record_xml_attribute(request):
|
||||
"""Add extra xml attributes to the tag for the calling test.
|
||||
The fixture is callable with ``(name, value)``, with value being automatically
|
||||
xml-encoded
|
||||
The fixture is callable with ``(name, value)``, with value being
|
||||
automatically xml-encoded
|
||||
"""
|
||||
request.node.warn(
|
||||
code='C3',
|
||||
|
@ -442,6 +452,10 @@ class LogXML(object):
|
|||
if report.when == "teardown":
|
||||
reporter = self._opentestcase(report)
|
||||
reporter.write_captured_output(report)
|
||||
|
||||
for propname, propvalue in report.user_properties:
|
||||
reporter.add_property(propname, propvalue)
|
||||
|
||||
self.finalize(report)
|
||||
report_wid = getattr(report, "worker_id", None)
|
||||
report_ii = getattr(report, "item_index", None)
|
||||
|
|
|
@ -360,6 +360,10 @@ class Item(Node):
|
|||
super(Item, self).__init__(name, parent, config, session)
|
||||
self._report_sections = []
|
||||
|
||||
#: user properties is a list of tuples (name, value) that holds user
|
||||
#: defined properties for this test.
|
||||
self.user_properties = []
|
||||
|
||||
def add_report_section(self, when, key, content):
|
||||
"""
|
||||
Adds a new report section, similar to what's done internally to add stdout and
|
||||
|
|
|
@ -317,6 +317,7 @@ def pytest_runtest_makereport(item, call):
|
|||
sections.append(("Captured %s %s" % (key, rwhen), content))
|
||||
return TestReport(item.nodeid, item.location,
|
||||
keywords, outcome, longrepr, when,
|
||||
item.user_properties,
|
||||
sections, duration)
|
||||
|
||||
|
||||
|
@ -326,7 +327,8 @@ class TestReport(BaseReport):
|
|||
"""
|
||||
|
||||
def __init__(self, nodeid, location, keywords, outcome,
|
||||
longrepr, when, sections=(), duration=0, **extra):
|
||||
longrepr, when, user_properties,
|
||||
sections=(), duration=0, **extra):
|
||||
#: normalized collection node id
|
||||
self.nodeid = nodeid
|
||||
|
||||
|
@ -348,6 +350,10 @@ class TestReport(BaseReport):
|
|||
#: one of 'setup', 'call', 'teardown' to indicate runtest phase.
|
||||
self.when = when
|
||||
|
||||
#: user properties is a list of tuples (name, value) that holds user
|
||||
#: defined properties of the test
|
||||
self.user_properties = user_properties
|
||||
|
||||
#: list of pairs ``(str, str)`` of extra information which needs to
|
||||
#: marshallable. Used by pytest to add captured text
|
||||
#: from ``stdout`` and ``stderr``, but may be used by other plugins
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
``record_xml_property`` renamed to ``record_property`` and is now compatible with xdist, markers and any reporter.
|
||||
``record_xml_property`` name is now deprecated.
|
|
@ -112,10 +112,11 @@ You can ask for available builtin or project-custom
|
|||
Inject names into the doctest namespace.
|
||||
pytestconfig
|
||||
the pytest config object with access to command line opts.
|
||||
record_xml_property
|
||||
Add extra xml properties to the tag for the calling test.
|
||||
The fixture is callable with ``(name, value)``, with value being automatically
|
||||
xml-encoded.
|
||||
record_property
|
||||
Add an extra properties the calling test.
|
||||
User properties become part of the test report and are available to the
|
||||
configured reporters, like JUnit XML.
|
||||
The fixture is callable with ``(name, value)``.
|
||||
record_xml_attribute
|
||||
Add extra xml attributes to the tag for the calling test.
|
||||
The fixture is callable with ``(name, value)``, with value being automatically
|
||||
|
|
|
@ -537,7 +537,7 @@ We can run this::
|
|||
file $REGENDOC_TMPDIR/b/test_error.py, line 1
|
||||
def test_root(db): # no db here, will error out
|
||||
E fixture 'db' not found
|
||||
> available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_xml_attribute, record_xml_property, recwarn, tmpdir, tmpdir_factory
|
||||
> available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_xml_attribute, record_property, recwarn, tmpdir, tmpdir_factory
|
||||
> use 'pytest --fixtures [testpath]' for help on them.
|
||||
|
||||
$REGENDOC_TMPDIR/b/test_error.py:1
|
||||
|
|
|
@ -220,19 +220,24 @@ To set the name of the root test suite xml item, you can configure the ``junit_s
|
|||
[pytest]
|
||||
junit_suite_name = my_suite
|
||||
|
||||
record_xml_property
|
||||
record_property
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. versionadded:: 2.8
|
||||
.. versionchanged:: 3.5
|
||||
|
||||
Fixture renamed from ``record_xml_property`` to ``record_property`` as user
|
||||
properties are now available to all reporters.
|
||||
``record_xml_property`` is now deprecated.
|
||||
|
||||
If you want to log additional information for a test, you can use the
|
||||
``record_xml_property`` fixture:
|
||||
``record_property`` fixture:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def test_function(record_xml_property):
|
||||
record_xml_property("example_key", 1)
|
||||
assert 0
|
||||
def test_function(record_property):
|
||||
record_property("example_key", 1)
|
||||
assert True
|
||||
|
||||
This will add an extra property ``example_key="1"`` to the generated
|
||||
``testcase`` tag:
|
||||
|
@ -245,13 +250,42 @@ This will add an extra property ``example_key="1"`` to the generated
|
|||
</properties>
|
||||
</testcase>
|
||||
|
||||
Alternatively, you can integrate this functionality with custom markers:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# content of conftest.py
|
||||
|
||||
def pytest_collection_modifyitems(session, config, items):
|
||||
for item in items:
|
||||
marker = item.get_marker('test_id')
|
||||
if marker is not None:
|
||||
test_id = marker.args[0]
|
||||
item.user_properties.append(('test_id', test_id))
|
||||
|
||||
And in your tests:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# content of test_function.py
|
||||
|
||||
@pytest.mark.test_id(1501)
|
||||
def test_function():
|
||||
assert True
|
||||
|
||||
Will result in:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<testcase classname="test_function" file="test_function.py" line="0" name="test_function" time="0.0009">
|
||||
<properties>
|
||||
<property name="test_id" value="1501" />
|
||||
</properties>
|
||||
</testcase>
|
||||
|
||||
.. warning::
|
||||
|
||||
``record_xml_property`` is an experimental feature, and its interface might be replaced
|
||||
by something more powerful and general in future versions. The
|
||||
functionality per-se will be kept, however.
|
||||
|
||||
Currently it does not work when used with the ``pytest-xdist`` plugin.
|
||||
``record_property`` is an experimental feature and may change in the future.
|
||||
|
||||
Also please note that using this feature will break any schema verification.
|
||||
This might be a problem when used with some CI servers.
|
||||
|
|
|
@ -863,10 +863,10 @@ def test_record_property(testdir):
|
|||
import pytest
|
||||
|
||||
@pytest.fixture
|
||||
def other(record_xml_property):
|
||||
record_xml_property("bar", 1)
|
||||
def test_record(record_xml_property, other):
|
||||
record_xml_property("foo", "<1");
|
||||
def other(record_property):
|
||||
record_property("bar", 1)
|
||||
def test_record(record_property, other):
|
||||
record_property("foo", "<1");
|
||||
""")
|
||||
result, dom = runandparse(testdir, '-rw')
|
||||
node = dom.find_first_by_tag("testsuite")
|
||||
|
@ -877,15 +877,15 @@ def test_record_property(testdir):
|
|||
pnodes[1].assert_attr(name="foo", value="<1")
|
||||
result.stdout.fnmatch_lines([
|
||||
'test_record_property.py::test_record',
|
||||
'*record_xml_property*experimental*',
|
||||
'*record_property*experimental*',
|
||||
])
|
||||
|
||||
|
||||
def test_record_property_same_name(testdir):
|
||||
testdir.makepyfile("""
|
||||
def test_record_with_same_name(record_xml_property):
|
||||
record_xml_property("foo", "bar")
|
||||
record_xml_property("foo", "baz")
|
||||
def test_record_with_same_name(record_property):
|
||||
record_property("foo", "bar")
|
||||
record_property("foo", "baz")
|
||||
""")
|
||||
result, dom = runandparse(testdir, '-rw')
|
||||
node = dom.find_first_by_tag("testsuite")
|
||||
|
|
Loading…
Reference in New Issue