def _appendrow(self, result_name, report): time = getattr(report, 'duration', 0.0) additional_html = [] links_html = [] for extra in getattr(report, 'extra', []): self.append_extra_html(extra, additional_html, links_html) self.append_log_html(report, additional_html) test_id = report.nodeid if report.when != 'call': test_id = '::'.join([report.nodeid, report.when]) rows_table = html.tr([ html.td(result_name, class_='col-result'), html.td(test_id, class_='col-name'), html.td('{0:.2f}'.format(time), class_='col-duration'), html.td(links_html, class_='col-links')]) rows_extra = html.tr(html.td(additional_html, class_='extra', colspan='5')) self.test_logs.append(html.tbody(rows_table, rows_extra, class_=result_name.lower() + ' results-table-row'))
def generate_html(self): generated = datetime.datetime.now() with open(os.path.join(base_path, "main.js")) as main_f: doc = html.html( self.head, html.body( html.script(raw(main_f.read())), html.p( "Report generated on %s at %s" % (generated.strftime("%d-%b-%Y"), generated.strftime("%H:%M:%S")), html.h2("Summary"), html.p( "%i tests ran in %.1f seconds." % ( sum(self.test_count.itervalues()), (self.suite_times["end"] - self.suite_times["start"]) / 1000.0, ), html.br(), html.span("%i passed" % self.test_count["PASS"], class_="pass"), ", ", html.span("%i skipped" % self.test_count["SKIP"], class_="skip"), ", ", html.span("%i failed" % self.test_count["UNEXPECTED_FAIL"], class_="fail"), ", ", html.span("%i errors" % self.test_count["UNEXPECTED_ERROR"], class_="error"), ".", html.br(), html.span( "%i expected failures" % self.test_count["EXPECTED_FAIL"], class_="expected_fail" ), ", ", html.span( "%i unexpected passes" % self.test_count["UNEXPECTED_PASS"], class_="unexpected_pass" ), ".", ), html.h2("Results"), html.table( [ html.thead( html.tr( [ html.th("Result", class_="sortable", col="result"), html.th("Class", class_="sortable", col="class"), html.th("Test Name", class_="sortable", col="name"), html.th("Duration", class_="sortable numeric", col="duration"), html.th("Links"), ] ), id="results-table-head", ), html.tbody(self.result_rows, id="results-table-body"), ], id="results-table", ), ), ), ) return u"<!DOCTYPE html>\n" + doc.unicode(indent=2)
def _appendrow(self, outcome, report): result = self.TestResult(outcome, report, self.logfile, self.config) if result.row_table is not None: index = bisect.bisect_right(self.results, result) self.results.insert(index, result) tbody = html.tbody( result.row_table, class_='{0} results-table-row'.format(result.outcome.lower())) if result.row_extra is not None: tbody.append(result.row_extra) self.test_logs.insert(index, tbody)
def make_regression_table(self): return html.table( html.thead( html.tr( html.th("Parent Test", col='parent'), html.th("Subtest", col='subtest'), html.th("Expected", col='expected'), html.th("Result", col='result'), ), id='results-table-head' ), html.tbody(*self.make_table_rows(), id='results-table-body'), id='results-table' )
def pytest_sessionfinish(self, session, exitstatus): self._make_report_dir() logfile = py.std.codecs.open(self.logfile, 'w', encoding='utf-8') suite_stop_time = time.time() suite_time_delta = suite_stop_time - self.suite_start_time numtests = self.passed + self.failed generated = datetime.datetime.now() doc = html.html( html.head( html.meta(charset='utf-8'), html.title('Test Report'), html.link(rel='stylesheet', href='style.css'), html.script(src='jquery.js'), html.script(src='main.js')), html.body( html.p('Report generated on %s at %s ' % ( generated.strftime('%d-%b-%Y'), generated.strftime('%H:%M:%S'), )), html.div([html.p( html.span('%i tests' % numtests, class_='all clickable'), ' ran in %i seconds.' % suite_time_delta, html.br(), html.span('%i passed' % self.passed, class_='passed clickable'), ', ', html.span('%i skipped' % self.skipped, class_='skipped clickable'), ', ', html.span('%i failed' % self.failed, class_='failed clickable'), ', ', html.span('%i errors' % self.errors, class_='error clickable'), '.', html.br(), ), html.span('Hide all errors', class_='clickable hide_all_errors'), ', ', html.span('Show all errors', class_='clickable show_all_errors'), ], id='summary-wrapper'), html.div(id='summary-space'), html.table([ html.thead(html.tr([ html.th('Result', class_='sortable', col='result'), html.th('Class', class_='sortable', col='class'), html.th('Name', class_='sortable', col='name'), html.th('Duration', class_='sortable numeric', col='duration'), # html.th('Output')]), id='results-table-head'), html.th('Links')]), id='results-table-head'), html.tbody(*self.test_logs, id='results-table-body')], id='results-table'))) logfile.write( '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' + doc.unicode( indent=2)) logfile.close() self.process_screenshot_files() self.process_debug_event_files() self.process_performance_files()
def make_result_table(self): return html.table( html.thead( html.tr( html.th("Subsuite"), html.th("Subsuite Errors"), html.th("Test Regressions"), html.th("Details") ) ), html.tbody( self.make_table_rows(self.subsuite_results) ) )
def make_result_table(self): return html.table( html.thead( html.tr( html.th("Subsuite", class_='sortable', col='subsuite'), html.th("Subsuite Errors"), html.th("Test Executions"), html.th("Details") ) ), html.tbody( self.make_table_rows(self.subsuite_results),id='results-table-body' ), id='results-table' )
def make_regression_table(self): return html.table( html.thead( html.tr( html.th("Parent Test"), html.th("Subtest"), html.th("Expected"), html.th("Result"), html.th("Message") ) ), html.tbody( *self.make_table_rows() ) )
def gen_html_table( mtx ): from py.xml import html # print("DBG genhtmltable", mtx) result = html.table( html.thead( html.tr( [html.th( x ) for x in mtx[0] ] ) ), # header html.tbody( *[ html.tr( [html.td( x ) for x in row] ) # rows for row in mtx[1:] ] ), class_="fixed_headers" ) # make it fixed height scrollable # https://codepen.io/tjvantoll/pen/JEKIu # result = str(result) + """ # """ return str(result)
def create_dir_html(path, href_prefix=''): h = html.html( html.head( html.title('directory listing of %s' % (path,)), style, ), ) body = html.body( html.h1('directory listing of %s' % (path,)), ) h.append(body) table = html.table() body.append(table) tbody = html.tbody() table.append(tbody) items = list(path.listdir()) items.sort(key=lambda p: p.basename) items.sort(key=lambda p: not p.check(dir=True)) for fpath in items: tr = html.tr() tbody.append(tr) td1 = html.td(fpath.check(dir=True) and 'D' or 'F', class_='type') tr.append(td1) href = fpath.basename if href_prefix: href = '%s%s' % (href_prefix, href) if fpath.check(dir=True): href += '/' td2 = html.td(html.a(fpath.basename, href=href), class_='name') tr.append(td2) td3 = html.td(time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(fpath.mtime())), class_='mtime') tr.append(td3) if fpath.check(dir=True): size = '' unit = '' else: size = fpath.size() unit = 'B' for u in ['kB', 'MB', 'GB', 'TB']: if size > 1024: size = round(size / 1024.0, 2) unit = u td4 = html.td('%s %s' % (size, unit), class_='size') tr.append(td4) return unicode(h)
def pytest_html_results_summary(prefix, summary, postfix): postfix.extend([ HTMLStyle.table( html.thead( html.tr([ HTMLStyle.th("Tests"), HTMLStyle.th("Success"), HTMLStyle.th("Failed"), HTMLStyle.th("XFail"), HTMLStyle.th("Error") ]), ), [ html.tbody( html.tr([ HTMLStyle.td(k), HTMLStyle.td(v['passed']), HTMLStyle.td(v['failed']), HTMLStyle.td(v['xfailed']), HTMLStyle.td(v['error']), ])) for k, v in results.items() ]) ])
def generate_html(self): generated = datetime.utcnow() with open(os.path.join(base_path, "main.js")) as main_f: doc = html.html( self.head, html.body( html.script(raw(main_f.read())), html.p('Report generated on %s at %s' % ( generated.strftime('%d-%b-%Y'), generated.strftime('%H:%M:%S'))), html.h2('Environment'), html.table( [html.tr(html.td(k), html.td(v)) for k, v in sorted(self.env.items()) if v], id='environment'), html.h2('Summary'), html.p('%i tests ran in %.1f seconds.' % (sum(self.test_count.itervalues()), (self.suite_times["end"] - self.suite_times["start"]) / 1000.), html.br(), html.span('%i passed' % self.test_count["PASS"], class_='pass'), ', ', html.span('%i skipped' % self.test_count["SKIP"], class_='skip'), ', ', html.span('%i failed' % self.test_count["UNEXPECTED_FAIL"], class_='fail'), ', ', html.span('%i errors' % self.test_count["UNEXPECTED_ERROR"], class_='error'), '.', html.br(), html.span('%i expected failures' % self.test_count["EXPECTED_FAIL"], class_='expected_fail'), ', ', html.span('%i unexpected passes' % self.test_count["UNEXPECTED_PASS"], class_='unexpected_pass'), '.'), html.h2('Results'), html.table([html.thead( html.tr([ html.th('Result', class_='sortable', col='result'), html.th('Test', class_='sortable', col='name'), html.th('Duration', class_='sortable numeric', col='duration'), html.th('Links')]), id='results-table-head'), html.tbody(self.result_rows, id='results-table-body')], id='results-table'))) return u"<!DOCTYPE html>\n" + doc.unicode(indent=2)
def generate_html(self): generated = datetime.datetime.now() with open(os.path.join(base_path, "main.js")) as main_f: doc = html.html( self.head, html.body( html.script( raw(main_f.read()), ), html.p('Report generated on %s at %s' % ( generated.strftime('%d-%b-%Y'), generated.strftime('%H:%M:%S')), html.h2('Summary'), html.p('%i tests ran in %.1f seconds.' % (sum(self.test_count.itervalues()), (self.suite_times["end"] - self.suite_times["start"]) / 1000.), html.br(), html.span('%i passed' % self.test_count["PASS"], class_='pass'), ', ', html.span('%i skipped' % self.test_count["SKIP"], class_='skip'), ', ', html.span('%i failed' % self.test_count["UNEXPECTED_FAIL"], class_='fail'), ', ', html.span('%i errors' % self.test_count["UNEXPECTED_ERROR"], class_='error'), '.', html.br(), html.span('%i expected failures' % self.test_count["EXPECTED_FAIL"], class_='expected_fail'), ', ', html.span('%i unexpected passes' % self.test_count["UNEXPECTED_PASS"], class_='unexpected_pass'), '.'), html.h2('Results'), html.table([html.thead( html.tr([ html.th('Result', class_='sortable', col='result'), html.th('Class', class_='sortable', col='class'), html.th('Test Name', class_='sortable', col='name'), html.th('Duration', class_='sortable numeric', col='duration'), html.th('Links')]), id='results-table-head'), html.tbody(self.result_rows, id='results-table-body')], id='results-table')))) return u"<!DOCTYPE html>\n" + doc.unicode(indent=2)
def handle_dcmp(self, dcmp): self.div_container.append( html.h2('Diff between %s and %s' % (dcmp.left, dcmp.right))) if len(dcmp.left_only) == 0 and len(dcmp.right_only) == 0 and len( dcmp.diff_files) == 0: self.div_container.append(html.p('No Differences Found')) # handle left dir1 if len(dcmp.left_only) > 0: self.div_container.append(html.h3('Only in %s' % (dcmp.left, ))) ul_left = html.ul() for name in dcmp.left_only: ul_left.append(html.li(name)) self.div_container.append(ul_left) # handle right dir2 if len(dcmp.right_only) > 0: self.div_container.append(html.h3('Only in %s' % (dcmp.right, ))) ul_right = html.ul() for name in dcmp.right_only: ul_right.append(html.li(name)) self.div_container.append(ul_right) # handle diff between dir1 and dir2 for name in dcmp.diff_files: if self.is_binary_file(os.path.join(dcmp.left, name), 1024): self.div_container.append( html.table(html.thead( html.tr(html.th(os.path.join(dcmp.left, name)), html.th(os.path.join(dcmp.right, name)))), html.tbody( html.tr(html.td('Binary files differ'))), class_='table')) else: self.diff_file(os.path.join(dcmp.left, name), os.path.join(dcmp.right, name)) # handle sub-dirs for sub_dcmp in dcmp.subdirs.values(): self.handle_dcmp(sub_dcmp)
def _generate_report(self, session): suite_stop_time = time.time() suite_time_delta = suite_stop_time - self.suite_start_time test_duration = '%.4f' %(suite_time_delta) numtests = self.passed + self.failed + self.xpassed + self.xfailed generated = datetime.datetime.now() jkbuildid=session.config.getoption("--jkbuildid") jkjobname=session.config.getoption("--jkjobname") if jkbuildid!=-1 and jkjobname: #print('update test collection to mysql, jobname: {}, buildid: {}'.format(jkjobname,jkbuildid)) try: from localplugins.mysql_opr import query_pymysql fpath=os.path.join(BASE_DIR,'localplugins','resources', 'mysql_conn.json') #print('fpath :',fpath) f=open(fpath, 'r', encoding='utf-8') dbinfo = json.loads(f.read()) sql=''' UPDATE uitest_collect SET fail_total={},pass_total={},skip_total={},error_total={},run_total={},duration='{}' WHERE jk_jobname='{}' AND jk_buildid='{}' '''.format(self.failed,self.passed,self.skipped,self.errors,numtests,test_duration,jkjobname,jkbuildid) #print('update uitest_collect: ',sql) query_pymysql(dbinfo['host'],dbinfo['user'],dbinfo['password'],dbinfo['port'],'qateam',sql) #print('.......update test collection to mysql <uitest_collect>......',time.strftime('%Y-%m-%d %H:%M:%S')) except Exception as e: print('[Exception<updating to uitest_collect>]',end='') #print('Exception when updating test collection to mysql: ',e) self.style_css = pkg_resources.resource_string( __name__, os.path.join('resources', 'style.css')) #print() #print('sytle_css path: ',os.path.join('resources', 'style.css')) if PY3: self.style_css = self.style_css.decode('utf-8') if ANSI: ansi_css = [ '\n/******************************', ' * ANSI2HTML STYLES', ' ******************************/\n'] ansi_css.extend([str(r) for r in style.get_styles()]) self.style_css += '\n'.join(ansi_css) # <DF> Add user-provided CSS for path in self.config.getoption('css') or []: self.style_css += '\n/******************************' self.style_css += '\n * CUSTOM CSS' self.style_css += '\n * {}'.format(path) self.style_css += '\n ******************************/\n\n' with open(path, 'r') as f: self.style_css += f.read() css_href = '{0}/{1}'.format('assets', 'style.css') html_css = html.link(href=css_href, rel='stylesheet', type='text/css') if self.self_contained: html_css = html.style(raw(self.style_css)) head = html.head( html.meta(charset='utf-8'), html.title('Test Report'), html_css) class Outcome: def __init__(self, outcome, total=0, label=None, test_result=None, class_html=None): self.outcome = outcome self.label = label or outcome self.class_html = class_html or outcome self.total = total self.test_result = test_result or outcome self.generate_checkbox() self.generate_summary_item() def generate_checkbox(self): checkbox_kwargs = {'data-test-result': self.test_result.lower()} if self.total == 0: checkbox_kwargs['disabled'] = 'true' self.checkbox = html.input(type='checkbox', checked='true', onChange='filter_table(this)', name='filter_checkbox', class_='filter', hidden='true', **checkbox_kwargs) def generate_summary_item(self): self.summary_item = html.span('{0} {1}'. format(self.total, self.label), class_=self.class_html) ''' outcomes = [Outcome('passed', self.passed), Outcome('skipped', self.skipped), Outcome('failed', self.failed), Outcome('error', self.errors, label='errors'), Outcome('xfailed', self.xfailed, label='expected failures'), Outcome('xpassed', self.xpassed, label='unexpected passes')] ''' outcomes = [Outcome('passed', self.passed, label='成功'), Outcome('skipped', self.skipped, label='过滤掉'), Outcome('failed', self.failed, label='失败'), Outcome('error', self.errors, label='报错'), #Outcome('xfailed', self.xfailed,label='预期为失败'), #Outcome('xpassed', self.xpassed,label='预期为成功') ] if self.rerun is not None: outcomes.append(Outcome('rerun', self.rerun,label='再次执行')) ''' summary = [html.p( '{0} tests ran in {1:.2f} seconds. '.format( numtests, suite_time_delta)), html.p('(Un)check the boxes to filter the results.', class_='filter', hidden='true')] ''' summary_thead = [ html.th('失败'), html.th('总共'), html.th('成功'), html.th('过滤'), html.th('报错')] summary_tbody = [ html.td(self.failed,class_='red'), html.td(numtests), html.td(self.passed), html.td(self.skipped), html.td(self.errors,style='color:red;')] # summary_table = [ # html.table([ # html.thead( # html.tr(summary_thead), # id='results-table-head' # ), # html.tbody(html.tr(summary_tbody)) # ], # class_='table-50') # ] summary = [ html.p('总共 {0} 个用例,总耗时: {1:.2f} 秒. '.format( numtests, suite_time_delta)), html.table([ html.thead( html.tr(summary_thead), id='results-summary' ), html.tbody(html.tr(summary_tbody)) ], class_='table-350') ] ''' summary = [ html.p('总共 {0} 个用例,总耗时: {1:.2f} 秒. '.format( numtests, suite_time_delta)), html.table([ html.thead( html.tr(summary_thead), id='results-summary' ), html.tbody(html.tr(summary_tbody)) ], class_='table-50'), html.p('勾选/取消勾选 复选框来过滤测试结果.', class_='filter', hidden='true') ] for i, outcome in enumerate(outcomes, start=1): summary.append(outcome.checkbox) summary.append(outcome.summary_item) if i < len(outcomes): summary.append(', ') cells = [ html.th('Result', class_='sortable result initial-sort', col='result'), html.th('Test', class_='sortable', col='name'), html.th('Duration', class_='sortable numeric', col='duration'), html.th('Links') ] ''' cells = [ html.th('用例状态', class_='sortable result initial-sort', col='result'), html.th('用例功能描述', col='description'), html.th('测试用例', class_='sortable', col='name'), html.th('运行耗时', class_='sortable numeric', col='duration') #,html.th('链接') ] session.config.hook.pytest_html_results_table_header(cells=cells) ''' results = [html.h2('Results'), html.table([html.thead( html.tr(cells), html.tr([ html.th('No results found. Try to check the filters', colspan=len(cells))], id='not-found-message', hidden='true'), id='results-table-head'), self.test_logs], id='results-table')] ''' results = [ html.h2('测试结果'), html.table([html.thead( html.tr(cells), html.tr([html.th('没有用例,请检查过滤条件',colspan=len(cells))], id='not-found-message', hidden='true'), id='results-table-head'), self.test_logs ], id='results-table',class_='table') ] #print('self.test_logs: ',self.test_logs) main_js = pkg_resources.resource_string( __name__, os.path.join('resources', 'main.js')) if PY3: main_js = main_js.decode('utf-8') '''***********************************gql*************************************** html.h1(os.path.basename(session.config.option.htmlpath)), html.p('Report generated on {0} at {1} by '.format( generated.strftime('%d-%b-%Y'), generated.strftime('%H:%M:%S')), html.a('pytest-html', href=__pypi_url__), ' v{0}'.format(__version__)), # html 标题 ''' body = html.body( html.script(raw(main_js)), #html.h1(os.path.basename(session.config.option.htmlpath)), html.h1(self.htmlhead), html.p('测试报告运行于: {0} {1}'.format( generated.strftime('%Y-%m-%d'), generated.strftime('%H:%M:%S')) #,html.a('pytest-html', href='http://www.baidu.com/'),' v{0}'.format('2.11') ), onLoad='init()') '''***********************************gql*************************************** body.extend(self._generate_environment(session.config)) ''' #body.extend(self._generate_environment(session.config)) summary_prefix, summary_postfix = [], [] session.config.hook.pytest_html_results_summary( prefix=summary_prefix, summary=summary, postfix=summary_postfix) '''***********************************gql*************************************** body.extend([html.h2('Summary')] + summary_prefix + summary + summary_postfix) ''' #print('html-body-extend--summary: ',summary) body.extend(summary) body.extend(results) doc = html.html(head, body) unicode_doc = u'<!DOCTYPE html>\n{0}'.format(doc.unicode(indent=2)) if PY3: # Fix encoding issues, e.g. with surrogates unicode_doc = unicode_doc.encode('utf-8', errors='xmlcharrefreplace') unicode_doc = unicode_doc.decode('utf-8') return unicode_doc
html.span('%i passed' % passed, class_='passed'), ', ', #'self.passed' html.span('%i skipped' % skipped, class_='skipped'), ', ', #'self.skipped' html.span('%i failed' % failed, class_='failed'), ', ', #'self.failed' html.span('%i errors' % errors, class_='error'), '.', #'self.errors' html.br()), #html.span('%i expected failures' % 0, class_='skipped'), ', ', #'self.xfailed' #html.span('%i unexpected passes' % 0, class_='failed'), '.'), #'self.xpassed' html.h2('Results'), html.table([ html.thead(html.tr([ html.th('Result', class_='sortable', col='result'), html.th('Class', class_='sortable', col='class'), html.th('Name', class_='sortable', col='name'), html.th( 'Duration', class_='sortable numeric', col='duration'), html.th('Links') ]), id='results-table-head'), html.tbody(*test_logs, id='results-table-body') ], id='results-table')))) # Write HTML report file logfile.write( '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' + doc.unicode(indent=2)) logfile.close()
def generate_html(self, results_list): tests = sum([results.testsRun for results in results_list]) failures = sum([len(results.failures) for results in results_list]) expected_failures = sum([len(results.expectedFailures) for results in results_list]) skips = sum([len(results.skipped) for results in results_list]) errors = sum([len(results.errors) for results in results_list]) passes = sum([results.passed for results in results_list]) unexpected_passes = sum([len(results.unexpectedSuccesses) for results in results_list]) test_time = self.elapsedtime.total_seconds() test_logs = [] def _extract_html(test, class_name, duration=0, text='', result='passed', debug=None): cls_name = class_name tc_name = unicode(test) tc_time = duration additional_html = [] debug = debug or {} links_html = [] if result in ['skipped', 'failure', 'expected failure', 'error']: if debug.get('screenshot'): screenshot = 'data:image/png;base64,%s' % debug['screenshot'] additional_html.append(html.div( html.a(html.img(src=screenshot), href="#"), class_='screenshot')) for name, content in debug.items(): try: if 'screenshot' in name: href = '#' else: # use base64 to avoid that some browser (such as Firefox, Opera) # treats '#' as the start of another link if the data URL contains. # use 'charset=utf-8' to show special characters like Chinese. href = 'data:text/plain;charset=utf-8;base64,%s' % base64.b64encode(content) links_html.append(html.a( name.title(), class_=name, href=href, target='_blank')) links_html.append(' ') except: pass log = html.div(class_='log') for line in text.splitlines(): separator = line.startswith(' ' * 10) if separator: log.append(line[:80]) else: if line.lower().find("error") != -1 or line.lower().find("exception") != -1: log.append(html.span(raw(cgi.escape(line)), class_='error')) else: log.append(raw(cgi.escape(line))) log.append(html.br()) additional_html.append(log) test_logs.append(html.tr([ html.td(result.title(), class_='col-result'), html.td(cls_name, class_='col-class'), html.td(tc_name, class_='col-name'), html.td(tc_time, class_='col-duration'), html.td(links_html, class_='col-links'), html.td(additional_html, class_='debug')], class_=result.lower() + ' results-table-row')) for results in results_list: for test in results.tests_passed: _extract_html(test.name, test.test_class) for result in results.skipped: _extract_html(result.name, result.test_class, text='\n'.join(result.output), result='skipped') for result in results.failures: _extract_html(result.name, result.test_class, text='\n'.join(result.output), result='failure', debug=result.debug) for result in results.expectedFailures: _extract_html(result.name, result.test_class, text='\n'.join(result.output), result='expected failure', debug=result.debug) for test in results.unexpectedSuccesses: _extract_html(test.name, test.test_class, result='unexpected pass') for result in results.errors: _extract_html(result.name, result.test_class, text='\n'.join(result.output), result='error', debug=result.debug) generated = datetime.datetime.now() doc = html.html( html.head( html.meta(charset='utf-8'), html.title('Test Report'), html.style(raw(pkg_resources.resource_string( __name__, os.path.sep.join(['resources', 'report', 'style.css']))), type='text/css')), html.body( html.script(raw(pkg_resources.resource_string( __name__, os.path.sep.join(['resources', 'report', 'jquery.js']))), type='text/javascript'), html.script(raw(pkg_resources.resource_string( __name__, os.path.sep.join(['resources', 'report', 'main.js']))), type='text/javascript'), html.p('Report generated on %s at %s by %s %s' % ( generated.strftime('%d-%b-%Y'), generated.strftime('%H:%M:%S'), __name__, __version__)), html.h2('Summary'), html.p('%i tests ran in %i seconds.' % (tests, test_time), html.br(), html.span('%i passed' % passes, class_='passed'), ', ', html.span('%i skipped' % skips, class_='skipped'), ', ', html.span('%i failed' % failures, class_='failed'), ', ', html.span('%i errors' % errors, class_='error'), '.', html.br(), html.span('%i expected failures' % expected_failures, class_='expected failure'), ', ', html.span('%i unexpected passes' % unexpected_passes, class_='unexpected pass'), '.'), html.h2('Results'), html.table([html.thead( html.tr([ html.th('Result', class_='sortable', col='result'), html.th('Class', class_='sortable', col='class'), html.th('Test Name', class_='sortable', col='name'), html.th('Duration', class_='sortable numeric', col='duration'), html.th('Links')]), id='results-table-head'), html.tbody(test_logs, id='results-table-body')], id='results-table'))) return doc.unicode(indent=2)
def pytest_sessionfinish(self, session): if not os.path.exists(os.path.dirname(self.logfile)): os.makedirs(os.path.dirname(self.logfile)) logfile = open(self.logfile, 'w', encoding='utf-8') suite_stop_time = time.time() suite_time_delta = suite_stop_time - self.suite_start_time numtests = self.passed + self.failed + self.xpassed + self.xfailed generated = datetime.datetime.now() style_css = pkg_resources.resource_string( __name__, os.path.join('resources', 'style.css')) if PY3: style_css = style_css.decode('utf-8') head = html.head( html.meta(charset='utf-8'), html.title('Test Report'), html.style(raw(style_css))) summary = [html.h2('Summary'), html.p( '{0} tests ran in {1:.2f} seconds.'.format( numtests, suite_time_delta), html.br(), html.span('{0} passed'.format( self.passed), class_='passed'), ', ', html.span('{0} skipped'.format( self.skipped), class_='skipped'), ', ', html.span('{0} failed'.format( self.failed), class_='failed'), ', ', html.span('{0} errors'.format( self.errors), class_='error'), '.', html.br(), html.span('{0} expected failures'.format( self.xfailed), class_='skipped'), ', ', html.span('{0} unexpected passes'.format( self.xpassed), class_='failed'), '.')] results = [html.h2('Results'), html.table([html.thead( html.tr([ html.th('Result', class_='sortable initial-sort result', col='result'), html.th('Test', class_='sortable', col='name'), html.th('Duration', class_='sortable numeric', col='duration'), html.th('Links')]), id='results-table-head'), html.tbody(*self.test_logs, id='results-table-body')], id='results-table')] main_js = pkg_resources.resource_string( __name__, os.path.join('resources', 'main.js')) if PY3: main_js = main_js.decode('utf-8') body = html.body( html.script(raw(main_js)), html.p('Report generated on {0} at {1}'.format( generated.strftime('%d-%b-%Y'), generated.strftime('%H:%M:%S')))) if session.config._environment: environment = set(session.config._environment) body.append(html.h2('Environment')) body.append(html.table( [html.tr(html.td(e[0]), html.td(e[1])) for e in sorted( environment, key=lambda e: e[0]) if e[1]], id='environment')) body.extend(summary) body.extend(results) doc = html.html(head, body) logfile.write('<!DOCTYPE html>') unicode_doc = doc.unicode(indent=2) if PY3: # Fix encoding issues, e.g. with surrogates unicode_doc = unicode_doc.encode('utf-8', errors='xmlcharrefreplace') unicode_doc = unicode_doc.decode('utf-8') logfile.write(unicode_doc) logfile.close()
def pytest_sessionfinish(self): if not os.path.exists(os.path.dirname(self.logfile)): os.makedirs(os.path.dirname(self.logfile)) logfile = open(self.logfile, 'w', encoding='utf-8') suite_stop_time = time.time() suite_time_delta = suite_stop_time - self.suite_start_time numtests = self.passed + self.failed + self.xpassed + self.xfailed generated = datetime.datetime.now() style_css = pkg_resources.resource_string( __name__, os.path.join('resources', 'style.css')) if PY3: style_css = style_css.decode('utf-8') head = html.head( html.meta(charset='utf-8'), html.title('Test Report'), html.style(raw(style_css))) summary = [html.h2('Summary'), html.p( '%i tests ran in %.2f seconds.' % (numtests, suite_time_delta), html.br(), html.span('%i passed' % self.passed, class_='passed'), ', ', html.span('%i skipped' % self.skipped, class_='skipped'), ', ', html.span('%i failed' % self.failed, class_='failed'), ', ', html.span('%i errors' % self.errors, class_='error'), '.', html.br(), html.span('%i expected failures' % self.xfailed, class_='skipped'), ', ', html.span('%i unexpected passes' % self.xpassed, class_='failed'), '.')] results = [html.h2('Results'), html.table([html.thead( html.tr([ html.th('Result', class_='sortable initial-sort result', col='result'), html.th('Test', class_='sortable', col='name'), html.th('Duration', class_='sortable numeric', col='duration'), html.th('Links')]), id='results-table-head'), html.tbody(*self.test_logs, id='results-table-body')], id='results-table')] main_js = pkg_resources.resource_string( __name__, os.path.join('resources', 'main.js')) if PY3: main_js = main_js.decode('utf-8') body = html.body( html.script(raw(main_js)), html.p('Report generated on %s at %s' % ( generated.strftime('%d-%b-%Y'), generated.strftime('%H:%M:%S')))) environment = {} for e in self.environment: for k, v in e.items(): environment[k] = v if environment: body.append(html.h2('Environment')) body.append(html.table( [html.tr(html.td(k), html.td(v)) for k, v in sorted( environment.items()) if v], id='environment')) body.extend(summary) body.extend(results) doc = html.html(head, body) logfile.write('<!DOCTYPE html>') logfile.write(doc.unicode(indent=2)) logfile.close()
def pytest_sessionfinish(self, session, exitstatus, __multicall__): self._make_report_dir() logfile = py.std.codecs.open(self.logfile, 'w', encoding='utf-8') suite_stop_time = time.time() suite_time_delta = suite_stop_time - self.suite_start_time numtests = self.passed + self.failed generated = datetime.datetime.now() doc = html.html( html.head(html.meta(charset='utf-8'), html.title('Test Report'), html.link(rel='stylesheet', href='style.css'), html.script(src='jquery.js'), html.script(src='main.js')), html.body( html.p('Report generated on %s at %s ' % ( generated.strftime('%d-%b-%Y'), generated.strftime('%H:%M:%S'), )), html.div([ html.p( html.span('%i tests' % numtests, class_='all clickable'), ' ran in %i seconds.' % suite_time_delta, html.br(), html.span('%i passed' % self.passed, class_='passed clickable'), ', ', html.span('%i skipped' % self.skipped, class_='skipped clickable'), ', ', html.span('%i failed' % self.failed, class_='failed clickable'), ', ', html.span('%i errors' % self.errors, class_='error clickable'), '.', html.br(), ), html.span('Hide all errors', class_='clickable hide_all_errors'), ', ', html.span('Show all errors', class_='clickable show_all_errors'), ], id='summary-wrapper'), html.div(id='summary-space'), html.table( [ html.thead( html.tr([ html.th( 'Result', class_='sortable', col='result'), html.th( 'Class', class_='sortable', col='class'), html.th('Name', class_='sortable', col='name'), html.th('Duration', class_='sortable numeric', col='duration'), #html.th('Output')]), id='results-table-head'), html.th('Links to BrowserStack') ]), id='results-table-head'), html.tbody(*self.test_logs, id='results-table-body') ], id='results-table'))) logfile.write( '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' + doc.unicode(indent=2)) logfile.close() self.process_screenshot_files()
def pytest_sessionfinish(self, session, exitstatus, __multicall__): self._make_report_dir() logfile = py.std.codecs.open(self.logfile, 'w', encoding='utf-8') suite_stop_time = time.time() suite_time_delta = suite_stop_time - self.suite_start_time numtests = self.passed + self.failed + self.xpassed + self.xfailed server = self.config.option.sauce_labs_credentials_file and \ 'Sauce Labs' or 'http://%s:%s' % (self.config.option.host, self.config.option.port) browser = self.config.option.browser_name and \ self.config.option.browser_version and \ self.config.option.platform and \ '%s %s on %s' % (str(self.config.option.browser_name).title(), self.config.option.browser_version, str(self.config.option.platform).title()) or \ self.config.option.environment or \ self.config.option.browser generated = datetime.datetime.now() configuration = { 'Base URL': self.config.option.base_url, 'Build': self.config.option.build, 'Selenium API': self.config.option.api, 'Driver': self.config.option.driver, 'Firefox Path': self.config.option.firefox_path, 'Google Chrome Path': self.config.option.chrome_path, 'Selenium Server': server, 'Browser': browser, 'Timeout': self.config.option.webqatimeout, 'Capture Network Traffic': self.config.option.capture_network, 'Credentials': self.config.option.credentials_file, 'Sauce Labs Credentials': self.config.option.sauce_labs_credentials_file} import pytest_mozwebqa doc = html.html( html.head( html.meta(charset='utf-8'), html.title('Test Report'), html.link(rel='stylesheet', href='style.css'), html.script(src='jquery.js'), html.script(src='main.js')), html.body( html.p('Report generated on %s at %s by pytest-mozwebqa %s' % ( generated.strftime('%d-%b-%Y'), generated.strftime('%H:%M:%S'), pytest_mozwebqa.__version__)), html.h2('Configuration'), html.table( [html.tr(html.td(k), html.td(v)) for k, v in sorted(configuration.items()) if v], id='configuration'), html.h2('Summary'), html.p( '%i tests ran in %i seconds.' % (numtests, suite_time_delta), html.br(), html.span('%i passed' % self.passed, class_='passed'), ', ', html.span('%i skipped' % self.skipped, class_='skipped'), ', ', html.span('%i failed' % self.failed, class_='failed'), ', ', html.span('%i errors' % self.errors, class_='error'), '.', html.br(), html.span('%i expected failures' % self.xfailed, class_='skipped'), ', ', html.span('%i unexpected passes' % self.xpassed, class_='failed'), '.'), html.h2('Results'), html.table([ html.thead(html.tr([ html.th('Result', class_='sortable', col='result'), html.th('Class', class_='sortable', col='class'), html.th('Name', class_='sortable', col='name'), html.th('Duration', class_='sortable numeric', col='duration'), html.th('Links')]), id='results-table-head'), html.tbody(*self.test_logs, id='results-table-body')], id='results-table'))) logfile.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' + doc.unicode(indent=2)) logfile.close()
generated.strftime('%d-%b-%Y'), generated.strftime('%H:%M:%S'), 'v0.0.1'), html.h2('Configuration'), html.table( [html.tr(html.td(k), html.td(v)) for k, v in sorted(configuration.items()) if v], id='configuration'), html.h2('Summary'), html.p( '%i tests ran in %i seconds.' % (numtests , suite_time_delta ), #'''numtests''' '''suite_time_delta''' html.br(), html.span('%i passed' % passed, class_='passed'), ', ', #'self.passed' html.span('%i skipped' % skipped, class_='skipped'), ', ', #'self.skipped' html.span('%i failed' % failed, class_='failed'), ', ', #'self.failed' html.span('%i errors' % errors, class_='error'), '.', #'self.errors' html.br()), #html.span('%i expected failures' % 0, class_='skipped'), ', ', #'self.xfailed' #html.span('%i unexpected passes' % 0, class_='failed'), '.'), #'self.xpassed' html.h2('Results'), html.table([ html.thead(html.tr([ html.th('Result', class_='sortable', col='result'), html.th('Class', class_='sortable', col='class'), html.th('Name', class_='sortable', col='name'), html.th('Duration', class_='sortable numeric', col='duration'), html.th('Links')]), id='results-table-head'), html.tbody(*test_logs, id='results-table-body')], id='results-table')))) # Write HTML report file logfile.write('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' + doc.unicode(indent=2)) logfile.close()
def _generate_report(self, session): """ The method writes HTML report to a temporary logfile. """ suite_stop_time = time.time() suite_time_delta = suite_stop_time - self.suite_start_time numtests = self.passed + self.failed + self.xpassed + self.xfailed generated = datetime.datetime.now() style_css = pkg_resources.resource_string( pytest_html_path, os.path.join('resources', 'style.css')) head = html.head( html.meta(charset='utf-8'), html.title('Test Report'), html.style(raw(style_css))) summary = [html.h2('Summary'), html.p( '{0} tests ran in {1:.2f} seconds.'.format( numtests, suite_time_delta), html.br(), html.span('{0} passed'.format( self.passed), class_='passed'), ', ', html.span('{0} skipped'.format( self.skipped), class_='skipped'), ', ', html.span('{0} failed'.format( self.failed), class_='failed'), ', ', html.span('{0} errors'.format( self.errors), class_='error'), '.', html.br(), html.span('{0} expected failures'.format( self.xfailed), class_='skipped'), ', ', html.span('{0} unexpected passes'.format( self.xpassed), class_='failed'), '.')] results = [html.h2('Results'), html.table([html.thead( html.tr([ html.th('Result', class_='sortable initial-sort result', col='result'), html.th('Test', class_='sortable', col='name'), html.th('Duration', class_='sortable numeric', col='duration'), html.th('Links')]), id='results-table-head'), html.tbody(*self.test_logs, id='results-table-body')], id='results-table')] main_js = pkg_resources.resource_string( pytest_html_path, os.path.join('resources', 'main.js')) body = html.body( html.script(raw(main_js)), html.p('Report generated on {0} at {1}'.format( generated.strftime('%d-%b-%Y'), generated.strftime('%H:%M:%S')))) if session.config._environment: environment = set(session.config._environment) body.append(html.h2('Environment')) body.append(html.table( [html.tr(html.td(e[0]), html.td(e[1])) for e in sorted( environment, key=lambda e: e[0]) if e[1]], id='environment')) body.extend(summary) body.extend(results) doc = html.html(head, body) # A string which holds the complete report. report_content = ( "Test executed on commit " "[[https://www.github.com/tardis-sn/tardis/commit/{0}|{0}]]\n\n".format( tardis.__githash__ ) ) report_content += doc.unicode(indent=2) # Quick hack for preventing log to be placed in narrow left out space report_content = report_content.replace( u'class="log"', u'class="log" style="clear: both"' ) return report_content
def pytest_sessionfinish(self, session): if not os.path.exists(os.path.dirname(self.logfile)): os.makedirs(os.path.dirname(self.logfile)) logfile = open(self.logfile, 'w', encoding='utf-8') suite_stop_time = time.time() suite_time_delta = suite_stop_time - self.suite_start_time numtests = self.passed + self.failed + self.xpassed + self.xfailed generated = datetime.datetime.now() style_css = pkg_resources.resource_string( __name__, os.path.join('resources', 'style.css')) if PY3: style_css = style_css.decode('utf-8') head = html.head(html.meta(charset='utf-8'), html.title('Test Report'), html.style(raw(style_css))) summary = [ html.h2('Summary'), html.p( '{0} tests ran in {1:.2f} seconds.'.format( numtests, suite_time_delta), html.br(), html.span('{0} passed'.format(self.passed), class_='passed'), ', ', html.span('{0} skipped'.format(self.skipped), class_='skipped'), ', ', html.span('{0} failed'.format(self.failed), class_='failed'), ', ', html.span('{0} errors'.format(self.errors), class_='error'), '.', html.br(), html.span('{0} expected failures'.format(self.xfailed), class_='skipped'), ', ', html.span('{0} unexpected passes'.format(self.xpassed), class_='failed'), '.') ] results = [ html.h2('Results'), html.table([ html.thead(html.tr([ html.th('Result', class_='sortable initial-sort result', col='result'), html.th('Test', class_='sortable', col='name'), html.th( 'Duration', class_='sortable numeric', col='duration'), html.th('Links') ]), id='results-table-head'), html.tbody(*self.test_logs, id='results-table-body') ], id='results-table') ] main_js = pkg_resources.resource_string( __name__, os.path.join('resources', 'main.js')) if PY3: main_js = main_js.decode('utf-8') body = html.body( html.script(raw(main_js)), html.p('Report generated on {0} at {1}'.format( generated.strftime('%d-%b-%Y'), generated.strftime('%H:%M:%S')))) if session.config._environment: body.append(html.h2('Environment')) body.append( html.table([ html.tr(html.td(e[0]), html.td(e[1])) for e in sorted(session.config._environment, key=lambda e: e[0]) if e[1] ], id='environment')) body.extend(summary) body.extend(results) doc = html.html(head, body) logfile.write('<!DOCTYPE html>') unicode_doc = doc.unicode(indent=2) if PY3: # Fix encoding issues, e.g. with surrogates unicode_doc = unicode_doc.encode('utf-8', errors='xmlcharrefreplace') unicode_doc = unicode_doc.decode('utf-8') logfile.write(unicode_doc) logfile.close()
def pytest_sessionfinish(self): if not os.path.exists(os.path.dirname(self.logfile)): os.makedirs(os.path.dirname(self.logfile)) logfile = open(self.logfile, "w", encoding="utf-8") suite_stop_time = time.time() suite_time_delta = suite_stop_time - self.suite_start_time numtests = self.passed + self.failed + self.xpassed + self.xfailed generated = datetime.datetime.now() style_css = pkg_resources.resource_string(__name__, os.path.join("resources", "style.css")) if PY3: style_css = style_css.decode("utf-8") head = html.head(html.meta(charset="utf-8"), html.title("Test Report"), html.style(raw(style_css))) summary = [ html.h2("Summary"), html.p( "%i tests ran in %.2f seconds." % (numtests, suite_time_delta), html.br(), html.span("%i passed" % self.passed, class_="passed"), ", ", html.span("%i skipped" % self.skipped, class_="skipped"), ", ", html.span("%i failed" % self.failed, class_="failed"), ", ", html.span("%i errors" % self.errors, class_="error"), ".", html.br(), html.span("%i expected failures" % self.xfailed, class_="skipped"), ", ", html.span("%i unexpected passes" % self.xpassed, class_="failed"), ".", ), ] self._create_overview() overview = [ html.h2("Overview"), html.table( [ html.thead( html.tr( [ html.th("Test", col="name"), html.th("Setup", col="setup"), html.th("Call", col="call"), html.th("Teardown", col="teardown"), ] ), id="overview-table-head", ), html.tbody(*self.test_overview, id="overview-table-body"), ], id="overview-table", ), ] results = [ html.h2("Results"), html.table( [ html.thead( html.tr( [ html.th("Result", class_="sortable initial-sort result", col="result"), html.th("Test", class_="sortable", col="name"), html.th("Duration", class_="sortable numeric", col="duration"), # html.th('Links') ] ), id="results-table-head", ), html.tbody(*self.test_logs, id="results-table-body"), ], id="results-table", ), ] main_js = pkg_resources.resource_string(__name__, os.path.join("resources", "main.js")) if PY3: main_js = main_js.decode("utf-8") body = html.body( html.script(raw(main_js)), html.p("Report generated on %s at %s" % (generated.strftime("%d-%b-%Y"), generated.strftime("%H:%M:%S"))), ) environment = {} for e in self.environment: for k, v in e.items(): environment[k] = v if environment: body.append(html.h2("Environment")) body.append( html.table( [html.tr(html.td(k), html.td(v)) for k, v in sorted(environment.items()) if v], id="environment" ) ) body.extend(summary) body.extend(overview) body.extend(results) doc = html.html(head, body) logfile.write("<!DOCTYPE html>") logfile.write(doc.unicode(indent=2)) logfile.close()
def html_stat(self, compare_to=None, hidenoise=0): if not compare_to: table = html.table( html.thead( html.tr( [ html.th(x, **{'mochi:format': y, 'align':'left'}) for (x,y) in [('Tests','str'), ('per run','float'), ('per oper.', 'float'), ('overhead', 'float')]]) ),id = "sortable_table") tests = self.tests.items() tests.sort() tbody = html.tbody() for name,t in tests: avg,op_avg,ov_avg = t.stat() tbody.append(html.tr( html.td(name), html.td(avg*1000.0), html.td(op_avg*1000000.0), html.td(ov_avg*1000.0) )) table.append(tbody) table.append(html.tr( 'Average round time %s' % (self.roundtime * 1000.0)) ) return table elif isinstance(compare_to, Benchmark): table = html.table(html.thead( html.tr([ html.th(x, **{'mochi:format': y, 'align':'left'}) for (x,y) in [('Tests','str'), ('per run','float'), ('per oper.', 'float'), ('diff', 'float')]])), id = "sortable_table", class_="datagrid") tests = self.tests.items() tests.sort() compatible = 1 tbody = html.tbody() for name,t in tests: avg,op_avg,ov_avg = t.stat() try: other = compare_to.tests[name] except KeyError: other = None if other and other.version == t.version and \ other.operations == t.operations: avg1,op_avg1,ov_avg1 = other.stat() qop_avg = (op_avg/op_avg1-1.0)*100.0 if hidenoise and abs(qop_avg) < 10: qop_avg = '' else: qop_avg = '%+7.2f%%' % qop_avg else: qavg,qop_avg = 'n/a', 'n/a' compatible = 0 tbody.append(html.tr( html.td(name), html.td(avg*1000.0), html.td(op_avg*1000000.0), html.td(qop_avg) )) if compatible and compare_to.roundtime > 0 and \ compare_to.version == self.version: tbody.append(html.tr( html.td('Average round time'), html.td(self.roundtime * 1000.0), html.td(''), html.td('%+7.2f%%'% (((self.roundtime*self.warp)/ (compare_to.roundtime*compare_to.warp)-1.0)*100.0) ))) else: tbody.append(html.tr( html.td('Average round time'), html.td(self.roundtime * 1000.0))) table.append(tbody) return table else: table = html.table(html.thead( html.tr([ html.th(x, **{'mochi:format': y, 'align':'left'}) for (x,y) in [('Tests','str')]+[('pypy ver','float') for z in compare_to] ])), id = "sortable_table") tests = self.tests.items() tests.sort() compatible = 1 for name,t in tests: avg,op_avg,ov_avg = t.stat() percent = [] for comp_to in compare_to: try: other = comp_to.tests[name] except KeyError: other = None if other and other.version == t.version and \ other.operations == t.operations: avg1,op_avg1,ov_avg1 = other.stat() qop_avg = (op_avg/op_avg1-1.0)*100.0 if hidenoise and abs(qop_avg) < 10: qop_avg = '' else: qop_avg = '%+7.2f%%' % qop_avg else: qavg,qop_avg = 'n/a', 'n/a' compatible = 0 percent.append(qop_avg) table.append(html.tr( html.td(name), [html.td(qop_avg) for qop_avg in percent] )) if compatible and compare_to.roundtime > 0 and \ compare_to.version == self.version: table.append(html.tr( html.td('Average round time'), html.td(self.roundtime * 1000.0), html.td(''), html.td('%+7.2f%%'% (((self.roundtime*self.warp)/ (compare_to.roundtime*compare_to.warp)-1.0)*100.0) ))) else: table.append(html.tr( html.td('Average round time'), html.td(self.roundtime * 1000.0))) return table
def generate_html(self, results_list): def failed_count(results): count = len(results.failures) if hasattr(results, 'unexpectedSuccesses'): count += len(results.unexpectedSuccesses) return count tests = sum([results.testsRun for results in results_list]) failures = sum([failed_count(results) for results in results_list]) skips = sum([len(results.skipped) + len(results.expectedFailures) for results in results_list]) errors = sum([len(results.errors) for results in results_list]) passes = 0 test_time = self.elapsedtime.total_seconds() test_logs = [] def _extract_html(test, text='', result='passed', debug=None): cls_name = test.__class__.__name__ tc_name = unicode(test).split()[0] tc_time = str(test.duration) additional_html = [] links_html = [] if result in ['failure', 'error', 'skipped']: if debug and debug.get('screenshot'): screenshot = 'data:image/png;base64,%s' % debug['screenshot'] additional_html.append( html.div( html.a(html.img(src=screenshot), href=screenshot), class_='screenshot')) for name, content in debug.items(): try: if 'screenshot' in name: links_html.append(html.a(name, href='data:image/png;base64,%s' % content.encode('us-ascii'))) else: # use base64 to avoid that some browser(such as Firefox, Opera) treats '#' as the start of another link if the data URL contains. # use 'charset=utf-8' to show special characters like Chinese. links_html.append(html.a(name, href='data:text/plain;charset=utf-8;base64,%s' % base64.b64encode(content))) links_html.append(' ') except: pass log = html.div(class_=result) for line in text.splitlines(): separator = line.startswith(' ' * 10) if separator: log.append(line[:80]) else: if line.lower().find("error") != -1 or line.lower().find("exception") != -1: log.append(html.span(raw(cgi.escape(line)), class_='error')) else: log.append(raw(cgi.escape(line))) log.append(html.br()) additional_html.append(log) test_logs.append(html.tr([ html.td(result, class_='col-result'), html.td(cls_name, class_='col-class'), html.td(tc_name, class_='col-name'), html.td(tc_time, class_='col-duration'), html.td(links_html, class_='col-links'), html.td(additional_html, class_='debug')], class_=result.lower() + ' results-table-row')) for results in results_list: for test in results.tests_passed: _extract_html(test) passes = passes + 1 for result in results.failures: _extract_html(result[0], text=result[1], result='failure', debug=result[2]) for result in results.errors: _extract_html(result[0], text=result[1], result='error', debug=result[2]) jquery_src = os.path.abspath(os.path.join(os.path.dirname(__file__), 'resources', 'jquery.js')) main_src = os.path.abspath(os.path.join(os.path.dirname(__file__), 'resources', 'main.js')) style_src = os.path.abspath(os.path.join(os.path.dirname(__file__), 'resources', 'style.css')) generated = datetime.datetime.now() doc = html.html( html.head( html.meta(charset='utf-8'), html.title('Test Report'), html.link(rel='stylesheet', href=style_src), html.script(src=jquery_src), html.script(src=main_src)), html.body( html.p('Report generated on %s at %s' % ( generated.strftime('%d-%b-%Y'), generated.strftime('%H:%M:%S'))), html.table( html.h2('Summary'), html.p('%i tests ran. in %i seconds' % (tests, test_time), html.br(), html.span('%i passed' % passes, class_='passed'), ', ', html.span('%i failed' % failures, class_='failed'), ', ', html.span('%i skipped' % skips, class_='skipped'), ', ', html.span('%i error' % errors, class_='error'), html.br()), html.h2('Results'), html.table([html.thead( html.tr([ html.th('Result', class_='sortable', col='result'), html.th('Class', class_='sortable', col='class'), html.th('Test Name', class_='sortable', col='name'), html.th('Duration', class_='sortable numeric', col='duration'), html.th('Links')]), id='results-table-head'), html.tbody(test_logs, id='results-table-body')], id='results-table') ) ) ) return doc.unicode(indent=2)
def generate_html(self, results_list): tests = sum([results.testsRun for results in results_list]) failures = sum([len(results.failures) for results in results_list]) expected_failures = sum( [len(results.expectedFailures) for results in results_list]) skips = sum([len(results.skipped) for results in results_list]) errors = sum([len(results.errors) for results in results_list]) passes = sum([results.passed for results in results_list]) unexpected_passes = sum( [len(results.unexpectedSuccesses) for results in results_list]) test_time = self.elapsedtime.total_seconds() test_logs = [] def _extract_html(test, class_name, duration=0, text='', result='passed', debug=None): cls_name = class_name tc_name = unicode(test) tc_time = duration additional_html = [] debug = debug or {} links_html = [] if result in ['skipped', 'failure', 'expected failure', 'error']: if debug.get('screenshot'): screenshot = 'data:image/png;base64,%s' % debug[ 'screenshot'] additional_html.append( html.div(html.a(html.img(src=screenshot), href="#"), class_='screenshot')) for name, content in debug.items(): try: if 'screenshot' in name: href = '#' else: # use base64 to avoid that some browser (such as Firefox, Opera) # treats '#' as the start of another link if the data URL contains. # use 'charset=utf-8' to show special characters like Chinese. href = 'data:text/plain;charset=utf-8;base64,%s' % base64.b64encode( content) links_html.append( html.a(name.title(), class_=name, href=href, target='_blank')) links_html.append(' ') except: pass log = html.div(class_='log') for line in text.splitlines(): separator = line.startswith(' ' * 10) if separator: log.append(line[:80]) else: if line.lower().find("error") != -1 or line.lower( ).find("exception") != -1: log.append( html.span(raw(cgi.escape(line)), class_='error')) else: log.append(raw(cgi.escape(line))) log.append(html.br()) additional_html.append(log) test_logs.append( html.tr([ html.td(result.title(), class_='col-result'), html.td(cls_name, class_='col-class'), html.td(tc_name, class_='col-name'), html.td(tc_time, class_='col-duration'), html.td(links_html, class_='col-links'), html.td(additional_html, class_='debug') ], class_=result.lower() + ' results-table-row')) for results in results_list: for test in results.tests_passed: _extract_html(test.name, test.test_class) for result in results.skipped: _extract_html(result.name, result.test_class, text='\n'.join(result.output), result='skipped') for result in results.failures: _extract_html(result.name, result.test_class, text='\n'.join(result.output), result='failure', debug=result.debug) for result in results.expectedFailures: _extract_html(result.name, result.test_class, text='\n'.join(result.output), result='expected failure', debug=result.debug) for test in results.unexpectedSuccesses: _extract_html(test.name, test.test_class, result='unexpected pass') for result in results.errors: _extract_html(result.name, result.test_class, text='\n'.join(result.output), result='error', debug=result.debug) generated = datetime.datetime.now() doc = html.html( html.head( html.meta(charset='utf-8'), html.title('Test Report'), html.style(raw( pkg_resources.resource_string( __name__, os.path.sep.join(['resources', 'report', 'style.css']))), type='text/css')), html.body( html.script(raw( pkg_resources.resource_string( __name__, os.path.sep.join(['resources', 'report', 'jquery.js']))), type='text/javascript'), html.script(raw( pkg_resources.resource_string( __name__, os.path.sep.join(['resources', 'report', 'main.js']))), type='text/javascript'), html.p( 'Report generated on %s at %s by %s %s' % (generated.strftime('%d-%b-%Y'), generated.strftime('%H:%M:%S'), __name__, __version__)), html.h2('Summary'), html.p( '%i tests ran in %i seconds.' % (tests, test_time), html.br(), html.span('%i passed' % passes, class_='passed'), ', ', html.span('%i skipped' % skips, class_='skipped'), ', ', html.span('%i failed' % failures, class_='failed'), ', ', html.span('%i errors' % errors, class_='error'), '.', html.br(), html.span('%i expected failures' % expected_failures, class_='expected failure'), ', ', html.span('%i unexpected passes' % unexpected_passes, class_='unexpected pass'), '.'), html.h2('Results'), html.table([ html.thead(html.tr([ html.th('Result', class_='sortable', col='result'), html.th('Class', class_='sortable', col='class'), html.th('Test Name', class_='sortable', col='name'), html.th('Duration', class_='sortable numeric', col='duration'), html.th('Links') ]), id='results-table-head'), html.tbody(test_logs, id='results-table-body') ], id='results-table'))) return doc.unicode(indent=2)
def html_stat(self, compare_to=None, hidenoise=0): if not compare_to: table = html.table(html.thead( html.tr([ html.th(x, **{ 'mochi:format': y, 'align': 'left' }) for (x, y) in [('Tests', 'str'), ( 'per run', 'float'), ('per oper.', 'float'), ('overhead', 'float')] ])), id="sortable_table") tests = self.tests.items() tests.sort() tbody = html.tbody() for name, t in tests: avg, op_avg, ov_avg = t.stat() tbody.append( html.tr(html.td(name), html.td(avg * 1000.0), html.td(op_avg * 1000000.0), html.td(ov_avg * 1000.0))) table.append(tbody) table.append( html.tr('Average round time %s' % (self.roundtime * 1000.0))) return table elif isinstance(compare_to, Benchmark): table = html.table(html.thead( html.tr([ html.th(x, **{ 'mochi:format': y, 'align': 'left' }) for (x, y) in [('Tests', 'str'), ('per run', 'float'), ('per oper.', 'float'), ('diff', 'float')] ])), id="sortable_table", class_="datagrid") tests = self.tests.items() tests.sort() compatible = 1 tbody = html.tbody() for name, t in tests: avg, op_avg, ov_avg = t.stat() try: other = compare_to.tests[name] except KeyError: other = None if other and other.version == t.version and \ other.operations == t.operations: avg1, op_avg1, ov_avg1 = other.stat() qop_avg = (op_avg / op_avg1 - 1.0) * 100.0 if hidenoise and abs(qop_avg) < 10: qop_avg = '' else: qop_avg = '%+7.2f%%' % qop_avg else: qavg, qop_avg = 'n/a', 'n/a' compatible = 0 tbody.append( html.tr(html.td(name), html.td(avg * 1000.0), html.td(op_avg * 1000000.0), html.td(qop_avg))) if compatible and compare_to.roundtime > 0 and \ compare_to.version == self.version: tbody.append( html.tr( html.td('Average round time'), html.td(self.roundtime * 1000.0), html.td(''), html.td( '%+7.2f%%' % (((self.roundtime * self.warp) / (compare_to.roundtime * compare_to.warp) - 1.0) * 100.0)))) else: tbody.append( html.tr(html.td('Average round time'), html.td(self.roundtime * 1000.0))) table.append(tbody) return table else: table = html.table(html.thead( html.tr([ html.th(x, **{ 'mochi:format': y, 'align': 'left' }) for (x, y) in [('Tests', 'str')] + [('pypy ver', 'float') for z in compare_to] ])), id="sortable_table") tests = self.tests.items() tests.sort() compatible = 1 for name, t in tests: avg, op_avg, ov_avg = t.stat() percent = [] for comp_to in compare_to: try: other = comp_to.tests[name] except KeyError: other = None if other and other.version == t.version and \ other.operations == t.operations: avg1, op_avg1, ov_avg1 = other.stat() qop_avg = (op_avg / op_avg1 - 1.0) * 100.0 if hidenoise and abs(qop_avg) < 10: qop_avg = '' else: qop_avg = '%+7.2f%%' % qop_avg else: qavg, qop_avg = 'n/a', 'n/a' compatible = 0 percent.append(qop_avg) table.append( html.tr(html.td(name), [html.td(qop_avg) for qop_avg in percent])) if compatible and compare_to.roundtime > 0 and \ compare_to.version == self.version: table.append( html.tr( html.td('Average round time'), html.td(self.roundtime * 1000.0), html.td(''), html.td( '%+7.2f%%' % (((self.roundtime * self.warp) / (compare_to.roundtime * compare_to.warp) - 1.0) * 100.0)))) else: table.append( html.tr(html.td('Average round time'), html.td(self.roundtime * 1000.0))) return table
def generate_html(self, results_list): tests = sum([results.testsRun for results in results_list]) failures = sum([len(results.failures) for results in results_list]) expected_failures = sum([len(results.expectedFailures) for results in results_list]) skips = sum([len(results.skipped) for results in results_list]) errors = sum([len(results.errors) for results in results_list]) passes = sum([results.passed for results in results_list]) unexpected_passes = sum([len(results.unexpectedSuccesses) for results in results_list]) test_time = self.elapsedtime.total_seconds() test_logs = [] def _extract_html(test, class_name, duration=0, text="", result="passed", debug=None): cls_name = class_name tc_name = unicode(test) tc_time = duration additional_html = [] debug = debug or {} links_html = [] if result in ["skipped", "failure", "expected failure", "error"]: if debug.get("screenshot"): screenshot = "data:image/png;base64,%s" % debug["screenshot"] additional_html.append(html.div(html.a(html.img(src=screenshot), href="#"), class_="screenshot")) for name, content in debug.items(): try: if "screenshot" in name: href = "#" else: # use base64 to avoid that some browser (such as Firefox, Opera) # treats '#' as the start of another link if the data URL contains. # use 'charset=utf-8' to show special characters like Chinese. href = "data:text/plain;charset=utf-8;base64,%s" % base64.b64encode(content) links_html.append(html.a(name.title(), class_=name, href=href, target="_blank")) links_html.append(" ") except: pass log = html.div(class_="log") for line in text.splitlines(): separator = line.startswith(" " * 10) if separator: log.append(line[:80]) else: if line.lower().find("error") != -1 or line.lower().find("exception") != -1: log.append(html.span(raw(cgi.escape(line)), class_="error")) else: log.append(raw(cgi.escape(line))) log.append(html.br()) additional_html.append(log) test_logs.append( html.tr( [ html.td(result.title(), class_="col-result"), html.td(cls_name, class_="col-class"), html.td(tc_name, class_="col-name"), html.td(tc_time, class_="col-duration"), html.td(links_html, class_="col-links"), html.td(additional_html, class_="debug"), ], class_=result.lower() + " results-table-row", ) ) for results in results_list: for test in results.tests_passed: _extract_html(test.name, test.test_class) for result in results.skipped: _extract_html(result.name, result.test_class, text="\n".join(result.output), result="skipped") for result in results.failures: _extract_html( result.name, result.test_class, text="\n".join(result.output), result="failure", debug=result.debug ) for result in results.expectedFailures: _extract_html( result.name, result.test_class, text="\n".join(result.output), result="expected failure", debug=result.debug, ) for test in results.unexpectedSuccesses: _extract_html(test.name, test.test_class, result="unexpected pass") for result in results.errors: _extract_html( result.name, result.test_class, text="\n".join(result.output), result="error", debug=result.debug ) generated = datetime.datetime.now() doc = html.html( html.head( html.meta(charset="utf-8"), html.title("Test Report"), html.style( raw( pkg_resources.resource_string(__name__, os.path.sep.join(["resources", "report", "style.css"])) ), type="text/css", ), ), html.body( html.script( raw( pkg_resources.resource_string(__name__, os.path.sep.join(["resources", "report", "jquery.js"])) ), type="text/javascript", ), html.script( raw(pkg_resources.resource_string(__name__, os.path.sep.join(["resources", "report", "main.js"]))), type="text/javascript", ), html.p( "Report generated on %s at %s by %s %s" % (generated.strftime("%d-%b-%Y"), generated.strftime("%H:%M:%S"), __name__, __version__) ), html.h2("Summary"), html.p( "%i tests ran in %i seconds." % (tests, test_time), html.br(), html.span("%i passed" % passes, class_="passed"), ", ", html.span("%i skipped" % skips, class_="skipped"), ", ", html.span("%i failed" % failures, class_="failed"), ", ", html.span("%i errors" % errors, class_="error"), ".", html.br(), html.span("%i expected failures" % expected_failures, class_="expected failure"), ", ", html.span("%i unexpected passes" % unexpected_passes, class_="unexpected pass"), ".", ), html.h2("Results"), html.table( [ html.thead( html.tr( [ html.th("Result", class_="sortable", col="result"), html.th("Class", class_="sortable", col="class"), html.th("Test Name", class_="sortable", col="name"), html.th("Duration", class_="sortable numeric", col="duration"), html.th("Links"), ] ), id="results-table-head", ), html.tbody(test_logs, id="results-table-body"), ], id="results-table", ), ), ) return doc.unicode(indent=2)
def create_table(self): table = html.table(cellpadding='0', cellspacing='0') tbody = html.tbody() table.append(tbody) return table, tbody