← Назад к вопросам

Что делаешь, чтобы убедиться в качестве написанного кода?

2.0 Middle🔥 231 комментариев
#DevOps и инфраструктура#Django

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Обеспечение качества кода

Это фундаментальный вопрос о моей разработке. За 10+ лет я выработал систему проверок, которая гарантирует, что код, который я пишу, имеет высокое качество. Это не просто тестирование — это комплексный подход.

1. Тестирование (Test-Driven Development)

Я пишу тесты ПЕРЕД кодом — TDD подход:

# Шаг 1: Падающий тест (RED)
def test_calculate_discount():
    # Клиент с 5 заказами должен получить 10% скидку
    customer = Customer(orders_count=5)
    assert customer.get_discount() == 0.10

# Шаг 2: Минимальный код (GREEN)
class Customer:
    def __init__(self, orders_count):
        self.orders_count = orders_count
    
    def get_discount(self):
        if self.orders_count >= 5:
            return 0.10
        return 0.0

# Шаг 3: Рефакторинг (REFACTOR)
class Customer:
    def __init__(self, orders_count):
        self.orders_count = orders_count
    
    def get_discount(self) -> float:
        """Рассчитывает скидку на основе истории заказов"""
        discount_tiers = {
            5: 0.10,
            10: 0.15,
            20: 0.25
        }
        for threshold, discount in sorted(discount_tiers.items(), reverse=True):
            if self.orders_count >= threshold:
                return discount
        return 0.0

Типы тестов, которые я пишу:

  • Unit тесты (90% покрытие)
  • Integration тесты (для критичных путей)
  • E2E тесты (для основного flow)
  • Performance тесты (для узких мест)

2. Code Review — самокритика

Перед тем, как отправить PR, я сам себя review:

# Чеклист перед commit:
checklist = {
    "читаемость": [
        "Имена переменных понятные?",
        "Нет магических чисел?",
        "Функции короткие (max 20 строк)?",
        "Комментарии там, где нужны?"
    ],
    "качество": [
        "Нет дублирования кода (DRY)?",
        "SOLID принципы соблюдены?",
        "Нет очевидных ошибок?",
        "Обработаны edge cases?"
    ],
    "архитектура": [
        "Слои архитектуры не нарушены?",
        "Нет циклических зависимостей?",
        "Type hints везде?",
        "Docstrings для публичного API?"
    ],
    "тесты": [
        "Есть тесты для новой функции?",
        "Coverage >= 90%?",
        "Тесты падают без кода?",
        "Граничные случаи покрыты?"
    ]
}

3. Статический анализ кода

Автоматические инструменты, которые я использую:

# Python инструменты
tools = {
    "pylint": "Проверка синтаксиса и логических ошибок",
    "flake8": "PEP 8 compliance",
    "mypy": "Type checking",
    "black": "Auto-formatting кода",
    "isort": "Сортировка импортов",
    "bandit": "Проверка безопасности",
    "pytest": "Запуск тестов",
    "coverage.py": "Измерение test coverage"
}

# Пример в CI/CD pipeline:
steps = [
    "flake8 src/",
    "mypy src/ --strict",
    "pytest tests/ --cov=src --cov-fail-under=90",
    "black --check src/",
    "bandit -r src/"
]

4. Следование best practices

Мои правила:

SOLID принципы:

# Плохо — нарушает Single Responsibility
class User:
    def save_to_db(self):
        pass
    
    def send_email(self):
        pass
    
    def generate_report(self):
        pass

# Хорошо — разделены ответственности
class User:
    def __init__(self, name: str):
        self.name = name

class UserRepository:
    def save(self, user: User):
        pass

class EmailService:
    def send_welcome(self, user: User):
        pass

class ReportGenerator:
    def generate_user_report(self, user: User):
        pass

DRY (Don't Repeat Yourself):

# Плохо — повторение
def validate_email(email):
    if "@" not in email:
        raise ValueError("Invalid email")
    return email

def validate_username(username):
    if len(username) < 3:
        raise ValueError("Username too short")
    return username

# Хорошо — абстракция
def validate_field(value: str, min_length: int = None, pattern: str = None) -> str:
    if min_length and len(value) < min_length:
        raise ValueError(f"Too short")
    if pattern and not re.match(pattern, value):
        raise ValueError(f"Invalid format")
    return value

email = validate_field(email, pattern=r".*@.*")
username = validate_field(username, min_length=3)

5. Code Review от коллег

Я никогда не мёржу свой код без review:

# Процесс:
steps = {
    "1_create_pr": "Создаю PR с подробным описанием",
    "2_write_tests": "Тесты уже включены",
    "3_request_review": "Прошу минимум 2 review",
    "4_address_feedback": "Исправляю все замечания",
    "5_approve_merge": "После approval мёржу",
    "6_verify_deploy": "Проверяю в production"
}

# В PR пишу:
pull_request = """
## Description
Что сделано и почему

## Type of change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change

## How to test
Шаги для проверки

## Test coverage
90%+

## Screenshots (если UI)
Исходный vs новый вид
"""

6. Performance проверки

import timeit

# Бенчмарк критичных функций
def benchmark_query():
    # Плохо: O(n) в цикле
    for user_id in user_ids:
        user = User.query.filter_by(id=user_id).first()  # N queries
    
    # Хорошо: batch query
    users = User.query.filter(User.id.in_(user_ids)).all()  # 1 query

# Время выполнения
time_bad = timeit.timeit(benchmark_query_bad, number=1000)
time_good = timeit.timeit(benchmark_query_good, number=1000)
print(f"Ускорение: {time_bad / time_good}x")

7. Мониторинг в production

# После deploy мониторю:
metrics = {
    "error_rate": "должна остаться прежней или снизиться",
    "response_time": "не должна вырасти",
    "cpu_usage": "нормальный уровень",
    "memory": "утечек нет",
    "failed_tests": "0"
}

# В логах ищу
search_patterns = [
    "ERROR",
    "WARNING",
    "Exception",
    "timeout"
]

8. Documentation

Я документирую сложный код:

def calculate_compound_interest(
    principal: float,
    rate: float,
    time: float,
    compounds_per_year: int = 12
) -> float:
    """
    Рассчитывает сложные проценты.
    
    Args:
        principal: Начальная сумма в USD
        rate: Годовая ставка (0.05 для 5%)
        time: Период в годах
        compounds_per_year: Частота начисления (12 для месячной)
    
    Returns:
        Итоговая сумма в USD
    
    Example:
        >>> calculate_compound_interest(1000, 0.05, 2, 12)
        1104.89
    """
    return principal * (1 + rate / compounds_per_year) ** (compounds_per_year * time)

Мой чеклист перед push

✅ Тесты написаны и все проходят ✅ Coverage >= 90% ✅ Статический анализ (lint, type check) пройден ✅ Code review пройден ✅ Граничные случаи обработаны ✅ Нет дублирования ✅ Имена понятные ✅ Документация полная ✅ Performance приемлемая ✅ Безопасность проверена

Итог

Качество кода — это не одна проверка, а система проверок, которая работает на всех этапах. Я инвестирую время в качество сейчас, чтобы сэкономить на поддержке позже. Мой опыт показывает: хороший код — это экономия денег, нервов и продуктивности команды.

Что делаешь, чтобы убедиться в качестве написанного кода? | PrepBro