You are on page 1of 17

Day 20

Unit Testing
Think of how you might test the lights on a car.

You would turn on the lights (known as the test step) and go outside the car or ask a
friend to check that the lights are on (known as the test assertion).

Testing multiple components is known as integration testing.

A major challenge with integration testing is when an integration test doesn’t give the
right result.
It’s very hard to diagnose the issue without being able to isolate which part of the
system is failing.

If the lights didn’t turn on, then maybe the bulbs are broken. Is the battery dead? What
about the alternator? Is the car’s computer failing?
A unit test is a smaller test, one that checks that a single component operates in the
right way.
A unit test helps you to isolate what is broken in your application and fix it faster.

To write a unit test for the built-in function sum(), you would check the output of
sum() against a known output.

>>> assert sum([1, 2, 3]) == 6, "Should be 6"


If the result from sum() is incorrect, this will fail with an AssertionError and the
message "Should be 6".
>>> assert sum([1, 1, 1]) == 6, "Should be 6"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: Should be 6
Moving the code to python file
def test_sum(): def test_sum():
assert sum([1, 2, 3]) == 6, "Should be 6" assert sum([1, 2, 3]) == 6, "Should be 6"

if __name__ == "__main__": def test_sum_tuple():


test_sum() assert sum((1, 2, 2)) == 6, "Should be 6"
print("Everything passed")
if __name__ == "__main__":
python test_sum.py test_sum()
Everything passed test_sum_tuple()
print("Everything passed")
$ python test_sum_2.py
Traceback (most recent call last):
File "test_sum_2.py", line 9, in <module>
test_sum_tuple()
File "test_sum_2.py", line 5, in test_sum_tuple
assert sum((1, 2, 2)) == 6, "Should be 6"
AssertionError: Should be 6
TestRunner
The test runner is a special application designed for running tests, checking the
output, and giving you tools for debugging and diagnosing tests and applications.

There are many test runners available for Python.

The one built into the Python standard library is called unittest.

unittest contains both a testing framework and a test runner. unittest has some
important requirements for writing and executing tests.

unittest requires that:


● You put your tests into classes as methods
● You use a series of special assertion methods in the unittest.TestCase class
instead of the built-in assert statement
General Steps for using unittest
1. Import unittest from the standard library
2. Create a class that inherits from the TestCase class
3. Convert the test functions into methods by adding self as the first argument
4. Change the assertions to use the self.assertEqual() method on the TestCase class
5. Change the command-line entry point to call unittest.main()
import unittest

class TestSum(unittest.TestCase):

def test_sum(self):
self.assertEqual(sum([1, 2, 3]), 6, "Should be 6")

def test_sum_tuple(self):
self.assertEqual(sum((1, 2, 2)), 6, "Should be 6")

if __name__ == '__main__':
unittest.main()
output
python test_sum_unittest.py
.F
=================================================================
=====
FAIL: test_sum_tuple (__main__.TestSum)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_sum_unittest.py", line 9, in test_sum_tuple
self.assertEqual(sum((1, 2, 2)), 6, "Should be 6")
AssertionError: Should be 6

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

FAILED (failures=1)
Structure of unittest
OOP concepts supported by unittest framework
● test fixture:
A test fixture is used as a baseline for running tests to ensure that there is a fixed environment in
which tests are run so that results are repeatable.
Examples :
○ creating temporary databases.
○ starting a server process.
● test case:
A test case is a set of conditions which is used to determine whether a system under test works
correctly.
● test suite:
Test suite is a collection of testcases that are used to test a software program to show that it has
some specified set of behaviours by executing the aggregated tests together.
● test runner:
A test runner is a component which set up the execution of tests and provides the outcome to the
user.
Outcomes Possible :

There are three types of possible test outcomes :

● OK – This means that all the tests are passed.


● FAIL – This means that the test did not pass and an AssertionError exception
is raised.
● ERROR – This means that the test raises an exception other than
AssertionError.
# Python code to demonstrate working of unittest # Returns true if the string is stripped and
import unittest # matches the given output.
def test_strip(self):
class TestStringMethods(unittest.TestCase): s = 'afora'
self.assertEqual(s.strip('a'), 'afora')
def setUp(self):
pass # Returns true if the string splits and
matches
# Returns True if the string contains 4 a. # the given output.
def test_strings_a(self): def test_split(self):
self.assertEqual( 'a'*4, 'aaaa') s = 'hello world'
self.assertEqual(s.split(), ['hello',
# Returns True if the string is in upper case. 'world'])
def test_upper(self): with self.assertRaises(TypeError):
self.assertEqual('foo'.upper(), 'FOO') s.split(2)

# Returns TRUE if the string is in uppercase if __name__ == '__main__':


# else returns False. unittest.main()
def test_isupper(self):
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
● assertEqual() – This statement is used to check if the result obtained is
equal to the expected result.
● assertTrue() / assertFalse() – This statement is used to verify if a given
statement is true or false.
● assertRaises() – This statement is used to raise a specific exception.
1. >>> import unittest
2. >>> def modthree(x): #defining the function
3. return x%3
4. >>> class Tests(unittest.TestCase):
5. def test(self): #test method
6. self.assertEqual(modthree(4),1)
7. >>> if __name__=='__main__':
8. unittest.main()
Running Your Tests From PyCharm
If you’re using the PyCharm IDE, you can run unittest or pytest by following these
steps:

1. In the Project tool window, select the tests directory.


2. On the context menu, choose the run command for unittest. For example, choose
Run ‘Unittests in my Tests…’.

This will execute unittest in a test window and give you the results within PyCharm:
Example
class Person:
name = []

def set_name(self, user_name):


self.name.append(user_name)
return len(self.name) - 1

def get_name(self, user_id):


if user_id >= len(self.name):
return 'There is no such user'
else:
return self.name[user_id]

if __name__ == '__main__':
person = Person()
print('User Abbas has been added with id ', person.set_name('Abbas'))
print('User associated with id 0 is ', person.get_name(0))
import unittest

# This is the class we want to test. So, we need to import it


import Person as PersonClass

class Test(unittest.TestCase):
"""
The basic class that inherits unittest.TestCase
"""
person = PersonClass.Person() # instantiate the Person Class
user_id = [] # variable that stores obtained user_id
user_name = [] # variable that stores person name
# test case function to check the Person.set_name function
def test_0_set_name(self):
print("Start set_name test\n")
"""
Any method which starts with ``test_`` will considered as a test case.
"""
for i in range(4):
# initialize a name
name = 'name' + str(i)
# store the name into the list variable
self.user_name.append(name)
# get the user id obtained from the function
user_id = self.person.set_name(name)
# check if the obtained user id is null or not
self.assertIsNotNone(user_id) # null user id will fail the test
# store the user id to the list
self.user_id.append(user_id)
print("user_id length = ", len(self.user_id))
print(self.user_id)
print("user_name length = ", len(self.user_name))
print(self.user_name)
print("\nFinish set_name test\n")
# test case function to check the Person.get_name function
def test_1_get_name(self):
print("\nStart get_name test\n")
"""
Any method that starts with ``test_`` will be considered as a test case.
"""
length = len(self.user_id) # total number of stored user information
print("user_id length = ", length)
print("user_name length = ", len(self.user_name))
for i in range(6):
# if i not exceed total length then verify the returned name
if i < length:
# if the two name not matches it will fail the test case
self.assertEqual(self.user_name[i], self.person.get_name(self.user_id[i]))
else:
print("Testing for get_name no user test")
# if length exceeds then check the 'no such user' type message
self.assertEqual('There is no such user', self.person.get_name(i))
print("\nFinish get_name test\n")

You might also like