Road to generate html report for Python Webdriver test suite using HTMLTestRunner

In my previous post ""Road to create test suite for python Webdriver scripts, I posted that how to create Suite file for webdriver python test script, but In this post I will show you how to integrate test suite with HTMLTestRunner to generate report in html format.

Before going through this post click here ( “Road to create test suite for python Webdriver scripts” ) to see both webdrive python unit test scripts.  I am taking these as example.

Follow below steps to setup:
1. Click on link "HTMLTestRunner" and download “HTMLTestRunner.py”, and “test_HTMLTestRunner.py” file put in your webdriver python project root folder.
2. Import all your test script in “test_HTMLTestRunner.py” as below:
import WebdriverTest2
import WebdriverTest1

3. If your test scripts are not parallel to “test _HTMLTestRunner.py” file, like I put under ${rootfolder}/test then use from in import section.
from test import WebdriverTest2
from test import WebdriverTest1

4. Associate your unit test with suite  object in “test_main” method as below:
self.suite = unittest.TestSuite()
        self.suite.addTests([           
            unittest.defaultTestLoader.loadTestsFromTestCase(WebdriverTest1.WebdriverTest1),
            unittest.defaultTestLoader.loadTestsFromTestCase(WebdriverTest2.WebdriverTest2),
                               
            ])

Example: Here is complete example
import StringIO
import sys
import unittest
from test import WebdriverTest2
from test import WebdriverTest1
import HTMLTestRunner

# ----------------------------------------------------------------------

def test_HTMLTestRunner(obj, *args):
    """ return the unicode representation of obj """
    try:
        return unicode(obj, *args)
    except UnicodeDecodeError:
        # obj is byte string
        ascii_text = str(obj).encode('string_escape')
        return unicode(ascii_text)

def safe_str(obj):
    """ return the byte string representation of obj """
    try:
        return str(obj)
    except UnicodeEncodeError:
        # obj is unicode
        return unicode(obj).encode('unicode_escape')

# This is the main test on HTMLTestRunner

class Test_HTMLTestRunner(unittest.TestCase):

    def test_main(self):
        # Run HTMLTestRunner. Verify the HTML report.

        # suite of TestCases
        self.suite = unittest.TestSuite()
        self.suite.addTests([            
            unittest.defaultTestLoader.loadTestsFromTestCase(WebdriverTest1.WebdriverTest1),
            unittest.defaultTestLoader.loadTestsFromTestCase(WebdriverTest2.WebdriverTest2),
                                
            ])

        # Invoke TestRunner
        buf = StringIO.StringIO()
        #runner = unittest.TextTestRunner(buf)       
        runner = HTMLTestRunner.HTMLTestRunner(
                    stream=buf,
                    title='',
                    description='This demonstrates the report output by Suite Execution.'
                    )
        runner.run(self.suite)

        # check out the output
        byte_output = buf.getvalue()
        # output the main test output for debugging & demo
        print byte_output
        # HTMLTestRunner pumps UTF-8 output
        output = byte_output.decode('utf-8')
        self._checkoutput(output,EXPECTED)
        EXPECTED = u"""
        """
        # check out the output
        byte_output = buf.getvalue()
        # output the main test output for debugging & demo
        print byte_output
        # HTMLTestRunner pumps UTF-8 output
        output = byte_output.decode('utf-8')
        self._checkoutput(output,EXPECTED)


    def _checkoutput(self,output,EXPECTED):
        i = 0
        for lineno, p in enumerate(EXPECTED.splitlines()):
            if not p:
                continue
            j = output.find(p,i)
            if j < 0:
                self.fail(safe_str('Pattern not found lineno %s: "%s"' % (lineno+1,p)))
            i = j + len(p)
    

import unittest
if __name__ == "__main__":
    if len(sys.argv) > 1:
        argv = sys.argv
    else:
        argv=['test_HTMLTestRunner.py', 'Test_HTMLTestRunner']
    unittest.main(argv=argv)

Execution: Run “test_HTMLTestRunner.py” using command, you should see report is generated in result.html file.
    >>python test_HTMLTestRunner.py > result.html 

Report: you should see report like this:

12 comments:

  1. Hi,

    If we have multiple test cases divided in multiple classes for eg. 100 . Then how are we going to get the HTMLTest Report using htmltestrunner in selenium using python.

    Thanks,
    Bittu Philip

    ReplyDelete
    Replies
    1. You can add all class file on runner "Test_HTMLTestRunner" similar I have added two class files

      Delete
    2. Hi Admin,

      If we are executing the script for 500/100 testcases , it will be too lengthy and difficult to maintain because everytime we need to import the class and add the the class in the testsuite.

      Is there any way we can loop through the classes and get the class name and then use that classname in the HTMLTest Runner test suite to generate the report?

      Thanks,

      Delete
  2. I've copied the test runner script as it is and ran it and i"m getting following error:
    .E
    Time Elapsed: 0:00:56.652000
    E
    ======================================================================
    ERROR: test_main (__main__.Test_HTMLTestRunner)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
    File "TestRunner.py", line 61, in test_main
    self._checkoutput(output,EXPECTED)
    UnboundLocalError: local variable 'EXPECTED' referenced before assignment

    ----------------------------------------------------------------------
    Ran 1 test in 56.652s

    FAILED (errors=1)

    Still script is able to generate the html report. So I moved the variable assignment before _checkoutput() function call so now it is not giving the error but in html report, it is creating report two times. Really great if you are able to assist in this

    ReplyDelete
    Replies
    1. You should clean report file before generating running test suite

      Delete
    2. This comment has been removed by the author.

      Delete
  3. Hi,
    While i am running the same for my script(which is in Python 3.4) its throwing an error:
    Traceback (most recent call last):
    File "test_HTMLTestRunner.py", line 3, in
    import StringIO
    ImportError: No module named 'StringIO'
    please help to fix this issue.

    ReplyDelete
  4. Hello Sumit,

    If you are using Python 3.x then please use the below link
    http://stackoverflow.com/questions/30954381/python-htmltestrunner-not-generating-report

    In this page you can find the code for HTMLTestRunner.py that works with Python 3.x

    ReplyDelete
  5. It’s really a nice and helpful piece of info. I’m happy that you shared this helpful information with us. Please keep us up to date like this. Thanks for sharing.
    Home automation Hamilton

    ReplyDelete
  6. I dont want to do manually all time the python test_HTMLTestRunner.py > result.html in cmd after running the py file ? what can change in code

    ReplyDelete
  7. i am facing this issue

    from test import WebdriverTest2
    ImportError: cannot import name WebdriverTest2

    ReplyDelete
  8. I am getting
    Traceback (most recent call last):
    File "test_HTMLTestRunner.py", line 253, in test_main
    self._checkoutput(output,EXPECTED)
    File "test_HTMLTestRunner.py", line 264, in _checkoutput
    self.fail(safe_str(lineno+1))
    AssertionError: 4

    ----------------------------------------------------------------------
    Ran 2 tests in 0.001s

    ReplyDelete

Leave your comments, queries, suggestion I will try to provide solution