Extract more information from your Python unittests

Hi guys, I know you love to write your unittest with python unittest module since its so easy and fun .
But sometimes we need to have a little more information than usual. This article is for those who want to use the powers of unittest module to get better control. Have more decision variables to play with.


I am going to use the below test script for reference.



import unittest

class TestExample(unittest.TestCase):
    def setUp(self):
        self.name = 'Python'
    def test_title(self):
        self.assertTrue(self.name.istitle(), 'Name not a title')
    def test_string(self):
        self.assertTrue(isinstance(self.name, str), 'self.name variable is not a string')
    def test_capital(self):
        self.assertEqual(self.name, self.name.capitalize(), 'Name not in capital')





Case 1:  Find number of test cases in your test script.



if __name__ == '__main__':
    # Creating a TestSuite object
    test_suite = unittest.TestLoader().loadTestsFromTestCase(TestExample)  
    # Creating a TestResult Object
    test_result = unittest.TextTestRunner(verbosity=2).run(test_suite)
    print test_suite.countTestCases()





   

You can also use the TestResult object to get the same.

   print 'No of test run : ', test_result.testsRun  # Note the value depends on how many tests have been run.


Case 2:  Test passed or failed ? Full and final result.

You might sometimes just want to get a single final result. Whether the test passed or failed.
Change the last line in above program to look like this.


if __name__ == '__main__':
    test_suite = unittest.TestLoader().loadTestsFromTestCase(TestExample)
    test_result = unittest.TextTestRunner(verbosity=2).run(test_suite)
    print "The test was:", test_result.wasSuccessful()


       

Output is a Boolean




test_capital (__main__.TestExample) ... ok
test_string (__main__.TestExample) ... ok
test_title (__main__.TestExample) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.017s

OK
Result is: True


Case 3:  Collect failure and error cases with details


Lets fail some test cases intentionally...change the self.name = 'python' . This will fail 2 tests.

The test_result.failures is a list of tuple. Each tuple has an object, and a trace back.

Lets say we just want names of the failed tests.


if test_result.wasSuccessful():

        pass

    elif test_result.failures:

        print 'These tests failed !'

        for test_case, traceback in test_result.failures:

            print 'Test case:', test_case

            #print 'Traceback info:', traceback


   

Output looks like this. (Note: Showing here only relevant lines of the output):




FAILED (failures=2)
No of test run: 3
These tests failed !
Test case: test_capital (__main__.TestExample)
Test case: test_title (__main__.TestExample)

The Complete code


if __name__ == '__main__':
    test_suite = unittest.TestLoader().loadTestsFromTestCase(TestExample)
    print 'No of test cases in test suite', test_suite.countTestCases()
    test_result = unittest.TextTestRunner().run(test_suite)  # test_result is a TextTestResult instance
   
    if test_result.wasSuccessful():
        pass
    elif test_result.failures or test_result.errors:
        print '%d Test failed!' % len(test_result.failures)
        print '%d Test with errors!' % len(test_result.errors)
        for test_case, traceback in test_result.failures:
            print 'Failed test case name:', str(test_case).split(' ')[0]
            #print traceback

        for test_case, traceback in test_result.errors:
            print 'Test case:', str(test_case).split(' ')[0]
            #print traceback

    if test_result.skipped:
        print "Test cases skipped", test_result.skipped





Final Result:


>>>
No of test cases in test suite 3
F.s
======================================================================
FAIL: test_capital (__main__.TestExample)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\inchowar\Desktop\test_example.py", line 17, in test_capital
    self.assertEqual(self.name, self.name.capitalize(), 'Name not in capital')
AssertionError: Name not in capital

----------------------------------------------------------------------
Ran 3 tests in 0.002s

FAILED (failures=1, skipped=1)
No of test run: 3
1 Test failed!
0 Test with errors!
Failed test case name: test_capital
Test cases skipped [(<__main__.TestExample testMethod=test_title>, 'Example skip')]


Case 4: Get the name of the test running

There might be some situation when you need the name of the test running. (I needed the name so I can use it to create a log file with name of the test case).

self._testMethodName

Example:


import unittest

class TestName(unittest.TestCase):
    def test_1(self):
        print self._testMethodName

    def test_2(self):
        print self._testMethodName

if __name__ == '__main__':
    unittest.main()

Output:


test_1
.test_2
.
----------------------------------------------------------------------
Ran 2 tests in 0.010s

OK
>>> 


Popular posts from this blog

Why should you visit Kashmir sooner?

CNTLM in Office

Rajasthan: The Best backpacking destination in India