Open In App

Getting Started With Unit Testing in Python

Last Updated : 18 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In Python, unit tests are the segments of codes that are written to test other modules and files that we refer to as a unit. Python Unit Testing is a very important part of the software development process that helps us to ensure that the code works properly without any errors. In this article, we will learn about testing in Python with the help of examples and proper explanations.

What is Python Unit Testing?

Python Unit testing is a software testing technique where individual units or components of a software application are tested in isolation from the rest of the system. The primary goal of Python unit testing is checking the validation that each unit of the software performs as designed, according to its specifications. Each unit test looks at a small part of the code, making sure it works even when things get a little tricky.

By testing each piece alone, programmers can find and fix mistakes early on, just like finding a little hole in a sock before it gets bigger, also developers can identify and fix bugs early in the development cycle, leading to better code quality and more robust software.

The main idea with unit testing is to make sure the code works well and won’t cause problems later on. So, by doing these tests as they’re building the program, developers can make sure it’s strong and won’t break when people use it.

Types of Python Testing Frameworks

Python has two main frameworks to make unit testing easier:

  • Unittest
  • Pytest
  • Nose or nose2
  • Doctest

The Assert Statement

Before diving to the testing framework, Let’s understand the assert statement, It is commonly used in Python unit testing frameworks like unittest and pytest to verify the correctness of code during testing. The assert statement in Python is used to check whether a given condition is true or false. It’s primarily used for debugging and testing purposes to verify assumptions made by the programmer during the development of the code.

Syntax of the assert statement

Here’s the syntax of the assert statement in Python:

assert condition, message
  • condition: The expression to be evaluated. If it evaluates to True, the program continues execution normally. If it evaluates to False, an AssertionError exception is raised.
  • message (optional): An optional message that can be provided to provide additional context when the assertion fails. This message is displayed along with the traceback when an assertion fails.

Implementing Unit Tests | unittest

The unittest is built into the standard Python library used for testing with Python.  import unittest should be the starting line of code for using it. Depends upon the python version, it should differ as later versions of Python supports unittest and earlier versions supported unittest2.

Example:

In this example, a unit test class that checks if the sum of a list of numbers matches an expected value using the unittest framework in Python.

Python3
# import library
import unittest

# create a class
class TestXXXXX(unittest.TestCase):

    # define a function
    def test_xxxxxxx(self):
    
        data = [100, 200, 300]
        result = sum(data)
        self.assertEqual(result, 6000)

# driver code
if __name__ == '__main__':

    unittest.main()

Output:

======================================================================
.F
FAIL: test_xxxxxxx (__main__.TestXXXXX)
----------------------------------------------------------------------
Traceback (most recent call last):
 File "......py", line 8, in test_xxxxxxx
   self.assertEqual(result, 6000)
AssertionError: 600 != 6000
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)

Implementing Unit Tests | Pytest

Pytest is the built-in library provided by Python for testing in Python. It simplifies the process of writing and executing tests. Pytest supports unittest test cases execution. It has benefits like supporting built in assert statement, filtering of test cases, returning from last failing test etc.

We can install Pytest by writing the following command in the command prompt:

pip install pytest

Let’s start with a simple example. Here, we will make a file named as math_functions.py.

Python3
# math_functions.py
def add(x, y):
    return x + y

def subtract(x, y):
    return x - y

Now, we will make another file named as test_math_functions.py. We are making this file to perform testing using pytest using sample inputs.

Python3
# test_math_functions.py
import math_functions

def test_add():
    assert math_functions.add(2, 3) == 5
    assert math_functions.add(-1, 1) == 0
    assert math_functions.add(0, 0) == 0

def test_subtract():
    assert math_functions.subtract(5, 3) == 2
    assert math_functions.subtract(0, 0) == 0
    assert math_functions.subtract(-1, -1) == 0

To run these tests using pytest, navigate to the directory containing these files in your terminal and run:

pytest

Output:

image-(1)

Implementing Unit Tests | Nose

“Nose” is a popular testing framework in Python, primarily used for writing unit tests. Nose is a test runner that extends the capabilities of Python’s built-in unittest module. It provides a simpler syntax for writing tests and offers additional features for test discovery, parallel test execution, and plugin support.

