Merge pull request #1454 from tareqalayan/add-global-properties-node
junitxml: add properties node in testsuite level
This commit is contained in:
commit
ceacc12b52
1
AUTHORS
1
AUTHORS
|
@ -75,6 +75,7 @@ Ronny Pfannschmidt
|
||||||
Ross Lawley
|
Ross Lawley
|
||||||
Ryan Wooden
|
Ryan Wooden
|
||||||
Samuele Pedroni
|
Samuele Pedroni
|
||||||
|
Tareq Alayan
|
||||||
Tom Viner
|
Tom Viner
|
||||||
Trevor Bekolay
|
Trevor Bekolay
|
||||||
Wouter van Ackooy
|
Wouter van Ackooy
|
||||||
|
|
|
@ -15,6 +15,10 @@
|
||||||
tests.
|
tests.
|
||||||
Thanks `@kalekundert`_ for the complete PR (`#1441`_).
|
Thanks `@kalekundert`_ for the complete PR (`#1441`_).
|
||||||
|
|
||||||
|
* New Add ability to add global properties in the final xunit output file.
|
||||||
|
Thanks `@tareqalayan`_ for the complete PR `#1454`_).
|
||||||
|
|
||||||
|
|
||||||
*
|
*
|
||||||
|
|
||||||
**Changes**
|
**Changes**
|
||||||
|
@ -28,10 +32,13 @@
|
||||||
.. _@milliams: https://github.com/milliams
|
.. _@milliams: https://github.com/milliams
|
||||||
.. _@novas0x2a: https://github.com/novas0x2a
|
.. _@novas0x2a: https://github.com/novas0x2a
|
||||||
.. _@kalekundert: https://github.com/kalekundert
|
.. _@kalekundert: https://github.com/kalekundert
|
||||||
|
.. _@tareqalayan: https://github.com/tareqalayan
|
||||||
|
|
||||||
.. _#1428: https://github.com/pytest-dev/pytest/pull/1428
|
.. _#1428: https://github.com/pytest-dev/pytest/pull/1428
|
||||||
.. _#1444: https://github.com/pytest-dev/pytest/pull/1444
|
.. _#1444: https://github.com/pytest-dev/pytest/pull/1444
|
||||||
.. _#1441: https://github.com/pytest-dev/pytest/pull/1441
|
.. _#1441: https://github.com/pytest-dev/pytest/pull/1441
|
||||||
|
.. _#1454: https://github.com/pytest-dev/pytest/pull/1454
|
||||||
|
|
||||||
|
|
||||||
2.9.1.dev1
|
2.9.1.dev1
|
||||||
==========
|
==========
|
||||||
|
|
|
@ -254,6 +254,7 @@ class LogXML(object):
|
||||||
], 0)
|
], 0)
|
||||||
self.node_reporters = {} # nodeid -> _NodeReporter
|
self.node_reporters = {} # nodeid -> _NodeReporter
|
||||||
self.node_reporters_ordered = []
|
self.node_reporters_ordered = []
|
||||||
|
self.global_properties = []
|
||||||
|
|
||||||
def finalize(self, report):
|
def finalize(self, report):
|
||||||
nodeid = getattr(report, 'nodeid', report)
|
nodeid = getattr(report, 'nodeid', report)
|
||||||
|
@ -273,9 +274,12 @@ class LogXML(object):
|
||||||
if key in self.node_reporters:
|
if key in self.node_reporters:
|
||||||
# TODO: breasks for --dist=each
|
# TODO: breasks for --dist=each
|
||||||
return self.node_reporters[key]
|
return self.node_reporters[key]
|
||||||
|
|
||||||
reporter = _NodeReporter(nodeid, self)
|
reporter = _NodeReporter(nodeid, self)
|
||||||
|
|
||||||
self.node_reporters[key] = reporter
|
self.node_reporters[key] = reporter
|
||||||
self.node_reporters_ordered.append(reporter)
|
self.node_reporters_ordered.append(reporter)
|
||||||
|
|
||||||
return reporter
|
return reporter
|
||||||
|
|
||||||
def add_stats(self, key):
|
def add_stats(self, key):
|
||||||
|
@ -361,7 +365,9 @@ class LogXML(object):
|
||||||
numtests = self.stats['passed'] + self.stats['failure']
|
numtests = self.stats['passed'] + self.stats['failure']
|
||||||
|
|
||||||
logfile.write('<?xml version="1.0" encoding="utf-8"?>')
|
logfile.write('<?xml version="1.0" encoding="utf-8"?>')
|
||||||
|
|
||||||
logfile.write(Junit.testsuite(
|
logfile.write(Junit.testsuite(
|
||||||
|
self._get_global_properties_node(),
|
||||||
[x.to_xml() for x in self.node_reporters_ordered],
|
[x.to_xml() for x in self.node_reporters_ordered],
|
||||||
name="pytest",
|
name="pytest",
|
||||||
errors=self.stats['error'],
|
errors=self.stats['error'],
|
||||||
|
@ -374,3 +380,18 @@ class LogXML(object):
|
||||||
def pytest_terminal_summary(self, terminalreporter):
|
def pytest_terminal_summary(self, terminalreporter):
|
||||||
terminalreporter.write_sep("-",
|
terminalreporter.write_sep("-",
|
||||||
"generated xml file: %s" % (self.logfile))
|
"generated xml file: %s" % (self.logfile))
|
||||||
|
|
||||||
|
def add_global_property(self, name, value):
|
||||||
|
self.global_properties.append((str(name), bin_xml_escape(value)))
|
||||||
|
|
||||||
|
def _get_global_properties_node(self):
|
||||||
|
"""Return a Junit node containing custom properties, if any.
|
||||||
|
"""
|
||||||
|
if self.global_properties:
|
||||||
|
return Junit.properties(
|
||||||
|
[
|
||||||
|
Junit.property(name=name, value=value)
|
||||||
|
for name, value in self.global_properties
|
||||||
|
]
|
||||||
|
)
|
||||||
|
return ''
|
||||||
|
|
|
@ -193,6 +193,53 @@ This will add an extra property ``example_key="1"`` to the generated
|
||||||
Also please note that using this feature will break any schema verification.
|
Also please note that using this feature will break any schema verification.
|
||||||
This might be a problem when used with some CI servers.
|
This might be a problem when used with some CI servers.
|
||||||
|
|
||||||
|
LogXML: add_global_property
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. versionadded:: 2.10
|
||||||
|
|
||||||
|
If you want to add a properties node in the testsuite level, which may contains properties that are relevant
|
||||||
|
to all testcases you can use ``LogXML.add_global_properties``
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def log_global_env_facts(f):
|
||||||
|
|
||||||
|
if pytest.config.pluginmanager.hasplugin('junitxml'):
|
||||||
|
my_junit = getattr(pytest.config, '_xml', None)
|
||||||
|
|
||||||
|
my_junit.add_global_property('ARCH', 'PPC')
|
||||||
|
my_junit.add_global_property('STORAGE_TYPE', 'CEPH')
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures(log_global_env_facts)
|
||||||
|
def start_and_prepare_env():
|
||||||
|
pass
|
||||||
|
|
||||||
|
class TestMe:
|
||||||
|
def test_foo(self):
|
||||||
|
assert True
|
||||||
|
|
||||||
|
This will add a property node below the testsuite node to the generated xml:
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<testsuite errors="0" failures="0" name="pytest" skips="0" tests="1" time="0.006">
|
||||||
|
<properties>
|
||||||
|
<property name="ARCH" value="PPC"/>
|
||||||
|
<property name="STORAGE_TYPE" value="CEPH"/>
|
||||||
|
</properties>
|
||||||
|
<testcase classname="test_me.TestMe" file="test_me.py" line="16" name="test_foo" time="0.000243663787842"/>
|
||||||
|
</testsuite>
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
This 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.
|
||||||
|
|
||||||
Creating resultlog format files
|
Creating resultlog format files
|
||||||
----------------------------------------------------
|
----------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -783,3 +783,38 @@ def test_fancy_items_regression(testdir):
|
||||||
u'test_fancy_items_regression test_pass'
|
u'test_fancy_items_regression test_pass'
|
||||||
u' test_fancy_items_regression.py',
|
u' test_fancy_items_regression.py',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def test_global_properties(testdir):
|
||||||
|
path = testdir.tmpdir.join("test_global_properties.xml")
|
||||||
|
log = LogXML(str(path), None)
|
||||||
|
from _pytest.runner import BaseReport
|
||||||
|
|
||||||
|
class Report(BaseReport):
|
||||||
|
sections = []
|
||||||
|
nodeid = "test_node_id"
|
||||||
|
|
||||||
|
log.pytest_sessionstart()
|
||||||
|
log.add_global_property('foo', 1)
|
||||||
|
log.add_global_property('bar', 2)
|
||||||
|
log.pytest_sessionfinish()
|
||||||
|
|
||||||
|
dom = minidom.parse(str(path))
|
||||||
|
|
||||||
|
properties = dom.getElementsByTagName('properties')
|
||||||
|
|
||||||
|
assert (properties.length == 1), "There must be one <properties> node"
|
||||||
|
|
||||||
|
property_list = dom.getElementsByTagName('property')
|
||||||
|
|
||||||
|
assert (property_list.length == 2), "There most be only 2 property nodes"
|
||||||
|
|
||||||
|
expected = {'foo': '1', 'bar': '2'}
|
||||||
|
actual = {}
|
||||||
|
|
||||||
|
for p in property_list:
|
||||||
|
k = str(p.getAttribute('name'))
|
||||||
|
v = str(p.getAttribute('value'))
|
||||||
|
actual[k] = v
|
||||||
|
|
||||||
|
assert actual == expected
|
||||||
|
|
Loading…
Reference in New Issue