I would like to add properties to the xUnit file that is output when using the -x flag. This would be analogous to the record_property and record_testsuite_property Fixtures in Pytest.
We would then be able to nestle properties underneath the testsuite and any individual testcase:
I had a look over that issue request you linked and saw your? comments.
I hadn’t replied to this earlier because honestly I don’t know much about xunit, so I was hoping someone more knowledgable would reply, and no point me cluttering up the thread.
It seems the feature you want is not there (by the request to add it), that issue is only 22 days old, so there is a good chance none of the RF maintainers have had a chance to look at it, it is an open source project after all so you could add the feature if you have the ability and issue a pull request.
If you don’t feel you have the ability to update the RF code, or you need a solution quickly, rather than post processing the output.xml file as discussed in that issue, another option would be to create a listener file that could generate your xunit xml for you. The Listener interface functions end_suite and end_test probably have everything you need and so you probably only need to write a listener function for each of those, and maybe one for start_suite that simply creates your xunit xml file with an initial blank template.
I appreciate the response. I had forgotten about the listener interface. That does seem like it could be a good approach to generating xunit files with custom properties. I will post this suggestion in the GitHub issue.
I have written a prerebotmodifier before. I think that I understand the basics. Actually, the listener interface makes things even easier by providing the xunit_file method, which runs when an xunit file is ready. I experimented and found that this method is called after the xunit file has already been written. This framework should provide a pathway for anybody wanting to postprocess an xunit file. I plan to somehow save the data that I need via end_test to a class field then use it in xunit_file.
This is a really old thread, but I found it today when searching for a way to add custom properties in the XUnit file to link tests to test cases in Azure. I thought I’d post my solution in case anyone else is having the same issue.
In our specific case we wanted to add the following to the xml:
Where the value is the work item/test case ID in Azure. Each test case has a link to this test case in its documentation:
209 Redundant steering angle
[Documentation] SwRS #209, Verify that the correct bits are set
... https://dev.azure.com/<organization>/<project>/_workitems/edit/304190
[Tags] test:retry(2) sae rae tested
keywords...
I created the following listener that extracts the id from the URL in the test case documentation and adds the property in each test cast in the XUnit file:
"""
This is a listener that adds the test case ID (in Azure) as a property to all test cases in the XUnit output file.
"""
import re
from lxml import etree
class AddTestSpecId:
ROBOT_LIBRARY_SCOPE = “GLOBAL”
ROBOT_LISTENER_API_VERSION = 3
def __init__(self):
self.spec_ids = {}
def end_test(self, test, _):
"""
Extracts the test case ID from the link in the documentation.
"""
spec_id = re.search(
r"https://dev.azure.com/<organisation>/<project>/_workitems/edit/(\d+)",
test.doc,
re.MULTILINE,
)
if spec_id:
self.spec_ids[test.name] = spec_id.group(1)
else:
print(f"No spec ID found in documentation for test {test.name}")
def xunit_file(self, path):
"""
Adds a property to each test case in the XUnit file with name 'test_spec_id' and value
set to the test case ID.
"""
content = etree.parse(path)
test_cases = content.findall(".//testcase")
for test_case in test_cases:
test_name = test_case.get("name")
if test_name in self.spec_ids:
spec_id = self.spec_ids[test_name]
properties = test_case.find("properties")
if properties is None:
properties = etree.SubElement(test_case, "properties")
etree.SubElement(
properties, "property", name="test_spec_id", value=spec_id
)
content.write(path, xml_declaration=True, encoding="utf-8")