diff --git a/src/ifcblenderexport/junit/template.html b/src/ifcblenderexport/junit/template.html
new file mode 100644
index 0000000000..5a4b6ae2f9
--- /dev/null
+++ b/src/ifcblenderexport/junit/template.html
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+ BlenderBIM
+
+
+
+
+
+ IFC QA Report: {{report_name}}
+
+ {{#testcases}}
+
+ {{name}}
+
+ {{#is_success}}Success{{/is_success}}{{^is_success}}Failure{{/is_success}}
+ Tests passed: {{total_passes}} / {{total_steps}}
+
+ Time taken: {{time}} seconds
+
+
+
+ {{#steps}}
+ -
+ {{name}}
+ {{time}}
+
+ {{/steps}}
+
+
+ {{/testcases}}
+
+
+
diff --git a/src/ifcblenderexport/junit2html.py b/src/ifcblenderexport/junit2html.py
new file mode 100644
index 0000000000..4f7d2f2d95
--- /dev/null
+++ b/src/ifcblenderexport/junit2html.py
@@ -0,0 +1,30 @@
+import xml.etree.ElementTree as ET
+import pystache
+
+with open('junit/template.html') as template:
+ root = ET.parse('junit/TESTS-example.xml').getroot()
+ data = {
+ 'report_name': root.get('name'),
+ 'testcases': []
+ }
+ for testcase in root.findall('testcase'):
+ steps = []
+ system_out = testcase.findall('system-out')[0].text.splitlines()
+ for line in system_out:
+ if line.strip()[0:5] in ['Given', 'Then ', 'When ']:
+ is_success = True if ' ... passed in ' in line else False
+ steps.append({
+ 'name': line.strip().split(' ... ')[0],
+ 'time': line.strip().split(' ... ')[1],
+ 'is_success': is_success
+ })
+ data['testcases'].append({
+ 'name': testcase.get('name'),
+ 'is_success': testcase.get('status') == 'passed',
+ 'time': testcase.get('time'),
+ 'steps': steps,
+ 'total_passes': len([s for s in steps if s['is_success'] == True]),
+ 'total_steps': len(steps)
+ })
+ with open('junit/results.html', 'w') as out:
+ out.write(pystache.render(template.read(), data))