In this tutorial are few examples how catch error and how to perform unit tests in Python.
When you code in Python, keep in mind:
Errors should never pass silently. Unless explicitly silenced.
(PEP20 - The Zen of Python)
Following function is designed to sum two variables (numbers - float or integers) together and return this result as float
In [7]:
def sum_together1(a, b):
return a + b
An example of correct use follows.
In [8]:
sum_together1(1., 2)
Out[8]:
Example of incorrect use that finish without error follows.
In [9]:
sum_together1("a", "b")
Out[9]:
Example of incorrect use that results in error follows
In [10]:
sum_together1("a", 1)
As you can see, if the function is used in incorrect way (different then planed) it can or cannot cause an error. If such a function is part of the application, both options are dangerous. Different version of the function above follows. This function allows only variables that are convertable to float.
In [11]:
def sum_together2(a, b):
a = float(a)
b = float(b)
return a + b
In [12]:
sum_together2(1, 2)
Out[12]:
In [13]:
sum_together2("a", "b")
In some cases you cannot allow the applications to crash, but providing of incorrect (predefined) result is ok. Example follows.
In [14]:
def sum_together3(a, b):
try:
a = float(a)
b = float(b)
return a + b
except:
return 0.0
In [15]:
sum_together3(1, 2)
Out[15]:
In [16]:
sum_together3("a", "b")
Out[16]:
In practice, you should still report/log this issues somehow, otherwise you will have no information about errors silenced like this.
Unit test is term describing tests for partical code units (functions, classes, blocks). In this tutorial are examples of such a tests. For the design of the tests was used unittest, that is standard Python library. Few simple tests follows. Some test are designed to fail - they are obviously wrong.
In [30]:
import unittest
class Test1(unittest.TestCase):
def test_type_error_number_and_string(self):
with self.assertRaises(TypeError):
1 + "a"
def test_type_error_number_and_number(self): # wrong test!
with self.assertRaises(TypeError):
1 + 1
def test_float_and_int_equality(self):
self.assertEquals(0, 0.0)
def test_equality(self): # this test is wrong!
self.assertEquals(0., 1.)
suite = unittest.TestLoader().loadTestsFromTestCase(Test1)
unittest.TextTestRunner(verbosity=3).run(suite)
Out[30]:
Example of unit tests for functions created before (sum_together1, sum_together2, sum_together3
) follows.
In [43]:
import unittest
class Test2(unittest.TestCase):
def test_nan_sum_together1(self):
"""
Check if it throws error only for unsumable inputs.
"""
# this should pass
sum_together1("a", "b")
# this should fail
with self.assertRaises(TypeError):
sum_together1(1, "b")
def test_nan_sum_together2(self):
"""
Check if it throws error every time.
"""
with self.assertRaises(ValueError):
sum_together2("a", "b")
with self.assertRaises(ValueError):
sum_together2(1, "b")
def test_nan_sum_together3(self):
"""
Check if it provides correct default
"""
self.assertEquals(sum_together3("a", "b"), 0.0)
self.assertEquals(sum_together3(1, "b"), 0.0)
def test_validity_sum_together1(self):
"""
Check if it returns correct values.
"""
self.assertEquals(sum_together1(0, 0), 0.0)
self.assertEquals(sum_together1(1, 0), 1.0)
def test_validity_sum_together2(self):
"""
Check if it returns correct values.
"""
self.assertEquals(sum_together2(0, 0), 0.0)
self.assertEquals(sum_together2(1, 0), 1.0)
def test_validity_sum_together3(self):
"""
Check if it returns correct values.
"""
self.assertEquals(sum_together3(0, 0), 0.0)
self.assertEquals(sum_together3(1, 0), 1.0)
suite = unittest.TestLoader().loadTestsFromTestCase(Test2)
unittest.TextTestRunner(verbosity=3).run(suite)
Out[43]: