Modern QA2026Анатомия качественного тестового промпта
Join

Course02 AI-Augmented Test Design

Cutting-edge · Chapter 02

Анатомия качественного тестового промпта

Updated Jul 2026

Почему структура промпта важна

Плохой промпт порождает плохие тесты. Разница между «напиши тесты для логина» и структурированным промптом -- это разница между тем, как джуниор-инженер угадывает, и тем, как сеньор-инженер анализирует требования. LLM -- это статистические модели сопоставления паттернов: качество их вывода прямо пропорционально конкретности и структуре вашего ввода.

В контексте генерации тестов это означает, что вам нужно рассматривать свой промпт как документ спецификации тестов, а не как небрежный запрос. Каждый элемент контекста, который вы включаете (или опускаете), влияет на покрытие, качество и полезность сгенерированных тестов.

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

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

Элемент Назначение Пример
Контекст Какая система/функциональность тестируется "An e-commerce checkout API built in Node.js/Express"
Артефакт Спецификация, схема или история для тестирования "Here is the OpenAPI schema: ..."
Ограничения Фреймворк, язык, паттерны для соблюдения "Use Jest + Supertest, follow AAA pattern"
Цели покрытия Какие категории тестов генерировать "Include happy path, auth failures, validation errors, edge cases"
Формат вывода Как структурировать ответ "One test per it() block, group by endpoint"

Элемент 1: Контекст

Контекст сообщает LLM, с какой системой она имеет дело. Без него LLM делает обобщённые допущения. С ним -- адаптирует результат под технологический стек и домен.

Слабый контекст:

Write tests for the checkout flow.

Сильный контекст:

We have an e-commerce checkout API built in Node.js 20 with Express 4.
The checkout flow involves:
1. Cart validation (check stock availability)
2. Payment processing via Stripe API (test mode)
3. Order creation in PostgreSQL
4. Email confirmation via SendGrid

The API is behind JWT authentication. All prices are in cents (integer).

Сильный контекст сообщает LLM о технологическом стеке, бизнес-потоке, внешних зависимостях, формате данных и механизме аутентификации. Это устраняет целые классы галлюцинаций.

Элемент 2: Артефакт

Артефакт -- это основной источник истины для генерации тестов. Это может быть OpenAPI-схема, пользовательская история, критерии приёмки, схема базы данных или даже скриншот, описанный текстом.

Лучшая практика: Вставляйте артефакт непосредственно в промпт, а не описывайте его. "Here is the OpenAPI schema" с последующим фактическим YAML гораздо эффективнее, чем "the endpoint accepts a name field and a price field."

