diff --git a/HTMLTestRunner.py b/HTMLTestRunner.py index 8d60600..d355c32 100644 --- a/HTMLTestRunner.py +++ b/HTMLTestRunner.py @@ -65,15 +65,12 @@ # URL: http://tungwaiyip.info/software/HTMLTestRunner.html __author__ = "Wai Yip Tung" -__version__ = "0.8.3" +__version__ = "0.8.2" """ Change History -Version 0.8.3 -* Prevent crash on class or module-level exceptions (Darren Wurf). - Version 0.8.2 * Show output inline instead of popup window (Viorel Lupu). @@ -92,14 +89,15 @@ # TODO: color stderr # TODO: simplify javascript using ,ore than 1 class in the class attribute? - +from selenium import webdriver import datetime import StringIO import sys import time import unittest from xml.sax import saxutils - +#make the necessary imports if required, in case of any config file or any +#other data required to display in the report # ------------------------------------------------------------------------ # The redirectors below are used to capture output during testing. Output @@ -112,23 +110,15 @@ # >>> logging.basicConfig(stream=HTMLTestRunner.stdout_redirector) # >>> -def to_unicode(s): - try: - return unicode(s) - except UnicodeDecodeError: - # s is non ascii byte string - return s.decode('unicode_escape') - class OutputRedirector(object): """ Wrapper to redirect stdout or stderr """ def __init__(self, fp): self.fp = fp def write(self, s): - self.fp.write(to_unicode(s)) + self.fp.write(s) def writelines(self, lines): - lines = map(to_unicode, lines) self.fp.writelines(lines) def flush(self): @@ -183,12 +173,12 @@ class Template_mixin(object): """ STATUS = { - 0: 'pass', - 1: 'fail', - 2: 'error', + 0: 'PASS', + 1: 'FAIL', + 2: 'ERROR', } - DEFAULT_TITLE = 'Unit Test Report' + DEFAULT_TITLE = "Test Report" DEFAULT_DESCRIPTION = '' # ------------------------------------------------------------------------ @@ -216,17 +206,25 @@ class Template_mixin(object): if (id.substr(0,2) == 'ft') { if (level < 1) { tr.className = 'hiddenRow'; + tr.nextElementSibling.className = 'hiddenRow' } else { tr.className = ''; + tr.nextElementSibling.className = ''; + tr.nextElementSibling.getElementsByTagName("div")[0].style.display = 'none'; + } } if (id.substr(0,2) == 'pt') { if (level > 1) { tr.className = ''; + tr.nextElementSibling.className = ''; + tr.nextElementSibling.getElementsByTagName("div")[0].style.display = 'none'; } else { tr.className = 'hiddenRow'; + tr.nextElementSibling.className = 'hiddenRow'; + } } } @@ -257,6 +255,7 @@ class Template_mixin(object): } else { document.getElementById(tid).className = ''; + document.getElementById(tid).nextElementSibling.className = ''; } } } @@ -290,7 +289,8 @@ class Template_mixin(object): "resizable,scrollbars,status,width=800,height=450"); d = w.document; d.write("
");
-    d.write(html_escape(output_list[id]));
+  //  d.write(html_escape(output_list[id]));
+    d.write(output_list[id]);
     d.write("\n");
     d.write("close\n");
     d.write("
\n"); @@ -317,25 +317,28 @@ class Template_mixin(object): STYLESHEET_TMPL = """ """ @@ -409,13 +538,22 @@ class Template_mixin(object): HEADING_TMPL = """

%(title)s

-%(parameters)s + +
+ +
+
""" # variables: (title, parameters, description) - HEADING_ATTRIBUTE_TMPL = """

%(name)s: %(value)s

+ HEADING_ATTRIBUTE_TMPL = """ +
  • %(name)s: %(value)s
  • + """ # variables: (name, value) @@ -425,14 +563,15 @@ class Template_mixin(object): # REPORT_TMPL = """ -

    Show +

    +

    Summary Failed All

    -+@@ -472,27 +611,36 @@ class Template_mixin(object): REPORT_TEST_WITH_OUTPUT_TMPL = r""" - + + + + + + + - + + """ # variables: (tid, Class, style, desc, status) @@ -505,9 +653,9 @@ class Template_mixin(object): REPORT_TEST_OUTPUT_TMPL = r""" -%(id)s: %(output)s +%(output)s """ # variables: (id, output) - +#%(id)s %(output)s # ------------------------------------------------------------------------ @@ -527,7 +675,6 @@ class _TestResult(TestResult): def __init__(self, verbosity=1): TestResult.__init__(self) - self.outputBuffer = StringIO.StringIO() self.stdout0 = None self.stderr0 = None self.success_count = 0 @@ -548,6 +695,7 @@ def __init__(self, verbosity=1): def startTest(self, test): TestResult.startTest(self, test) # just one buffer for both stdout and stderr + self.outputBuffer = StringIO.StringIO() stdout_redirector.fp = self.outputBuffer stderr_redirector.fp = self.outputBuffer self.stdout0 = sys.stdout @@ -639,7 +787,7 @@ def run(self, test): test(result) self.stopTime = datetime.datetime.now() self.generateReport(test, result) - print >>sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime) + print >>sys.stderr, '\n Time Elapsed for Running Test Cases: %s' % (self.stopTime-self.startTime) return result @@ -666,9 +814,19 @@ def getReportAttributes(self, result): startTime = str(self.startTime)[:19] duration = str(self.stopTime - self.startTime) status = [] - if result.success_count: status.append('Pass %s' % result.success_count) - if result.failure_count: status.append('Failure %s' % result.failure_count) - if result.error_count: status.append('Error %s' % result.error_count ) + #In order to specify the URL and browser in the test report, use a config file to set the following parameters. + ''' + sample code: + url = config.get("set_url",'url') + + try: + browser= config.get("set_path_to_chromedriver",'browser') + except NoSectionError: + browser= "Firefox" + ''' + if result.success_count: status.append('PASS %s' % result.success_count) + if result.failure_count: status.append('FAILURE %s' % result.failure_count) + if result.error_count: status.append('ERROR %s' % result.error_count ) if status: status = ' '.join(status) else: @@ -677,6 +835,13 @@ def getReportAttributes(self, result): ('Start Time', startTime), ('Duration', duration), ('Status', status), + ''' + sample code continued implementation: + + # ('URL', url), + # ('Browser', browser), + ''' + #or you may alaso hardcode the URL and browser name here itself in place of using a config file ] @@ -735,8 +900,8 @@ def _generate_report(self, result): else: name = "%s.%s" % (cls.__module__, cls.__name__) doc = cls.__doc__ and cls.__doc__.split("\n")[0] or "" - desc = doc and '%s: %s' % (name, doc) or name - + desc = doc and '%s %s' % (name, doc) or name + desc = "Tests" row = self.REPORT_CLASS_TMPL % dict( style = ne > 0 and 'errorClass' or nf > 0 and 'failClass' or 'passClass', desc = desc, @@ -764,10 +929,26 @@ def _generate_report(self, result): def _generate_report_test(self, rows, cid, tid, n, t, o, e): # e.g. 'pt1.1', 'ft1.1', etc has_output = bool(o or e) + #tid = '#' tid = (n == 0 and 'p' or 'f') + 't%s.%s' % (cid+1,tid+1) + name = t.id().split('.')[-1] doc = t.shortDescription() or "" - desc = doc and ('%s: %s' % (name, doc)) or name + desc = doc and ('%s %s' % (name, doc)) or name + +#if you want to add the description to your test case in place of a dynamic test name, +#you can simply use the following code, +#may be link to a dictionary or add the test desrciptiton here itself to the code + +''' +Sample code: + if desc == 'test_testcase1': #where test_testcase1 is the dynamic test case name + desc = test_cases['testcase1'] #where test_cases is a dictionary with description of each test case included in the test suite + else desc == 'test_testcase2: + desc = "To verify that..... " #OR you can hard code the test description in the library file itself in place of linking to a dictionary + +''' + tmpl = has_output and self.REPORT_TEST_WITH_OUTPUT_TMPL or self.REPORT_TEST_NO_OUTPUT_TMPL # o and e should be byte string because they are collected from stdout and stderr? @@ -786,13 +967,14 @@ def _generate_report_test(self, rows, cid, tid, n, t, o, e): script = self.REPORT_TEST_OUTPUT_TMPL % dict( id = tid, - output = saxutils.escape(uo+ue), + #output = saxutils.escape(uo+ue), + output = uo+ue, ) row = tmpl % dict( tid = tid, Class = (n == 0 and 'hiddenRow' or 'none'), - style = n == 2 and 'errorCase' or (n == 1 and 'failCase' or 'none'), + style = n == 2 and 'errorCase' or (n == 1 and 'failCase' or 'passCase'), desc = desc, script = script, status = self.STATUS[n], diff --git a/README b/README index b1beea9..62ad961 100644 --- a/README +++ b/README @@ -3,3 +3,12 @@ It generates easy to use HTML test reports. HTMLTestRunner is released under a BSD style license. Only a single file module HTMLTestRunner.py is needed to generate your report. + +Additions: +Changed CSS +One can add description to the test cases by following the sample code +mentioned in the HTMLTestRunner.py module itself. +Read the comments carefully in order to generate detailed reports. + +View the sample report in sample_report.png + diff --git a/sample_report.png b/sample_report.png new file mode 100644 index 0000000..a2d2889 Binary files /dev/null and b/sample_report.png differ
    %(desc)s
    %(status)s + -
    + - +