The unittest module is part of Python’s standard library and it is very popular when it comes to testing Python code. You need two files (preferably placed in the same directory), one file that contains the code that is tested and another file with the code that tests the code of the first file.

My first file is named `math_operators.py`

and it contains basic functions I am going to test. The second file is named `test_math_operators.py`

and it is going to contain the testing code.

Note:

I am referring to this documentation when writing the tests on this page: https://docs.python.org/3/library/unittest.html#unittest.TestCase.debug.

## Testing Python’s mathematical operators with unittest module

In order to start testing I have created the following basic functions in my `math_operators.py`

file.

```
def addition(a, b):
return a + b
def subtraction(a, b):
return a - b
def multiplication(a, b):
return a * b
def division(a, b):
if b == 0:
raise ValueError("Can't divide by zero!")
return a / b
```

The code is self explanatory with the exception of `division(a, b)`

function which contains an `if`

statement used for the case when `b`

variable is 0.

Now the interesting part, the `test_math_operators.py`

file.

```
import unittest
import math_operators
class TestMathOperators(unittest.TestCase):
def test_addition(self):
result = math_operators.addition(8, 4)
self.assertEqual(result, 12)
if __name__ == '__main__':
unittest.main()
```

First of all we have to import the `unittest`

module. As I said, it is part of the main Python library and it can easily be imported as shown on line one.

On the second line we import the module that we want to test. Since it is in the same directory with our testing file it also can be imported easily.

Next, we have to create some test cases for the functions we want to test. In order to do that we have to create a test `class`

that inherits from `unittest.Testcase`

. This will give our class different testing capabilities within the `TestMathOperators`

class.

The first test is written within the class we have just created. The test is actually a method and its name has to start with `test_`

otherwise it won’t be run. This is a unittest naming convention. The first method is named `test_addition`

and it tests the `addition`

function.

Note:

As any method in a class, a method takes `self`

as the first argument.

Now, within our method, we can write our actual test. I have created a variable named `result`

which actually is the result of the `addition`

function from our `math_operators.py`

module. It is the line `result = math_operators.addition(8, 4)`

.

Since we pass the values of 8 and 4, we expect the result to be 12. The next line of code does exactly that `self.assertEqual(result, 12)`

.

The last part has to do with running the test.

The `if`

statement says that if we run this module directly then run the code within the conditional. That code is `unittest.main()`

, so now we can run this file in the terminal running the command `python3 test_math_operators.py`

.

Without this conditional we would have to run the command `python3 -m unittest test_math_operators.py`

.

This is the terminal output:

```
(PythonTesting) saigon@ddnro:~/Documents/Environments/PythonTesting$ python3 test_math_operators.py
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
(PythonTesting) saigon@ddnro:~/Documents/Environments/PythonTesting$
```

Let’s try to make our test to fail. For that I will just replace the 12 with 13. Since 8 + 4 = 12 not 13, the test should fail. If we run it in the terminal the result is as shown below:

```
(PythonTesting) saigon@ddnro:~/Documents/Environments/PythonTesting$ python3 test_math_operators.py
F
======================================================================
FAIL: test_addition (__main__.TestMathOperators)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_math_operators.py", line 8, in test_addition
self.assertEqual(result, 13)
AssertionError: 12 != 13
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)
(PythonTesting) saigon@ddnro:~/Documents/Environments/PythonTesting$
```

### Shortening the code

We can clearly see that the `result`

repeats on both lines within the testing method `test_addition`

. We can eliminate the first line (`result = math_operators.addition(8, 4)`

) by replacing the `result`

on the second line with the value of the `result`

from the first line. The `test_addition`

now looks like shown below:

```
def test_addition(self):
self.assertEqual(math_operators.addition(8, 4), 12)
```

Running the test now will give you the same positive result.

Now, we have to test some edge cases. For example addition of -3 and 3 should equal 0, or addition of two negative numbers etc.

```
def test_addition(self):
self.assertEqual(math_operators.addition(8, 4), 12)
self.assertEqual(math_operators.addition(-3, 3), 0)
self.assertEqual(math_operators.addition(-3, -3), -6)
```

If we run it in the terminal then the result will be the same “Run 1 test … OK”. You might expect three tests but it is really a single test, the `test_addition`

, but with three assertions.

Note:

The goal of writing tests is not to write as many tests as possible but to write as good tests as possible.

Now we have to test the other three mathematical operations. We will do it the same way we tested the addition function.

```
def test_addition(self):
self.assertEqual(math_operators.addition(8, 4), 12)
self.assertEqual(math_operators.addition(-3, 3), 0)
self.assertEqual(math_operators.addition(-3, -3), -6)
def test_subtraction(self):
self.assertEqual(math_operators.subtraction(8, 4), 4)
self.assertEqual(math_operators.subtraction(-3, 3), -6)
self.assertEqual(math_operators.subtraction(-3, -3), 0)
def test_multiplication(self):
self.assertEqual(math_operators.multiplication(8, 4), 32)
self.assertEqual(math_operators.multiplication(-3, 3), -9)
self.assertEqual(math_operators.multiplication(-3, -3), 9)
self.assertEqual(math_operators.multiplication(3, 0), 0)
def test_division(self):
self.assertEqual(math_operators.division(8, 4), 2)
self.assertEqual(math_operators.division(-3, 3), -1)
self.assertEqual(math_operators.division(-3, -3), 1)
self.assertEqual(math_operators.division(3, 6), 0.5)
with self.assertRaises(ValueError):
math_operators.division(3, 0)
```

Everything should be clear at this stage, except the last two lines of code that checks the `if`

statement within our division function. We have to check if a number is divided by 0 the function raises a `ValueError`

.

This can be done in more than one way but one common way of testing this is by using the context manager. Basically, what the code says is that if 3 is divided by 0 then the `ValueError`

error is raised.