Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое парадокс пестицида?
Парадокс пестицида — это явление в тестировании, когда повторное использование одних и тех же тест-кейсов перестаёт находить новые баги. Баги остаются, но тесты их не ловят, потому что код был изменён под уже известные проблемы.
Суть проблемы
Представь фермера, который опрыскивает поле одним и тем же пестицидом. Сначала пестицид уничтожает насекомых. Но через время насекомые приспосабливаются. Фермер продолжает опрыскивать, но пестицид уже не работает. Так же и с тестами.
Аналогия:
- Пестицид = Тесты
- Насекомые = Баги
- Сопротивляемость = Код адаптируется к известным тест-кейсам
Как это происходит
Этап 1: Новые тесты, находят баги
Пишу тест для валидации email:
def test_email_validation():
assert is_valid_email("user@example.com") == True
assert is_valid_email("invalid-email") == False
Разработчик видит падающий тест, исправляет баг.
Этап 2: Тот же тест, баги уже найдены
Пишу новую фичу, но не добавляю новые тест-кейсы. Запускаю старые тесты — все зелёные.
Но я не тестирую:
- Email с 40 символами в локальной части
- Идентификаторы email+tag
- Кириллицу в домене
- Новую логику разработчика
Этап 3: Баги остаются незамеченными
Код изменился под старые тест-кейсы, но новые сценарии не покрыты. Баги находят пользователи.
Реальный пример
Старые тесты:
class TestUserCreation:
def test_create_user_with_valid_name(self):
user = create_user("John", "john@example.com", 25)
assert user.name == "John"
def test_create_user_with_short_name(self):
with pytest.raises(ValidationError):
create_user("J", "j@example.com", 25)
Новая логика разработчика:
def create_user(name, email, age):
if len(name) < 2:
raise ValidationError("Name too short")
# НОВОЕ: Возрастная проверка (баг: нет теста)
if age < 18:
raise ValidationError("User must be 18+")
# НОВОЕ: Email подтверждение (баг: не проверяли)
send_confirmation_email(email)
return User(name=name, email=email, age=age)
Что упустили тесты:
- Возрастная проверка: create_user("John", "john@example.com", 17) не тестировалось
- Email подтверждение не проверялось
Симптомы парадокса
- Тест-ран всегда зелёный месяцами
- Юзеры находят баги в production
- Одни и те же тест-кейсы не обновляются
- Высокий баг-rate после релиза
- Скука в работе с тестами
Как избежать парадокса
Стратегия 1: Расширять тест-кейсы
Плохо:
def test_age_validation():
assert is_valid_age(25) == True
assert is_valid_age(-5) == False
Хорошо:
@pytest.mark.parametrize("age,expected", [
(0, False),
(17, False),
(18, True),
(65, True),
(120, True),
(121, False),
(999, False),
(-1, False),
])
def test_age_validation(age, expected):
assert is_valid_age(age) == expected
Стратегия 2: Exploratory Testing
Не только автотесты. Интуитивный поиск багов:
- Некорректные данные
- Double-click, rapid clicks
- Отключённый JavaScript
- Разные языки системы
- Разные временные зоны
- 100 открытых вкладок
Стратегия 3: Mutation Testing
Вноси баги в код и проверяй, падают ли тесты:
# Оригинал
def is_admin(role):
return role == "admin"
# Мутация
def is_admin(role):
return role == "admin" or role == "moderator" # BAG
# Тест должен упасть
def test_only_admin():
assert is_admin("moderator") == False
Стратегия 4: Property-Based Testing
Используй Hypothesis для генерации случайных входов:
from hypothesis import given, strategies as st
@given(st.integers())
def test_abs_positive(x):
assert abs(x) >= 0
Стратегия 5: Обновлять при каждом изменении
Новая фича → Новые тесты
Исправление → Тест на баг
Рефакторинг → Проверка старых тестов
Стратегия 6: Разнообразить тестирование
Не только unit-тесты:
- Unit tests
- Integration tests
- E2E tests
- Performance tests
- Security tests
- Exploratory testing
Стратегия 7: Анализировать баги production
Когда юзер находит баг:
- Создай тест, воспроизводящий баг
- Убедись, что тест падает
- Разработчик исправляет
- Тест становится зелёным
- Тест остаётся в наборе
Мониторинг парадокса
Метрики:
- TCE (Test Case Effectiveness) — баги найдено / всего тестов
- DER (Defect Escape Rate) — баги в production / всего
- Code Coverage Trend — увеличивается ли покрытие
- Bug Type Distribution — новые типы багов в production
Пример:
Месяц 1: 50 тестов → 20 багов (40% эффективность)
Месяц 2: 50 тестов → 10 багов (20% эффективность)
Месяц 3: 50 тестов → 5 багов (10% эффективность) ← Парадокс!
Цикл обновления тестов
Неделя 1: 20 новых тест-кейсов
Неделя 2: Расширяю граничные случаи
Неделя 3: Добавляю exploratory результаты
Неделя 4: Анализирую упущенные сценарии
Неделя 5: Mutation testing
Неделя 6: Начинаю заново
Практический совет
Парадокс пестицида — признак застоя. Если месяцами не находишь новые баги и юзеры обнаруживают проблемы:
- Добавь граничные случаи
- Запусти exploratory testing
- Используй mutation testing
- Разнообразь методы тестирования
- Анализируй баги в production
- Требуй новых тест-кейсов при каждой фиче
Помни: тесты, которые не находят баги — это плохие тесты. Их нужно улучшать постоянно.