Настройка в CI, database seeding, hypothesis в production
«Автоматическое тестирование в CI и безопасное использование в production.»
# .github/workflows/test.yml
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.9, 3.10, 3.11]
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip install poetry
poetry install
- name: Run Hypothesis tests
run: |
poetry run pytest tests/ \
--hypothesis-seed=0 \
--hypothesis-max-examples=200 \
--hypothesis-deadline=500
env:
HYPOTHESIS_DATABASE=:memory:# .gitlab-ci.yml
test:
image: python:3.11
script:
- pip install poetry
- poetry install
- poetry run pytest tests/ \
--hypothesis-seed=$CI_PIPELINE_ID \
--hypothesis-max-examples=500
variables:
HYPOTHESIS_DATABASE: ":memory:"
artifacts:
when: on_failure
paths:
- .hypothesis/
expire_in: 1 week# conftest.py
import os
from hypothesis import settings, Database, in_memory
def pytest_configure(config):
# В CI отключаем базу для детерминизма
if os.getenv('CI'):
settings.register_profile(
'ci',
database=in_memory,
max_examples=200,
deadline=500,
print_blob=True,
)
settings.load_profile('ci')
else:
settings.register_profile(
'dev',
database=DirectoryDatabase('.hypothesis'),
max_examples=100,
)
settings.load_profile('dev')# Очистить failing cases
rm -rf .hypothesis/examples/
# Очистить всё
hypothesis cache cleanfrom hypothesis import given, strategies as st
from hypothesis import Verbosity
import logging
logger = logging.getLogger(__name__)
def validate_user_data(data: dict) -> bool:
"""Валидация данных пользователя в production"""
try:
# Используем Hypothesis для генерации тестовых случаев
# и проверки инвариантов
@given(st.from_type(dict))
@settings(verbosity=Verbosity.quiet, max_examples=50)
def check_invariants(test_data):
# Проверка что валидация не падает
assert isinstance(test_data.get('email'), str)
assert isinstance(test_data.get('age'), int)
check_invariants()
return True
except Exception as e:
logger.error(f"Validation error: {e}")
return Falsefrom hypothesis import given, strategies as st
def ab_test_checkout_flow(user_data: dict):
"""A/B тестирование checkout процесса"""
@given(st.builds(dict,
cart_value=st.floats(min_value=0, max_value=10000),
items_count=st.integers(min_value=1, max_value=100),
is_first_purchase=st.booleans()
))
def test_conversion(test_data):
# Тестирование новой воронки
new_flow_result = new_checkout_flow(test_data)
# Сравнение со старой
old_flow_result = old_checkout_flow(test_data)
# Новая воронка не должна быть хуже
assert new_flow_result.conversion >= old_flow_result.conversion * 0.95
test_conversion()Правильная настройка Hypothesis в CI обеспечивает стабильность тестов, а использование в production помогает находить баги на ранних этапах.
Следующая тема: Продвинутые паттерны — best practices, антипаттерны, оптимизация.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.