• Home
  • LLMs
  • Python
  • Docker
  • Kubernetes
  • Java
  • Maven
  • All
  • About
Python | Unit Testing
pytest is one of the most popular testing frameworks in Python. It makes writing and running tests simple and efficient.

See the official documentation for more details: https://docs.pytest.org/en/stable/index.html

Installing pytest:
To install pytest for the current user:
$ python3 -m pip install --user pytest
Alternatively, to install it globally on Ubuntu:
$ sudo apt install python3-pytest
To verify the installation:
$ pytest --version
Output:
pytest 7.4.4
pytest.ini:
The pytest.ini file is used to configure pytest behavior. It takes precedence, even when empty, over other config files. You may also use a hidden version named .pytest.ini.

Create a pytest.ini file in your project's root directory:
$ vi pytest.ini
[pytest]
minversion = 6.0
addopts = -ra -q
testpaths =
  tests
  integration
Assertions:
Assertions are used to validate conditions in unit tests.

  • Basic assertions:
    assert output                              # Assert that 'output' is truthy (i.e., evaluates to True)
    assert not output                          # Assert that 'output' is falsy (i.e., evaluates to False)
    assert output == value                     # Assert that 'output' is equal to 'value' (assert equality)
    assert output != value                     # Assert that 'output' is not equal to 'value' (assert inequality)
    assert output is None                      # Assert that 'output' is None
    assert output is not None                  # Assert that 'output' is not None
  • Collection assertions:
    assert item in collection                  # Assert that 'item' is in the 'collection' (assert membership)
    assert item not in collection              # Assert that 'item' is not in the 'collection' (assert non membership)
    assert len(collection) == value            # Assert that the length of the 'collection' is equal to 'value' (assert collection length)
    assert all(collection)                     # Assert that all items in the 'collection' are truthy
    assert any(collection)                     # Assert that at least one item in the 'collection' is truthy
  • Numeric assertions:
    assert output > value                      # Assert that 'output' is greater than 'value'
    assert output >= value                     # Assert that 'output' is greater than or equal to 'value'
    assert output < value                      # Assert that 'output' is less than 'value'
    assert output <= value                     # Assert that 'output' is less than or equal to 'value'
    assert abs(output - value) < 0.001         # Assert that 'output' is approximately equal to 'value' (floating-point comparison)
  • Type assertions:
    assert isinstance(output, specific_type)   # Assert that 'output' is of type 'specific_type' (i.e., str)
    assert hasattr(obj, 'method_name')         # Assert that 'obj' has the attribute 'method_name'
  • Exception assertions:
    with pytest.raises(ValueError):
        function_that_should_raise_value_error()
    
    with pytest.raises(ValueError, match="invalid input"):
        function_with_specific_error_message()
Simple unit test:
  • Create a file hello.py that contains a simple function 'hello':
    $ vi hello.py
    def hello(name):
      if not isinstance(name, str):
        raise TypeError("Arguments must be strings")
      elif name == '':
        raise ValueError("Arguments cannot be empty")
      else:
        return name
  • Create a unit test file test_hello.py:
    $ vi test_hello.py
    import pytest
    from hello import hello
    
    def test_hello():
      """hello unit test"""
      with pytest.raises(TypeError, match="Arguments must be strings"):
        hello(123)
    
      with pytest.raises(ValueError):
        hello('')
    
      output = hello('abc')
      assert output == 'abc'
  • To execute the unit test, open a terminal and run 'pytest' command from the project folder:
    $ pytest
    Output:
    ================================================================================ test session starts ================================================================================
    platform linux -- Python 3.12.3, pytest-7.4.4, pluggy-1.4.0
    rootdir: ~/dev/python/my_project
    collected 1 item
    
    test_hello.py .                                                                                                                                                               [100%]
    
    ================================================================================= 1 passed in 0.01s =================================================================================
  • If the test encounters a failed assertion or an unexpected exception, pytest will report the test as failed or errored.

    Here's an example of a unit test that will fail:
    import pytest
    from hello import hello
    
    def test_hello():
      """hello unit test"""
      with pytest.raises(ValueError, match="Arguments must be strings"):
        hello(123)
    
      with pytest.raises(TypeError, match="Arguments should be strings"):
        hello(123)
    
      with pytest.raises(TypeError):
        hello('')
    
      output = hello('abc')
      assert output == 'xyz'
    Running pytest on this test will produce the following errors:
    >       raise TypeError("Arguments must be strings")
    E       TypeError: Arguments must be strings
    >     with pytest.raises(TypeError, match="Arguments should be strings"):
    E     AssertionError: Regex pattern did not match.
    E      Regex: 'Arguments should be strings'
    E      Input: 'Arguments must be strings'
    >       raise ValueError("Arguments cannot be empty")
    E       ValueError: Arguments cannot be empty
    >     assert output == 'xyz'
    E     AssertionError: assert 'abc' == 'xyz'
    E       - xyz
    E       + abc
Using Fixtures:
Fixtures (@pytest.fixture) in pytest provide a flexible way to set up test data, create and inject mock objects into unit tests, and establish reusable test environments across multiple test functions.

  • Create a file addition.py that contains a simple class 'Addition':
    $ vi addition.py
    class Addition:
      def __init__(self, i, j):
        self.i = i
        self.j = j
    
      def add(self):
        return self.i + self.j
  • Create a unit test file test_addition.py:
    $ vi test_addition.py
    import pytest
    from addition import Addition
    
    @pytest.fixture
    def addition():
      addition = Addition(4, 6)
      return addition
    
    def test_add(addition):
      """add unit test"""
      output = addition.add()
      assert output == 10
  • To execute the unit test, open a terminal and run 'pytest' command from the project folder:
    $ pytest
    ================================================================================ test session starts ================================================================================
    platform linux -- Python 3.12.3, pytest-7.4.4, pluggy-1.4.0
    rootdir: ~/dev/python/my_project
    collected 1 item
    
    test_addition.py .                                                                                                                                                            [100%]
    
    ================================================================================= 1 passed in 0.01s =================================================================================
Fixture Scopes:
Fixtures can have different scopes to optimize test execution.

  • Fixtures recreated for each test (default):
    @pytest.fixture(scope="function")
    def addition():
      addition = Addition(4, 6)
      return addition
  • Fixtures shared across all tests in a class:
    @pytest.fixture(scope="class")
    def addition():
      addition = Addition(4, 6)
      return addition
  • Fixtures shared across all tests in a module:
    @pytest.fixture(scope="module")
    def addition():
      addition = Addition(4, 6)
      return addition
  • Fixtures shared across entire test session:
    @pytest.fixture(scope="session")
    def addition():
      addition = Addition(4, 6)
      return addition
© 2025  mtitek