how and why to use them

Introduction

pytest is one of the most popular and powerful testing tools in Python. In addition to its simplicity and expressiveness, it offers a powerful extension mechanism through hooks. In this article, we will look at what hooks are in pytest, how they work, and how they can be used to customize and extend the behavior of your test environment.

What are hooks?

Hooks in pytest are special extension points that allow developers to intervene in various stages of the testing process. They provide an interface for performing additional actions before, after, or during test execution. Hooks are defined as functions prefixed with pytest_.

Basic pytest hooks

1. pytest_configure(config)

This hook is called after the pytest configuration is initialized, but before the tests are run. It allows you to customize the behavior of the test environment.

def pytest_configure(config):
    config.addinivalue_line(
        "markers", "custom_marker: описание вашего маркера"
    )

2. pytest_collection_modifyitems(config, items)

This hook is called after all tests are built but before they are run. It allows you to modify or filter the list of tests.

def pytest_collection_modifyitems(config, items):
    for item in items:
        if "slow" in item.keywords:
            item.add_marker(pytest.mark.skip(reason="Пропускаем медленные тесты"))

3. pytest_runtest_setup(item)

This hook is called before each test is run. It allows you to set up the environment for each test.

def pytest_runtest_setup(item):
    if "need_env" in item.keywords and not os.getenv("MY_ENV_VAR"):
        pytest.skip("Требуется переменная окружения MY_ENV_VAR")

4. pytest_runtest_teardown(item, nextitem)

This hook is called after each test is executed. It is used to clean up the environment after the test.

def pytest_runtest_teardown(item, nextitem):
    if "temp_file" in item.keywords:
        os.remove("/tmp/tempfile")

5. pytest_terminal_summary(terminalreporter, exitstatus)

This hook is called after all tests have completed and is used to add custom data to the final report.

def pytest_terminal_summary(terminalreporter, exitstatus):
    terminalreporter.write_sep("=", "Мой пользовательский отчет")
    terminalreporter.write_line("Все тесты выполнены успешно!")

Examples of using hooks

Example 1: Test execution counter

Let's create a hook that will count the number of tests executed and display this information after testing is completed.

# conftest.py

def pytest_sessionstart(session):
    session.tests_ran = 0

def pytest_runtest_logreport(report):
    if report.when == 'call' and report.passed:
        session.tests_ran += 1

def pytest_terminal_summary(terminalreporter, exitstatus):
    terminalreporter.write_sep("=", f"Количество успешно выполненных тестов: {session.tests_ran}")

Example 2: Conditional skipping of tests

Skip all tests if they are marked with a marker skip_if_no_dband the database is not available.

# conftest.py

def pytest_runtest_setup(item):
    if "skip_if_no_db" in item.keywords and not check_database_connection():
        pytest.skip("База данных недоступна")

Example 3: Adding a custom marker

Let's add a new marker and use it to perform additional actions before tests.

# conftest.py

def pytest_configure(config):
    config.addinivalue_line(
        "markers", "dbtest: тесты, требующие подключения к базе данных"
    )

def pytest_runtest_setup(item):
    if "dbtest" in item.keywords:
        setup_database()

Pytest hooks provide powerful capabilities for customizing and extending the testing process. Using hooks, you can customize how tests are collected, the environment is prepared, tests are executed, and results are processed. This makes pytest an incredibly flexible and extensible tool for testing automation.

By using hooks in practice, you can create a more manageable, repeatable, and efficient testing environment tailored to your specific requirements and conditions.

I hope this article has helped you better understand how to work with hooks in pytest and how they can help you write more efficient and flexible tests. Happy testing!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *