Open In App

Typical directory structure for running tests using unittest in Python

In this article, we will take a look at the typical directory structure for running tests using unittest in Python.

What is the unittest module in Python?

The unittest module is a built-in Python library that is used for testing the functionality of individual units of source code. It is a powerful tool that allows developers to write and run repeatable tests, which can help to ensure that their code is working as intended and that it remains reliable over time.



The unittest module provides several key features, including:

Before we dive into the specifics of the directory structure, it’s important to understand some key concepts related to unittest.



The typical directory structure for running tests

Here is a typical directory structure for organizing tests using unittest in a Python project:

project/
├── package/
│   ├── __init__.py
│   ├── module.py
├── tests/
│   ├── __init__.py
│   ├── test_module.py
├── setup.py

Implementation of running tests using unittest in Python:

Here is an example of a complete working code that we can use to test the unittest module in Python:

We are going to have two different files math_functions.py which contain different mathematical functions and test_math_functions.py which contains tests related to math_functions.py. We are not creating that typical structure because we are taking a simple example of running tests using unittest in Python.

math_functions.py: In this code, we are defining some mathematical functions.




# math_functions.py
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):
    return a / b

test_math_functions.py: In this code we have written our main program to test the function present in math_functions.py




# test_math_functions.py
 
import unittest
from math_functions import *
 
# Define class to test the program
class TestMathFunctions(unittest.TestCase):
    # Function to test addition function
    def test_addition(self):
        result = addition(2, 2)
        self.assertEqual(result, 4)
         
    # Function to test addition function
    def test_subtraction(self):
        result = subtraction(4, 2)
        self.assertEqual(result, 2)
         
   # Function to test addition function
    def test_multiplication(self):
        result = multiplication(2, 3)
        self.assertEqual(result, 6)
         
    # Function to test addition function
    def test_division(self):
        result = division(4, 2)
        self.assertEqual(result, 2)
 
if __name__ == '__main__':
    unittest.main()

Explanation:

  1. Firstly we will import unittest module.
  2. The math_functions module is imported. This module should contain the functions being tested.
  3. A new class called TestMathFunctions is defined. Which is a class that provides a number of assert methods for testing.
  4. Four test methods are defined in the TestMathFunctions class: test_addition, test_subtraction, test_multiplication, and test_division. These methods test the corresponding functions in the math_functions module.
  5. In each test method, the function being tested is called with specific input arguments. The result of the function is then checked using the assertEqual method, which checks that the result is equal to the expected output. If the result is not equal to the expected output, the ‘assertEqual’ method will raise an error, causing the test to fail.
  6. The if __name__ == ‘__main__’: block at the bottom runs the test suite when the script is run. The unittest.main() function is called, which runs the tests in the TestMathFunctions class.

To run this code, first, save the “math_functions.py” file and the “test_math_functions.py” file in the same directory. Then, open a terminal window and navigate to the directory containing these files. Finally, run the following command:

$ Python -m unittest

Output:

The output will typically consist of a series of dots or other symbols, with each symbol representing the execution of a single test case. A dot (.) indicates that the test case passed, while an “F” indicates that the test case failed. If all of the test cases pass, you should see a message indicating that all tests have been run and the total number of tests that were run.

....
----------------------------------------------------------------------
Ran 4 tests in 0.000s

OK

If any of the test cases fail, the output will include a detailed error message indicating what went wrong. Let’s take an example where the test case failed, for that, we have modified the math_functions.py file so that it will return a string which will cause an error as an integer value is expected.




# Program with error in one function
def addition(a, b):
    return "error_causing_format"
 
def subtraction(a, b):
    return a - b
 
def multiplication(a, b):
    return a * b
 
def division(a, b):
    return a / b

Now if we run the “test_math_functions.py” file the same as before then we will get the following error message:

F...
======================================================================
FAIL: test_addition (test_math_functions.TestMathFunctions.test_addition)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\siddh\OneDrive\Desktop\GFG\test_math_functions.py", line 7, in test_addition
    self.assertEqual(result, 4)
AssertionError: 'error' != 4

----------------------------------------------------------------------
Ran 4 tests in 0.002s

FAILED (failures=1)

In the above case, the first test case failed, and hence the output shows FAILED status.

Here are a few additional points to consider when organizing your tests using unittest:


Article Tags :