Merge pull request #956 from nicoddemus/record-xml-property

add preliminary support for extended junit xml properties
This commit is contained in:
Ronny Pfannschmidt 2015-08-24 09:13:04 +02:00
commit b25e41e348
6 changed files with 69 additions and 3 deletions

View File

@ -61,3 +61,4 @@ Samuele Pedroni
Tom Viner
Trevor Bekolay
Wouter van Ackooy
David Díaz-Barquero

View File

@ -147,6 +147,9 @@
- fix issue890: changed extension of all documentation files from ``txt`` to
``rst``. Thanks to Abhijeet for the PR.
- issue951: add new record_xml_property fixture, that supports logging
additional information on xml output. Thanks David Diaz for the PR.
2.7.3 (compared to 2.7.2)
-----------------------------

View File

@ -9,6 +9,7 @@ import os
import re
import sys
import time
import pytest
# Python 2.X and 3.X compatibility
if sys.version_info[0] < 3:
@ -53,6 +54,20 @@ def bin_xml_escape(arg):
return unicode('#x%04X') % i
return py.xml.raw(illegal_xml_re.sub(repl, py.xml.escape(arg)))
@pytest.fixture
def record_xml_property(request):
"""Fixture that adds extra xml properties to the tag for the calling test.
The fixture is callable with (name, value), with value being automatically
xml-encoded.
"""
def inner(name, value):
if hasattr(request.config, "_xml"):
request.config._xml.add_custom_property(name, value)
msg = 'record_xml_property is an experimental feature'
request.config.warn(code='C3', message=msg,
fslocation=request.node.location[:2])
return inner
def pytest_addoption(parser):
group = parser.getgroup("terminal reporting")
group.addoption('--junitxml', '--junit-xml', action="store",
@ -75,7 +90,6 @@ def pytest_unconfigure(config):
del config._xml
config.pluginmanager.unregister(xml)
def mangle_testnames(names):
names = [x.replace(".py", "") for x in names if x != '()']
names[0] = names[0].replace("/", '.')
@ -89,6 +103,10 @@ class LogXML(object):
self.tests = []
self.passed = self.skipped = 0
self.failed = self.errors = 0
self.custom_properties = {}
def add_custom_property(self, name, value):
self.custom_properties[str(name)] = bin_xml_escape(str(value))
def _opentestcase(self, report):
names = mangle_testnames(report.nodeid.split("::"))
@ -118,6 +136,10 @@ class LogXML(object):
def append(self, obj):
self.tests[-1].append(obj)
def append_custom_properties(self):
self.tests[-1].attr.__dict__.update(self.custom_properties)
self.custom_properties.clear()
def append_pass(self, report):
self.passed += 1
self._write_captured_output(report)
@ -179,6 +201,7 @@ class LogXML(object):
if report.when == "setup":
self._opentestcase(report)
self.tests[-1].attr.time += getattr(report, 'duration', 0)
self.append_custom_properties()
if report.passed:
if report.when == "call": # ignore setup/teardown
self.append_pass(report)

View File

@ -6,7 +6,7 @@ def get_version_string():
fn = py.path.local(__file__).join("..", "..", "..",
"_pytest", "__init__.py")
for line in fn.readlines():
if "version" in line:
if "version" in line and not line.strip().startswith('#'):
return eval(line.split("=")[-1])
def get_minor_version_string():

View File

@ -153,6 +153,36 @@ integration servers, use this invocation::
to create an XML file at ``path``.
record_xml_property
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. versionadded:: 2.8
If you want to log additional information for a test, you can use the
``record_xml_property`` fixture:
.. code-block:: python
def test_function(record_xml_property):
record_xml_property("example_key", 1)
assert 0
This will add an extra property ``example_key="1"`` to the generated
``testcase`` tag:
.. code-block:: xml
<testcase classname="test_function" example_key="1" file="test_function.py" line="0" name="test_function" time="0.0009">
.. 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, however.
Also please note that using this feature will break any schema verification.
This might be a problem when used with some CI servers.
Creating resultlog format files
----------------------------------------------------

View File

@ -553,4 +553,13 @@ def test_unicode_issue368(testdir):
log.append_skipped(report)
log.pytest_sessionfinish()
def test_record_property(testdir):
testdir.makepyfile("""
def test_record(record_xml_property):
record_xml_property("foo", "<1");
""")
result, dom = runandparse(testdir, '-rw')
node = dom.getElementsByTagName("testsuite")[0]
tnode = node.getElementsByTagName("testcase")[0]
assert_attr(tnode, foo="<1")
result.stdout.fnmatch_lines('*C3*test_record_property.py*experimental*')