Improve junit xml generated fields
* trial ('testsuites' node): Add fields 'tests', 'errors', 'failures', 'time'. * testsuite: Add fields 'errors', 'failures', 'skipped', 'disabled' * test: Add field 'classname' (empty). Fix and improve suite.py and test.py to count errors, skipped, failures properly. Change-Id: Ie2d10cee88a9c0d829e4620553164cf3150e8e5c
This commit is contained in:
parent
a5f7bef0a2
commit
02e8a8d4e1
|
@ -17,6 +17,8 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# junit xml format: https://llg.cubic.org/docs/junit/
|
||||||
|
|
||||||
import math
|
import math
|
||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
|
@ -50,9 +52,24 @@ def trial_to_junit_write(trial, junit_path):
|
||||||
|
|
||||||
def trial_to_junit(trial):
|
def trial_to_junit(trial):
|
||||||
testsuites = et.Element('testsuites')
|
testsuites = et.Element('testsuites')
|
||||||
|
num_tests = 0
|
||||||
|
num_failures = 0
|
||||||
|
num_errors = 0
|
||||||
|
time = 0
|
||||||
|
id = 0
|
||||||
for suite in trial.suites:
|
for suite in trial.suites:
|
||||||
testsuite = suite_to_junit(suite)
|
testsuite = suite_to_junit(suite)
|
||||||
|
testsuite.set('id', str(id))
|
||||||
|
id += 1
|
||||||
testsuites.append(testsuite)
|
testsuites.append(testsuite)
|
||||||
|
num_tests += int(testsuite.get('tests'))
|
||||||
|
num_failures += int(testsuite.get('failures'))
|
||||||
|
num_errors += int(testsuite.get('errors'))
|
||||||
|
time += suite.duration
|
||||||
|
testsuites.set('tests', str(num_tests))
|
||||||
|
testsuites.set('errors', str(num_errors))
|
||||||
|
testsuites.set('failures', str(num_failures))
|
||||||
|
testsuites.set('time', str(math.ceil(time)))
|
||||||
return testsuites
|
return testsuites
|
||||||
|
|
||||||
def suite_to_junit(suite):
|
def suite_to_junit(suite):
|
||||||
|
@ -63,9 +80,14 @@ def suite_to_junit(suite):
|
||||||
testsuite.set('timestamp', datetime.fromtimestamp(round(suite.start_timestamp)).isoformat())
|
testsuite.set('timestamp', datetime.fromtimestamp(round(suite.start_timestamp)).isoformat())
|
||||||
testsuite.set('time', str(math.ceil(suite.duration)))
|
testsuite.set('time', str(math.ceil(suite.duration)))
|
||||||
testsuite.set('tests', str(len(suite.tests)))
|
testsuite.set('tests', str(len(suite.tests)))
|
||||||
testsuite.set('failures', str(suite.count_test_results()[2]))
|
passed, skipped, failed, errors = suite.count_test_results()
|
||||||
|
testsuite.set('errors', str(errors))
|
||||||
|
testsuite.set('failures', str(failed))
|
||||||
|
testsuite.set('skipped', str(skipped))
|
||||||
|
testsuite.set('disabled', str(skipped))
|
||||||
for suite_test in suite.tests:
|
for suite_test in suite.tests:
|
||||||
testcase = test_to_junit(suite_test)
|
testcase = test_to_junit(suite_test)
|
||||||
|
testcase.set('classname', suite.name())
|
||||||
testsuite.append(testcase)
|
testsuite.append(testcase)
|
||||||
return testsuite
|
return testsuite
|
||||||
|
|
||||||
|
@ -113,10 +135,12 @@ def suite_to_text(suite):
|
||||||
if not suite.tests:
|
if not suite.tests:
|
||||||
return 'no tests were run.'
|
return 'no tests were run.'
|
||||||
|
|
||||||
passed, skipped, failed = suite.count_test_results()
|
passed, skipped, failed, errors = suite.count_test_results()
|
||||||
details = []
|
details = []
|
||||||
if failed:
|
if failed:
|
||||||
details.append('fail: %d' % failed)
|
details.append('fail: %d' % failed)
|
||||||
|
if errors:
|
||||||
|
details.append('errors: %d' % errors)
|
||||||
if passed:
|
if passed:
|
||||||
details.append('pass: %d' % passed)
|
details.append('pass: %d' % passed)
|
||||||
if skipped:
|
if skipped:
|
||||||
|
|
|
@ -213,9 +213,9 @@ class SuiteRun(log.Origin):
|
||||||
util.import_path_remove(suite_libdir)
|
util.import_path_remove(suite_libdir)
|
||||||
self.duration = time.time() - self.start_timestamp
|
self.duration = time.time() - self.start_timestamp
|
||||||
|
|
||||||
passed, skipped, failed = self.count_test_results()
|
passed, skipped, failed, errors = self.count_test_results()
|
||||||
# if no tests ran, count it as failure
|
# if no tests ran, count it as failure
|
||||||
if passed and not failed:
|
if passed and not failed and not errors:
|
||||||
self.status = SuiteRun.PASS
|
self.status = SuiteRun.PASS
|
||||||
else:
|
else:
|
||||||
self.status = SuiteRun.FAIL
|
self.status = SuiteRun.FAIL
|
||||||
|
@ -229,14 +229,17 @@ class SuiteRun(log.Origin):
|
||||||
passed = 0
|
passed = 0
|
||||||
skipped = 0
|
skipped = 0
|
||||||
failed = 0
|
failed = 0
|
||||||
|
errors = 0
|
||||||
for t in self.tests:
|
for t in self.tests:
|
||||||
if t.status == test.Test.PASS:
|
if t.status == test.Test.SKIP:
|
||||||
|
skipped += 1
|
||||||
|
elif t.status == test.Test.PASS:
|
||||||
passed += 1
|
passed += 1
|
||||||
elif t.status == test.Test.FAIL:
|
elif t.status == test.Test.FAIL:
|
||||||
failed += 1
|
failed += 1
|
||||||
else:
|
else: # error, could not run
|
||||||
skipped += 1
|
errors += 1
|
||||||
return (passed, skipped, failed)
|
return (passed, skipped, failed, errors)
|
||||||
|
|
||||||
def remember_to_stop(self, process, respawn=False):
|
def remember_to_stop(self, process, respawn=False):
|
||||||
'''Ask suite to monitor and manage lifecycle of the Process object. If a
|
'''Ask suite to monitor and manage lifecycle of the Process object. If a
|
||||||
|
|
|
@ -26,7 +26,7 @@ from . import testenv
|
||||||
from . import log, util, resource
|
from . import log, util, resource
|
||||||
|
|
||||||
class Test(log.Origin):
|
class Test(log.Origin):
|
||||||
UNKNOWN = 'UNKNOWN'
|
UNKNOWN = 'UNKNOWN' # matches junit 'error'
|
||||||
SKIP = 'skip'
|
SKIP = 'skip'
|
||||||
PASS = 'pass'
|
PASS = 'pass'
|
||||||
FAIL = 'FAIL'
|
FAIL = 'FAIL'
|
||||||
|
|
Loading…
Reference in New Issue