**Artifact — OpenAPI excerpt:**
```yaml
paths:
  /api/v2/checkout:
    post:
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [cart_id, payment_method_id]
              properties:
                cart_id:
                  type: string
                  format: uuid
                payment_method_id:
                  type: string
                coupon_code:
                  type: string
                  pattern: "^[A-Z0-9]{8}$"

Элемент 3: Ограничения

Ограничения не позволяют LLM генерировать тесты в неправильном фреймворке, на неправильном языке или в неправильном стиле. Они также обеспечивают соблюдение командных соглашений.

**Constraints:**
- Language: TypeScript 5.x
- Framework: Vitest with supertest
- Pattern: Arrange/Act/Assert with explicit comments
- Naming: "should [behavior] when [condition]"
- No external HTTP calls -- mock all Stripe/SendGrid calls
- Use factory functions from ./tests/factories.ts
- Each test file must import { describe, it, expect } from 'vitest'

Элемент 4: Цели покрытия

Без явных целей покрытия LLM по умолчанию генерирует тесты только для happy-path. Вы должны явно запросить негативные сценарии, граничные случаи и пограничные значения.

**Coverage requirements:**
- Every acceptance criterion must have at least one test
- Include at least 2 negative/error cases per endpoint
- Include 1 boundary value test for every numeric field
- Test auth: valid token, expired token, missing token, wrong role
- Test idempotency: calling the endpoint twice with the same cart_id

Элемент 5: Формат вывода

Управление форматом вывода делает сгенерированный код сразу пригодным к использованию без необходимости переформатирования.

**Output format:**
- One describe block per endpoint
- One it block per test case
- Group related tests with nested describe blocks
- Include JSDoc comment above each test explaining the scenario
- Output as a single TypeScript file that can be saved directly to tests/

Собираем всё вместе: полный промпт

You are a senior QA engineer. Given the following user story, acceptance criteria,
and technical context, generate a comprehensive test suite.

**User Story:**
As a customer, I want to apply a coupon code during checkout so that I get
a discount on my order.

**Acceptance Criteria:**
1. Valid coupon codes reduce the order total by the specified percentage
2. Expired coupons return a clear error message
3. Coupons can only be used once per customer
4. Invalid coupon format is rejected before hitting the database

**Technical Context:**
- Backend: Node.js 20, Express 4, TypeScript
- Database: PostgreSQL 15 via Prisma ORM
- Test framework: Vitest + Supertest
- Auth: JWT tokens via get_test_token("customer") helper
- Coupon format: 8 uppercase alphanumeric characters (regex: ^[A-Z0-9]{8}$)

**Generate:**
1. Unit tests for coupon validation logic (no DB, no HTTP)
2. Integration tests for the POST /api/v2/checkout endpoint with coupon
3. Edge case tests (empty string coupon, SQL injection in coupon field, etc.)

**For each test, include:**
- Test name: "should [expected behavior] when [condition]"
- Arrange/Act/Assert structure with comments
- Explicit assertions (not just "expect something")

**Coverage requirements:**
- All 4 acceptance criteria must have at least one test
- At least 2 negative/error cases per AC
- Boundary test for coupon format (7 chars, 8 chars, 9 chars)

Частые ошибки в промптах и как их исправить

Ошибка 1: Размытый запрос

# BAD
Write tests for the user service.

# GOOD
Generate pytest tests for the UserService.create_user() method defined
in app/services/user_service.py. The method accepts a CreateUserDTO
and returns a User model. Test validation, duplicate email handling,
and the happy path.

Ошибка 2: Не указан фреймворк

Без указания фреймворка LLM может сгенерировать тесты в стиле unittest для Python, когда вы используете pytest, или в стиле Mocha для JavaScript, когда вы используете Jest.

Ошибка 3: Нет примера стиля

Если у вашей команды есть специфические соглашения, вставьте 2-3 существующих теста в качестве «руководства по стилю». LLM будет соответствовать паттернам именования, стилям утверждений и использованию фикстур.

**Style reference (existing test from our codebase):**
```python
class TestUserCreation:
    def test_should_create_user_when_valid_email(self, db_session, user_factory):
        # Arrange
        dto = user_factory.build(email="new@example.com")

        # Act
        user = UserService(db_session).create_user(dto)

        # Assert
        assert user.id is not None
        assert user.email == "new@example.com"
        assert user.created_at is not None

Follow this exact pattern for all generated tests.


### Ошибка 4: Запрос слишком большого объёма за раз

Если вы запрашиваете 100 тестов в одном промпте, качество ухудшается к концу. Вместо этого генерируйте пакетами по 10-20, проверяйте, затем генерируйте следующий пакет.

---

## Итерационный цикл промптинга

Промпт-инженерия -- это не одноразовый процесс. Используйте следующий цикл:

  1. DRAFT the prompt with all five elements
  2. GENERATE a small batch (5-10 tests)
  3. EVALUATE: Are assertions correct? Are APIs real? Is the style right?
  4. REFINE the prompt based on what was wrong
  5. REGENERATE with the improved prompt
  6. REPEAT until output quality is consistently high
  7. SAVE the refined prompt as a template for future use

Этот цикл обычно сходится за 2-3 итерации. Инвестиции в доработку промпта окупаются каждый раз, когда вы переиспользуете шаблон для аналогичной функциональности.

---

## Ключевой вывод

Пять элементов (контекст, артефакт, ограничения, цели покрытия, формат вывода) формируют **спецификацию генерации тестов**. Относитесь к своему промпту с той же строгостью, с которой вы относитесь к документу требований. LLM хороша ровно настолько, насколько хороша спецификация, которую вы ей даёте.