Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Продвинутые паттерны и антипаттерны
advanced_patterns

Продвинутые паттерны и антипаттерны

Best practices, типичные ошибки, оптимизация тестов

Продвинутые паттерны и антипаттерны

«Избегайте типичных ошибок и используйте best practices для эффективного PBT.»

#Best Practices

#1. Правильный размер тестов

# ❌ ПЛОХО: Слишком много примеров, тесты медленные @settings(max_examples=10000) @given(st.integers()) def test_too_slow(x): ... # ✅ ХОРОШО: Разумный баланс @settings(max_examples=100) @given(st.integers()) def test_fast(x): ... # ✅ Для критичных тестов @settings(max_examples=500) @given(st.integers()) def test_critical(x): ...

#2. Избегайте слишком строгой фильтрации

# ❌ ПЛОХО: 99% данных отбрасывается @given(st.integers().filter(lambda x: x > 1000000)) def test_strict_filter(x): ... # ✅ ХОРОШО: Используйте assume() или правильные границы @given(st.integers(min_value=1000001, max_value=2000000)) def test_correct_range(x): ... # ✅ Или assume() для сложной логики @given(st.integers(), st.integers()) def test_division(x, y): assume(y != 0) assume(x > 0) ...

#3. Содержательные инварианты

# ❌ ПЛОХО: Бессмысленный инвариант @given(st.lists(st.integers())) def test_trivial(lst): assert lst == lst # Всегда истинно # ✅ ХОРОШО: Проверяйте свойства @given(st.lists(st.integers())) def test_sort_idempotent(lst): assert sorted(sorted(lst)) == sorted(lst) # ✅ Проверяйте инварианты предметной области @given(order_strategy()) def test_order_total(order): expected = sum(item.price * item.quantity for item in order.items) assert order.total == expected * (1 - order.discount)

#4. Используйте примеры для регрессии

# ✅ Добавьте failing case как пример @example(lst=[0, float('inf'), -float('inf')]) @given(st.lists(st.floats())) def test_sort(lst): assert sorted(lst) == sorted(lst)

#Антипаттерны

#1. Тестирование без свойств

# ❌ ПЛОХО: Это unit test, не PBT @given(st.integers()) def test_not_property_based(x): result = some_function(x) assert result == expected_value(x) # Конкретное значение

#2. Сложные стратегии

# ❌ ПЛОХО: Нечитаемая стратегия @given(st.one_of( st.builds(dict, a=st.integers()).flatmap(...).filter(...).map(...) )) def test_complex(data): ... # ✅ ХОРОШО: Вынесите в отдельную стратегию @st.composite def my_complex_strategy(draw): data = draw(st.builds(dict, a=st.integers())) # Логика обработки return data @given(my_complex_strategy()) def test_readable(data): ...

#3. Игнорирование shrinking

# ❌ ПЛОХО: map скрывает исходные значения @given(st.integers().map(lambda x: x * 1000000)) def test_bad_shrinking(x): # Failing case будет большим даже после shrinking # ✅ ХОРОШО: Используйте правильные границы @given(st.integers(min_value=0, max_value=1000000)) def test_good_shrinking(x): ...

#Оптимизация тестов

#1. Кэширование стратегий

# ✅ Создавайте стратегии один раз USER_STRATEGY = st.builds(User, ...) @given(USER_STRATEGY) def test_cached(user): ...

#2. Избегайте тяжёлых операций

# ❌ ПЛОХО: Медленная операция в тесте @given(st.lists(st.integers())) def test_slow(lst): time.sleep(0.1) # Замедляет все 100 примеров ... # ✅ ХОРОШО: Вынесите в fixture

#3. Группировка тестов

# ✅ Один тест с несколькими проверками @given(st.lists(st.integers())) def test_sort_properties(lst): result = sorted(lst) assert len(result) == len(lst) assert all(result[i] <= result[i+1] for i in range(len(result)-1)) assert Counter(result) == Counter(lst)

#Заключение

Следование best practices и избегание антипаттернов делает PBT эффективнее и быстрее.


Следующая тема: Реальные кейсы — разбор багов из production.

Далее: Реальные кейсы из Production