Bug 758452 - Add xUnit output support to Marionette, r=jgriffin, DONTBUILD because NPOTB,

This commit is contained in:
Mihnea Balaur 2012-07-10 10:37:00 -07:00
parent cc3721d151
commit d0872ccade

View File

@ -15,6 +15,7 @@ import sys
import time
import platform
import datazilla
import xml.dom.minidom as dom
try:
from manifestparser import TestManifest
@ -36,10 +37,12 @@ class MarionetteTestResult(unittest._TextTestResult):
super(MarionetteTestResult, self).__init__(*args)
self.passed = 0
self.perfdata = None
self.tests_passed = []
def addSuccess(self, test):
super(MarionetteTestResult, self).addSuccess(test)
self.passed += 1
self.tests_passed.append(test)
def getInfo(self, test):
if hasattr(test, 'jsFile'):
@ -148,7 +151,7 @@ class MarionetteTestRunner(object):
emulator_res='480x800', homedir=None, bin=None, profile=None,
autolog=False, revision=None, es_server=None,
rest_server=None, logger=None, testgroup="marionette",
noWindow=False, logcat_dir=None):
noWindow=False, logcat_dir=None, xml_output=None):
self.address = address
self.emulator = emulator
self.emulatorBinary = emulatorBinary
@ -168,6 +171,7 @@ class MarionetteTestRunner(object):
self.marionette = None
self.logcat_dir = logcat_dir
self.perfrequest = None
self.xml_output = xml_output
self.reset_test_stats()
@ -180,6 +184,9 @@ class MarionetteTestRunner(object):
if not os.access(self.logcat_dir, os.F_OK):
os.mkdir(self.logcat_dir)
# for XML output
self.results = []
def reset_test_stats(self):
self.passed = 0
self.failed = 0
@ -287,9 +294,9 @@ class MarionetteTestRunner(object):
self.logger.info('passed: %d' % self.passed)
self.logger.info('failed: %d' % self.failed)
self.logger.info('todo: %d' % self.todo)
elapsedtime = datetime.utcnow() - starttime
self.elapsedtime = datetime.utcnow() - starttime
if self.autolog:
self.post_to_autolog(elapsedtime)
self.post_to_autolog(self.elapsedtime)
if self.perfrequest and options.perf:
try:
self.perfrequest.submit()
@ -301,6 +308,10 @@ class MarionetteTestRunner(object):
self.marionette.emulator = None
self.marionette = None
if self.xml_output:
with open(self.xml_output, 'w') as f:
f.write(self.generate_xml(self.results))
def run_test(self, test, testtype):
if not self.httpd:
print "starting httpd"
@ -379,6 +390,8 @@ class MarionetteTestRunner(object):
if suite.countTestCases():
results = MarionetteTextTestRunner(verbosity=3).run(suite)
self.results.append(results)
self.failed += len(results.failures) + len(results.errors)
if results.perfdata and options.perf:
self.perfrequest.add_datazilla_result(results.perfdata)
@ -398,6 +411,86 @@ class MarionetteTestRunner(object):
__del__ = cleanup
def generate_xml(self, results_list):
def _extract_xml(test, text='', result='Pass'):
cls_name = test.__class__.__name__
# if the test class is not already created, create it
if cls_name not in classes:
cls = doc.createElement('class')
cls.setAttribute('name', cls_name)
assembly.appendChild(cls)
classes[cls_name] = cls
t = doc.createElement('test')
t.setAttribute('name', unicode(test).split()[0])
t.setAttribute('result', result)
if result == 'Fail':
f = doc.createElement('failure')
st = doc.createElement('stack-trace')
st.appendChild(doc.createTextNode(text))
f.appendChild(st)
t.appendChild(f)
elif result == 'Skip':
r = doc.createElement('reason')
msg = doc.createElement('message')
msg.appendChild(doc.createTextNode(text))
r.appendChild(msg)
t.appendChild(f)
cls = classes[cls_name]
cls.appendChild(t)
doc = dom.Document()
assembly = doc.createElement('assembly')
assembly.setAttribute('name', 'Tests')
assembly.setAttribute('time', str(self.elapsedtime))
assembly.setAttribute('total', str(sum([results.testsRun for
results in results_list])))
assembly.setAttribute('passed', str(sum([results.passed for
results in results_list])))
assembly.setAttribute('failed', str(sum([len(results.failures) +
len(results.errors) +
len(results.unexpectedSuccesses)
for results in results_list])))
assembly.setAttribute('skipped', str(sum([len(results.skipped) +
len(results.expectedFailures)
for results in results_list])))
for results in results_list:
classes = {} # str -> xml class element
for tup in results.errors:
_extract_xml(*tup, result='Fail')
for tup in results.failures:
_extract_xml(*tup, result='Fail')
for test in results.unexpectedSuccesses:
# unexpectedSuccesses is a list of Testcases only, no tuples
_extract_xml(test, text='TEST-UNEXPECTED-PASS', result='Fail')
for tup in results.skipped:
_extract_xml(*tup, result='Skip')
for tup in results.expectedFailures:
_extract_xml(*tup, result='Skip')
for test in results.tests_passed:
_extract_xml(test)
for cls in classes.itervalues():
assembly.appendChild(cls)
doc.appendChild(assembly)
return doc.toxml(encoding='utf-8')
if __name__ == "__main__":
parser = OptionParser(usage='%prog [options] test_file_or_dir <test_file_or_dir> ...')
@ -461,6 +554,8 @@ if __name__ == "__main__":
'will overwrite the perfserv value in any passed .ini files.')
parser.add_option('--repeat', dest='repeat', action='store', type=int,
default=0, help='number of times to repeat the test(s).')
parser.add_option('-x', '--xml-output', action='store', dest='xml_output',
help='XML output.')
options, tests = parser.parse_args()
@ -499,7 +594,8 @@ if __name__ == "__main__":
noWindow=options.noWindow,
revision=options.revision,
testgroup=options.testgroup,
autolog=options.autolog)
autolog=options.autolog,
xml_output=options.xml_output)
runner.run_tests(tests, testtype=options.type)
if runner.failed > 0:
sys.exit(10)