/
Вопросы и ответы
/
Вайбкодинг
/

Как писать тесты с помощью ИИ?

Как писать тесты с помощью ИИ?

8 часов назад

Никита Вихров

Ответы

0

Как писать тесты с помощью ИИ

Тесты — одна из лучших задач для вайбкодинга. Шаблонные, предсказуемые, и ИИ пишет их быстро. Но есть нюансы.

Промпт для генерации тестов

Не просите просто «напиши тесты». Давайте структуру:

напиши тесты на pytest для этой функции: def calculate_discount(price: Decimal, user_tier: str) -> Decimal: if user_tier == "premium": return price * Decimal("0.10") elif user_tier == "standard": return price * Decimal("0.05") else: raise ValueError(f"Unknown user tier: {user_tier}") покрой: 1. happy path — premium и standard пользователи 2. граничные случаи — цена 0, очень большая цена 3. некорректные данные — неизвестный tier, отрицательная цена, None 4. используй parametrize где уместно

Результат от Claude:

import pytest
from decimal import Decimal
from app.pricing import calculate_discount


@pytest.mark.parametrize("tier,price,expected", [
    ("premium", Decimal("100"), Decimal("10.00")),
    ("premium", Decimal("0"), Decimal("0.00")),
    ("premium", Decimal("0.01"), Decimal("0.001")),
    ("standard", Decimal("100"), Decimal("5.00")),
    ("standard", Decimal("999999"), Decimal("49999.95")),
])
def test_calculate_discount_valid(tier, price, expected):
    assert calculate_discount(price, tier) == expected


@pytest.mark.parametrize("tier", ["gold", "vip", "", "PREMIUM"])
def test_calculate_discount_unknown_tier(tier):
    with pytest.raises(ValueError, match="Unknown user tier"):
        calculate_discount(Decimal("100"), tier)


def test_calculate_discount_none_tier():
    with pytest.raises((ValueError, TypeError)):
        calculate_discount(Decimal("100"), None)

TDD с ИИ: сначала тесты

Попробуйте обратный подход — тесты до реализации:

шаг 1. напиши тесты для функции parse_config(path: str) -> dict. функция должна: - читать YAML-файл по пути - возвращать словарь с ключами: host, port, debug - бросать FileNotFoundError если файл не существует - бросать ValueError если отсутствует обязательный ключ host - port должен быть int, если в файле строка — конвертировать шаг 2 (после проверки тестов): теперь напиши реализацию которая проходит эти тесты

Тесты написанные по требованиям, а не по коду — ловят баги в реализации.

Запрос граничных случаев отдельно

Модель по умолчанию пишет happy path. Просите граничные случаи явно:

вот мои тесты для parse_csv(file_path): [тесты] какие граничные случаи я не учёл? предложи дополнительные тест-кейсы

Claude найдёт: пустой файл, файл только с заголовками, unicode в значениях, разные line endings (\r\n vs \n), кавычки внутри полей, BOM в начале файла.

Генерация фикстур и фабрик

ИИ отлично генерирует тестовые данные:

напиши factory_boy фабрику для модели Order: class Order(Base): id: int user_id: int items: list[OrderItem] status: str # "pending", "paid", "cancelled" total: Decimal created_at: datetime нужны варианты: - обычный заказ (pending) - оплаченный заказ (paid) - заказ с несколькими товарами - отменённый заказ

Результат:

import factory
from factory.alchemy import SQLAlchemyModelFactory
from decimal import Decimal
from app.models import Order, OrderItem


class OrderItemFactory(SQLAlchemyModelFactory):
    class Meta:
        model = OrderItem

    name = factory.Faker("word")
    price = factory.LazyFunction(lambda: Decimal("9.99"))
    quantity = factory.Faker("random_int", min=1, max=5)


class OrderFactory(SQLAlchemyModelFactory):
    class Meta:
        model = Order

    user_id = factory.Faker("random_int", min=1, max=1000)
    status = "pending"
    total = factory.LazyFunction(lambda: Decimal("49.95"))
    created_at = factory.Faker("date_time_this_year")

    @factory.post_generation
    def items(self, create, extracted, **kwargs):
        if extracted:
            for item in extracted:
                self.items.append(item)
        else:
            OrderItemFactory.create_batch(2, order=self)


class PaidOrderFactory(OrderFactory):
    status = "paid"


class CancelledOrderFactory(OrderFactory):
    status = "cancelled"

Ревью тестов с ИИ

Уже написанные тесты отдайте на проверку:

вот мои тесты. найди: 1. что я не протестировал 2. тесты которые проверяют реализацию, а не поведение 3. возможные false positive 4. дублирование [тесты]

Главная ловушка

Тесты написанные по коду могут закреплять баги:

# Баг в коде: скидка считается от итого, а не от цены
def apply_discount(price, discount_percent):
    total = price * 1.2  # с налогом
    return total * (1 - discount_percent / 100)  # скидка от total — баг!

# ИИ напишет тест по этому коду:
def test_apply_discount():
    # И тест будет проходить, хотя логика неверная
    assert apply_discount(100, 10) == 108.0  # 120 * 0.9

Решение — формулируйте тест от требования:

вот требование: скидка 10% применяется к цене до налога. вот реализация: [код] напиши тест по требованию. если реализация противоречит — укажи на это

Если коротко: давайте структуру в промпте, просите граничные случаи отдельно, пишите тесты от требований — и покрытие будет реальным, а не формальным.

8 часов назад

Никита Вихров

+7 800 100 22 47

бесплатно по РФ

+7 495 085 21 62

бесплатно по Москве

108813 г. Москва, вн.тер.г. поселение Московский,
г. Московский, ул. Солнечная, д. 3А, стр. 1, помещ. 20Б/3
ОГРН 1217300010476
ИНН 7325174845