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

Почему падают автотесты? Гонки условий в параллельном тестировании с 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) и уникальные данные для каждого теста, чтобы сэкономить время на отладке.