Почему падают автотесты? Гонки условий в параллельном тестировании с Pytest

18 марта 2025 г.Код на салфетке
Почему падают автотесты? Гонки условий в параллельном тестировании с Pytest | 🔁 Новости из телеграм - Ghostbase News

Почему падают автотесты? Гонки условий в параллельном тестировании с Pytest

Гонки условий (race condition) – это когда два теста одновременно лезут к одному ресурсу (файлу, базе данных, сети), и результат зависит от того, кто успеет первым. Эта проблема общая не только в написании кода, но и в его тестировании. В Python с Pytest это частая причина сбоев при параллельном запуске тестов (флаг -n).

Представьте, что два теста пишут в один файл test.txt. Один записал "Hello", другой – "World", а в итоге там каша, и тесты падают. Или оба обновляют одну запись в базе, и данные конфликтуют.

Как чинить race condition в автотестах?

Изоляция: Дайте каждому тесту свои ресурсы. Для файлов – фикстура tmp_path:

def test_write_file(tmp_path):

file = tmp_path / "test.txt"

file.write_text("Hello")

assert file.read_text() == "Hello"

Моки: Заменяйте внешние сервисы заглушками. Запросы к реальным API при тестировании могут приводить к гонке условий – решение в моках:

@patch('requests.get')

def test_api_call(mock_get):

mock_get.return_value.status_code = 200

mock_get.return_value.json.return_value = {'data': 'test'}

# Тестируем код, использующий requests.get

Базы данных: Используйте уникальные данные или транзакции для каждого теста:

def test_db_operation(db_session):

# Используем уникальный идентификатор для каждого теста

unique_id = uuid.uuid4().hex

test_user = User(name=f"user_{unique_id}")

db_session.add(test_user)

db_session.commit()

При этом глобальные переменные в параллельных тестах (pytest -n) безопасны, ведь память у процессов своя.

Это базовые меры, чтобы помочь сделать тесты более надежными и менее подверженными race conditions. Изолируйте тесты, используйте моки (и monkey patching) и уникальные данные для каждого теста, чтобы сэкономить время на отладке.