Understanding Unit Testing In Python Part I
Amateur programmers who are learning to code clean and beautifully, need to understand the importance of unit testing their functions before deploying them.
If you are new to programming and are barely starting out then obviously you are asking, what are unit tests anyway? Testing in general is simple, it is some code that ensures your program works the way it is supposed to. And testing is done in different phases in developing. Usually the first phase is unit testing and we’ll take a look into it in this with some examples in this post.
As the name implies, unit testing is where we test the working of basic components in our program. So lets assume we have a file myProgramfile.py and it has a function defined as follows
def addNumbers(A,B):
return A+B
You could test it by running it with any couple numbers and be sure that it would work for any set of numbers. But consider a function that could do different things based on the parameters like this
def operateNumbers(A,B,Select):
if (Select == "Add"):
return A+B
elif (Select == "Subtract"):
return A-B
elif (Select == "Multiply"):
return A*B
elif (Select == "Divide"):
return A/B
So in this case based on the Select parameter the output differs and you would have to run the program multiple times to check if the output is correct manually, which is let’s be honest a real pain in the butt.
Let’s try the ‘pain in the butt’ version first. To test operate function I would have to do this
result = operateNumbers(10,-2000,"Add")
print("Result: "result)
Run the script. Go to the output to verify if it says
Result: -1990
And do it over again for subtraction, multiplication and division. Imagine doing this for 1000 line program with much complex functions. Man, that’s tiring. But worry not, python’s unit testing module makes it a piece of cake.
Let’s try doing it the unit testing way. The unit test for operateNumbers looks as simple as this
import unittest
from myProgramFile import operateNumbersclass testMyProgram(unittest.TestCase):
def test_operateNumbers(self):
self.assertEqual(operateNumbers(10,20,"Add"),30)
self.assertEqual(operateNumbers(10,20,"Subtract"),-10)
self.assertEqual(operateNumbers(10,20,"Multiply"),200)
self.assertEqual(operateNumbers(10,20,"Divide"),0.5)
if __name__ == '__main__':
unittest.main()
All you do is create a class for the unit test and define a test function in the right syntax and use the assertEqual method to check if you get back the desired value. Python’s unit testing has more assert methods like assertTrue, assertFalse, assertIsNone etc, but they are all straightforward, so you really should check out the docs.
Run the script and you will see something like this
.
--------------------------------------------------------------------
Ran 1 test in 0.017sOK
That means your unit (here, out operateNumbers() function) was successfully tested. Let’s say I keep working on my program and I add 2 functions to myProgramFile.py and 2 more test functions in unitTest.py. And by some mistake I change this our first function’s conditional logic to be
def operateNumbers(A,B,Select):
if (Select == "Subtract"): #notice i have changed add to sub
return A+B
elif (Select == "Add"): #and sub to add
return A-B
elif (Select == "Multiply"):
return A*B
elif (Select == "Divide"):
return A/B#the 2 other functions I wrote
Now, I don’t realise I made this change so without a pre-written test I won’t check for the operateNumbers’s working again. But, we have a test code written already! So now when I run my unitTest.py.
.F.====================================================================FAIL: test_operateNumbers (__main__.testMyProgram)--------------------------------------------------------------------Traceback (most recent call last):File "myProgramUnitTest.py", line 5, in test_operateNumbersself.assertEqual(operateNumbers(10,20,"Add"),30)AssertionError: -10 != 30-------------------------------------------------------------------Ran 3 tests in 0.001sFAILED (failures=1)
And viola. We found out about our unintended bug and its location just like that.
You are better off learning to test your code as you start to learn programming. Not only does it save you a ton of time but it will also make your program cleaner, easier to debug and much easier to collaborate with.