Installing Nose

pip install nose

Now, to perform unit tests using nose, we will make a file named as main.py and write the following test code.

main.py

Python3
def test_addition():
    assert 1 + 1 == 2

def test_subtraction():
    assert 3 - 1 == 2
    

To run this program, we will write the following command:

nosetests main.py

Output:

Screenshot-2024-04-17-164451

Python Unit Testing Using nose

Implementing Unit Tests | Doctest

Doctest Module is used to write tests in the form of interactive Python sessions within docstrings and then automatically run those tests to verify that the code behaves as expected. Doctest Module finds patterns in the docstring that looks like interactive shell commands.

Now, we will create a file named as main.py and we will create a test code using docstring.

main.py

Python3
def add(a, b):
    """
    Function to add two numbers.

    >>> add(2, 3)
    5
    >>> add(-1, 1)
    0
    """
    return a + b

def subtract(a, b):
    """
    Function to subtract two numbers.

    >>> subtract(5, 2)
    3
    >>> subtract(10, 5)
    4
    """
    return a - b

To run the program, write the following command in your terminal in the same directory as main.py file.

python -m doctest main.py

Output:

Screenshot-2024-04-17-165622

Python Unit Testing Using doctest

How to Write Assertions in Python Testing

Assertion is nothing but validating the output against a known response. i.e. in above code, we have passed the list containing 3 values namely 10, 20 and 30, and we know that its multiplication result is 6000. So as a last step in code, we will be writing assertion code and above code comes up with assertEqual and surely it will give the output as 6000 and hence the testcase passes. 

unittest has lots of methods to assert on the values, types, and existence of variables. Below are some of the methods that are commonly used to write assertions.

Method

Description

.assertEqual(a, b)

Checks if a is equal to b, similar to the expression a == b.

.assertTrue(x)

Asserts that the boolean value of x is True, equivalent to bool(x) is True.

.assertIsInstance(a, b)

Asserts that a is an instance of class b, similar to the expression isinstance(a, b).

.assertIsNone(x)

Ensures that x is None, similar to the expression x is None.

.assertFalse(x)

Asserts that the boolean value of x is False, similar to bool(x) is False.

.assertIs(a, b)

Verifies if a is identical to b, akin to the expression a is b.

.assertIn(a, b)

Checks if a is a member of b, akin to the expression a in b.

More Advanced Testing Scenarios

  • Fixture is used which is nothing but the data that is created as an input and reusing them.
  • Parameterization can be followed which is nothing but running the same test several times by passing different values and expecting the same result.
  • Need to cover different scenarios like handling expected failures, writing integration tests, testing in multiple environments etc.

Below example shows how to write test for bad data type:

Python3
import unittest

class TestSumDifferentPatterns(unittest.TestCase):
    def test_list_tuple_values(self):

        # Summation of numbers present
        # in a tuple value
        data = (10*2, 200*2)
        result = sum(data)
        self.assertEqual(result, 600)

    def test_bad_data_type(self):
        data = "alpha value passed instead of numeric"
        
        with self.assertRaises(TypeError):
            result = sum(data)


if __name__ == '__main__':
    unittest.main()

Output:

.F
======================================================================
FAIL: test_list_tuple_values (__main__.TestSumDifferentPatterns)
----------------------------------------------------------------------
Traceback (most recent call last):
 File "......py", line 10, in test_list_tuple_values
   self.assertEqual(result, 600)
AssertionError: 420 != 600
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)

Automating the Execution of Tests

Continuous Integration/Continuous Deployment tools are available. They help to run tests, compile, publish and also deploy into production.
https://travis-ci.com/ is one among them which works well with Python and it is an open source project. Login into the site and create.travis.yml with the below contents:

language: python 
python:
<Include the versions as 2.7 or 3.7 whichever required>

install:
– pip install -r <your requirements file>


script: 
– python -m unittest discover

Above file instructs “Travis CI” to look into this file and for given Python versions, the test cases are getting tested by installing the necessary packages as given in the requirements file and finally run below command to run the test.

 python -m unittest discover 

 Results are on the website against your credential.



Like Article
Suggest improvement
Next
Share your thoughts in the comments

Similar Reads