Tutorial

PyTest: Python Testing Framework for Backend Engineers

Published on November 20, 2023

Sr Technical Writer

PyTest: Python Testing Framework for Backend Engineers

Introduction

As a backend engineer or a QA/test Engineer, ensuring the quality and reliability of your code is important. One way to achieve this is by using Python testing frameworks to automate the testing process and identify bugs or issues in your code before the piece of software is released or deployed.

They offer the following benefits:

  • Testing frameworks improve code quality.

  • Automated testing saves time and effort.

  • Code reusability optimises testing efforts and reduces duplication.

  • Python testing frameworks integrate seamlessly with other tools, modules and libraries.

In this step-by-step guide, you will learn how to implement PyTest - one of Python’s most popular Python testing frameworks.

Prerequisites

Before diving into the details of Python testing frameworks, let’s first focus on the prerequisites for implementing PyTest.

  • Python Installation: Please ensure you have Python installed on your system. One can download the latest version of Python from the official Python website.

  • Pip Installation: Pip(package installer for Python) is a tool used to manage packages, libraries and dependencies in Python. It allows us to install and manage Python packages. Make sure you have pip installed on your system.

You can check if pip is installed by running the following command in your command prompt/terminal:

  1. python -m pip --version

or

  1. python3 -m pip --version

You can check out this official Python website to install packages.

What is a Python Testing Framework

Python Testing framework is a set of tools and libraries that provide a structure and guidelines to write and execute tests in Python for Test automation. It makes sure that the code meets the desired quality standards. It is essential and useful for every Backend developer, software engineer, DevOps and QA/Test engineer. A few famous and widely used Python testing frameworks are Pytest, PyUnit, DocTest, Testify, Robot and many more.

Implementing PyTest

Installing PyTest

To get started with PyTest, you need to install it on your system. Open your terminal and run the following command:

  1. pip install pytest

This command will download and install the latest PyTest version and its dependencies.

Writing Test Cases

Now that PyTest is installed let’s start writing basic unit test cases.

Please create a new Python file and name it test_backend.py. This file will define our test cases using PyTest’s syntax.

Note: By default, PyTest will discover and run all the test cases in files with names starting with “test_” or ending with “_test”.The pytest discovery process will recursively scan the current folder and its subfolders for files starting with names either “test_” or ending with “_test”. Tests located in those files are then executed.

  1. import pytest
  2. def test_addition():
  3. assert 3 + 3 == 6
  4. def test_subtraction():
  5. assert 5 - 4 == 1
  6. def test_multiplication():
  7. assert 4 * 4 == 16
  8. def test_division():
  9. assert 10 / 2 == 5

In the above example, we have defined four basic unit test cases as functions: test_addition, test_subtraction, test_multiplication, and test_division. The assert keyword is used when debugging code and lets you test if a certain condition in your code returns True; if not, it will return an AssertionError.

Running Test Cases, Running Specific tests

To run the tests, go to the folder where you saved the test_backend.py file and then execute the below command in your terminal or command prompt:

  1. pytest

Or,

  1. python -m pytest

Output:

Output
test session starts ================================================== platform darwin -- Python 3.9.6, pytest-7.4.3, pluggy-1.3.0 rootdir: ~/Python Testing Frameworks collected 4 items test_backend.py .... ================================================== 4 passed in 0.01s [100%]

When using PyTest, you don’t have to manually run each test case in your file. The tool will automatically find and execute all the defined test cases. If everything goes well and all the assertions are true, you’ll get a nice summary of test results along with the number of passed tests as shown above.

Let’s assume that one of the tests fails then, we would notice the following output:

Output
test session starts ================================================== platform darwin -- Python 3.9.6, pytest-7.4.3, pluggy-1.3.0 rootdir: ~/Python Testing Frameworks collected 4 items test_backend.py ...F ================================================== [100%] FAILURES ================================================== test_division def test_division(): > assert 10 / 2 == 6 E assert (10 / 2) == 6 test_backend.py:13: AssertionError short test summary info ================================================== FAILED test_backend.py::**test_division** - assert (10 / 2) == 6 1 failed, 3 passed in 0.01s

Test Discovery

PyTest provides powerful test discovery capabilities that allow you to organize your test cases in a structured manner. By default, PyTest will discover and run all the test cases in files with names starting with “test_” or ending with “_test”. However, you can customise the test discovery process using various command-line options or by configuring a pytest.ini file.

For example, one can specify a specific directory to search for test modules by running the following command:

  1. pytest tests/

This command will only run the test cases inside the “tests” directory.

Test Fixtures

Test Fixtures in Pytest are amazing components that can be reused to set a fixed baseline for your test cases. They come in handy when you need to create preconditions for your tests and when you want to clean up any resources once your tests are done. PyTest makes it easy to define and use test fixtures elegantly.

To define a test fixture, you need to use the @pytest.fixture decorator. For example, a fixture called db defined below, sets up a database connection and then closes the connection after operating. We can define this fixture as follows:

  1. import pytest
  2. @pytest.fixture
  3. def db():
  4. # Set up the database connection
  5. db = create_db()
  6. yield db
  7. # Clean up the database connection
  8. db.close()

In this example, the yield statement defines the code executed after running the test cases. The yield keyword is used to control the flow of a generator function, which is similar to a return statement used for returning values in Python.

To use a fixture in a test case, you must include it as an argument in the test function.

For example:

  1. def query_test(db):
  2. results = db.query("SELECT * FROM users")
  3. assert len(result) == 12

In this test case, the db fixture will be automatically injected into the query_test() function, allowing you to use it to perform database operations. Fixtures are handy for developers to prepare a specific testing environment, such as database connections, API clients, or mock objects. By using fixtures, developers can ensure that tests are isolated and repeatable.

Test engineers can also use fixtures to prepare the system under test, manage test data, or simulate complex scenarios.

Moreover, fixtures can be utilised to handle resource cleanup after tests, improving test suite reliability and maintainability.

Conclusion

In this tutorial, we learned to implement and use PyTest, one of the most popular and feature-rich Python testing frameworks and provided a step-by-step guide on implementing it in Python.

It is essential to continuously write and update test cases as your codebase evolves. By investing time and effort in testing, you can catch bugs early, improve code quality, and deliver more robust and reliable software.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar

Sr Technical Writer

Sr. Technical Writer@ DigitalOcean | Medium Top Writers(AI & ChatGPT) | 2M+ monthly views & 34K Subscribers | Ex Cloud Consultant @ AMEX | Ex SRE(DevOps) @ NUTANIX

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.