/
Вопросы и ответы
/
Промт-инжиниринг
/

ИИ для написания тестов

ИИ для написания тестов

2 месяца назад

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

Ответы

0

ИИ для написания тестов

Тесты — то что все должны писать и никто не любит. ИИ справляется с рутиной: генерирует базовые кейсы, граничные случаи, моки. Остаётся проверить логику и добавить специфику бизнеса.


Генерация тестов по функции

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from anthropic import Anthropic

client = Anthropic()


def generate_tests(function_code: str, framework: str = "pytest") -> str:
    frameworks = {
        "pytest": "pytest с фикстурами",
        "unittest": "unittest.TestCase",
        "jest": "Jest для JavaScript/TypeScript",
    }

    response = client.messages.create(
        model="claude-opus-4-5",
        max_tokens=2048,
        system=f"""Пишешь тесты на {frameworks[framework]}.

Обязательно покрывай:
1. Happy path — нормальная работа функции
2. Граничные случаи — пустые входные данные, None, нулевые значения
3. Ошибочные сценарии — неверный тип, недопустимые значения
4. Edge cases — максимальные/минимальные значения, очень длинные строки

Для каждого теста пиши понятное название через should_/when_/given_.
Тесты должны быть независимыми — без глобального состояния.""",
        messages=[{
            "role": "user",
            "content": f"Напиши тесты для этой функции:\n\n```python\n{function_code}\n```"
        }]
    )
    return response.content[0].text


# Пример
function = """
def calculate_discount(price: float, discount_percent: float, is_premium: bool = False) -> float:
    if price < 0:
        raise ValueError("Price cannot be negative")
    if not 0 <= discount_percent <= 100:
        raise ValueError("Discount must be between 0 and 100")

    discount = price * discount_percent / 100
    if is_premium:
        discount *= 1.5  # премиум-клиенты получают +50% к скидке

    return round(price - discount, 2)
"""

print(generate_tests(function))

Генерация граничных случаев по спецификации

Иногда нужно не писать тесты с нуля, а найти что пропустили:

1
2
3
4
5
6
7
8
9
def find_missing_test_cases(function_code: str, existing_tests: str) -> str:
    response = client.messages.create(
        model="claude-opus-4-5",
        max_tokens=1024,
        messages=[{
            "role": "user",
            "content": f"""Вот функция:
```python
{function_code}

Вот существующие тесты:

1
{existing_tests}

Найди граничные случаи и сценарии которые НЕ покрыты тестами. Для каждого случая напиши: описание сценария и тест-код.""" }] ) return response.content[0].text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
---

**Тесты для API-эндпоинтов**

```python
def generate_api_tests(endpoint_code: str, schema_code: str) -> str:
    response = client.messages.create(
        model="claude-opus-4-5",
        max_tokens=2048,
        system="""Пишешь интеграционные тесты для FastAPI через pytest и httpx.AsyncClient.

Структура файла:
- фикстуры для клиента и тестовой БД
- тесты сгруппированы по эндпоинту
- покрывай: успешные запросы, валидацию, авторизацию, несуществующие ресурсы

Используй factory_boy или fixtures для тестовых данных.""",
        messages=[{
            "role": "user",
            "content": f"""Эндпоинт:
```python
{endpoint_code}

Схемы Pydantic:

1
{schema_code}

Напиши интеграционные тесты.""" }] ) return response.content[0].text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
---

**Мутационное тестирование с ИИ**

Проверь насколько тесты реально ловят баги — попроси ИИ внести намеренные ошибки:

```python
def generate_mutations(function_code: str, count: int = 5) -> list[dict]:
    response = client.messages.create(
        model="claude-opus-4-5",
        max_tokens=1024,
        system="""Создаёшь мутации кода для мутационного тестирования.
Мутация — небольшое изменение которое должно сломать хотя бы один тест.
Отвечай JSON-массивом: [{"description": "...", "mutated_code": "..."}]""",
        messages=[{
            "role": "user",
            "content": f"Создай {count} мутаций для этой функции:\n\n```python\n{function_code}\n```"
        }]
    )

    import json, re
    text = re.sub(r'```(?:json)?|```', '', response.content[0].text).strip()
    return json.loads(text)


def check_test_quality(function_code: str, test_code: str):
    """Проверяет ловят ли тесты намеренные баги"""
    mutations = generate_mutations(function_code)

    caught = 0
    for mutation in mutations:
        # Здесь в реальности нужно запустить тесты с мутированным кодом
        print(f"Мутация: {mutation['description']}")
        print(f"Код: {mutation['mutated_code'][:100]}...")

    print(f"\nПроверь вручную: ловят ли твои тесты эти мутации?")
    print("Если нет — добавь тесты для непокрытых случаев")

Что проверять в сгенерированных тестах

ИИ генерирует структурно правильные тесты, но иногда:

  • Моки настроены неверно — тест проходит но ничего не проверяет
  • Ассерты слишком мягкие — assert result is not None вместо конкретного значения
  • Тест проверяет реализацию а не поведение — ломается при рефакторинге

Всегда запускай сгенерированные тесты и проверяй что они реально падают когда код неправильный.


На курсе «ИИ для разработчиков» на Хекслете разбирают как использовать ИИ на каждом этапе разработки — включая тестирование и ревью кода на реальном проекте.

2 месяца назад

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

+7 800 100 22 47

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

+7 495 085 21 62

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

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