Skip to main content

Art of Unittest writing : Auto-generation of unit test cases


How to auto create test cases with minimum coding 

Lets say , you want to run a series of test cases that undergo similar kind of testing  . but you need to generate different test cases for each comparison (or whatever test procedure you are using).

So imagine. We want to test a function. A function that accepts two variables, and an operator for comparison. Here's our test function:

    def _test_func(self, a, b, exp, operator):
        ans = 0
        exec("ans = %d %s %d" % (a, operator, b))
        self.assertEqual(ans, exp)


We want to test above function with various inputs....And...we want each scenario as a test case...You might need it for test report or something...


import unittest
from collections import namedtuple

class TestAuto(unittest.TestCase):
    def setUp(self):
        pass

    def tearDown(self):
        pass

# Adder function to add test case
def _add_test(cls, generator):
    for func, name, doc, a, b, exp, operator in generator():
        test = lambda self, a=a, b=b,  expected=exp, oper=operator, func=func : func(self, a, b, expected, oper)
        test.__name__ = "test_{}".format(name)
        test.__doc__ = doc
        setattr(cls, test.__name__, test)

def _test_generator_normal():
    """Generator function for testing queries"""        


    def _test_func(self, a, b, exp, operator):
        ans = 0
        exec("ans = %d %s %d" % (a, operator, b))
        self.assertEqual(ans, exp)

       
    tr = namedtuple('TestCase', 'name doc a b exp operator')
    test_list = (
        tr(name="sub", doc='Test for sub', a=10, b=20, exp=-10,  operator='-'),
        tr(name="add", doc='Test for add', a=30, b=50, exp=80,  operator='+'),
        tr(name="div", doc='Test for divide', a=10, b=2, exp=5, operator='/')
        )
    for ti in test_list:
        yield _test_func, ti.name, ti.doc, ti.a, ti.b, ti.exp, ti.operator

_add_test(TestAuto, _test_generator_normal)

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


Results:


>>>
test_add (__main__.TestAuto)
Test for add ... ok
test_div (__main__.TestAuto)
Test for divide ... ok
test_sub (__main__.TestAuto)
Test for sub ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.010s

OK

Recently , we (me and my friend Sumant)came up with one more simpler model for the same purpose.


import unittest

def generator(test_class, a, b):
    def test(self):
        self.assertEqual(a, b)
    return test

def add_test_methods(test_class):
    #First element of list is variable "a", then variable "b", then name of test case that will be used as suffix.
    test_list = [[2,3, 'one'], [5,5, 'two'], [0,0, 'three']]
    for case in test_list:
        test = generator(test_class, case[0], case[1])
        setattr(test_class, "test_%s" % case[2], test)
        

class TestAuto(unittest.TestCase):
    def setUp(self):
        print 'Setup'
        pass

    def tearDown(self):
        print 'TearDown'
        pass

_add_test_methods(TestAuto)  # It's better to start with underscore so it is not detected as a test itself

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


RESULT:



>>>
Setup
FTearDown
Setup
TearDown
.Setup
TearDown
.
======================================================================
FAIL: test_one (__main__.TestAuto)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:/inchowar/Desktop/PyTrash/test_auto_3.py", line 5, in test
    self.assertEqual(a, b)
AssertionError: 2 != 3

----------------------------------------------------------------------
Ran 3 tests in 0.019s

FAILED (failures=1)

In case , you want to be extra cautious, you can use the decorator @nottest to indicate that the function is not a test method.

"from nose.tools import notttest"

Popular posts from this blog

Why should you visit Kashmir sooner?

"If there is paradise on Earth, this is it"
And paradise it was . Early winter is the perfect time to plan for a visit to Kashmir. We will suggest to keep your itinerary  short . And enjoy the best trip of your life. 

   My Visit Month : Mid November 2015

As we were flying close to Srinagar, about 20 minutes before landing , all of a sudden , every passenger in the aircraft was on his toes craning theirs necks over the tiny window to catch a glimpse of the above. A fleet of Snow Giants.


   Visit Meena Bazaar in Dal Lake
  You will find a floating village with houses , shops, and hotels on all kinds of boats.


    A night on a House Boat




Take a Shikara ride.Watch the super clear reflection of the mountain. Spot fishes and water birds.



Take a 2 day stay in Pahalgam. Visit Mini Switzerland first day on a horse ride.


Visit Sonemarg. Enjoy the snow.



On your way to Pahalgam, visit apple orchids . Taste all kind of apples. The golden ones are supposed to be the best.



The dark ominous mou…

Kerala : How to plan for a lifetime's experience

I have been planning this for months and it finally came along in the best time. A full stretch Kerala trip with Kanyakumari as an added bonus. I will not tell you what to do, but HOW to do it. How to plan your dream Kerala Trip. 

Caution: Mine was too comprehensive. Needs high energy and will be quite tiring. 

I chose the monsoon theme..I wanted to be in the middle of the action. This is the only place in India which offers monsoon as a tourism opportunity. I was lucky. I expected super heavy rains. Instead. I ended up right in between the rainy season and summer which was Perfect.

Advantages in travelling in mid AugustRainfall almost over.Waterfalls at their fullest.Greenery all over the state.Backwaters, beach sides and rivers all very clean.Abundant coconuts to enjoy.Hotel rates brought down.Less crowd everywhere.Festive Preparation going on.Shopping becomes pocket friendly.Our route map:






Day 1 Day 2 Day 3 Day 4 Day 5 Day 6

CNTLM in Office

If you are facing a proxy problem , CNTLM is a general option everybody considers. But the working of CNTLM is not always guaranteed. I myself get confused every time I need to use it.

What problem are we actually talking about?

While working in offices and restricted environments where firewalls and other invisible barriers stop your requests from going out, you sometimes need a way to temporarily jump over that barrier to get your job done . Example: You might face them while trying to install using pip in command line, trying to clone a personal git repository. 

What is CNTLM exactly?

I think this is best answered by the creator himself. Refer this. You can download it from here. For configuration, you an refer this. There are many uses of CNTLM but I am trying to solve my own problem here. So I will stick to breaking office barriers for now ;) .

Why do I need to use it :
1) Python package installations using PIP
2) Git operations : Cloning and pushing to server.

Here are a set of steps I …