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

Как можно протестировать требование?

1.0 Junior🔥 131 комментариев
#Требования и их анализ

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

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

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

Как протестировать требование

Тестирование требования — это процесс проверки, что реализованная функциональность соответствует исходному требованию. Это не просто проверка на ошибки, а подтверждение того, что система делает именно то, что нужно бизнесу. Это ключевая задача системного аналитика и QA команды.

Основной подход: Acceptance Criteria

Перед тестированием требования нужно определить критерии приёмки (Acceptance Criteria). Это конкретные, проверяемые условия, которые должны быть выполнены.

Пример:

Требование: "Пользователь должен иметь возможность отфильтровать товары по цене"

Акцептанс критерии:

  • AC1: При выборе диапазона цены от 100 до 500 показываются только товары в этом диапазоне
  • AC2: Фильтр работает при первой загрузке страницы
  • AC3: При изменении фильтра список обновляется в реальном времени
  • AC4: При очистке фильтра показываются все товары
  • AC5: Фильтр сохраняется при обновлении страницы (URL параметры)

1. Модульное тестирование (Unit Testing)

Что тестировать: Отдельные компоненты и функции, которые реализуют требование.

Пример: Фильтрация товаров

import pytest
from app.services import ProductService

class TestProductFilter:
    def test_filter_by_price_range(self):
        """AC1: Фильтр работает по диапазону цены"""
        service = ProductService()
        
        # Arrange
        products = [
            {"id": 1, "name": "Товар 1", "price": 100},
            {"id": 2, "name": "Товар 2", "price": 300},
            {"id": 3, "name": "Товар 3", "price": 600},
        ]
        
        # Act
        filtered = service.filter_by_price(products, min_price=100, max_price=500)
        
        # Assert
        assert len(filtered) == 2
        assert filtered[0]["id"] == 1
        assert filtered[1]["id"] == 2
    
    def test_filter_empty_result(self):
        """AC: Фильтр может вернуть пустой результат"""
        service = ProductService()
        products = [{"id": 1, "price": 100}]
        
        filtered = service.filter_by_price(products, min_price=500, max_price=1000)
        
        assert len(filtered) == 0
    
    def test_filter_all_results_with_empty_filter(self):
        """AC4: Без фильтра показываются все товары"""
        service = ProductService()
        products = [
            {"id": 1, "price": 100},
            {"id": 2, "price": 300},
        ]
        
        filtered = service.filter_by_price(products, min_price=None, max_price=None)
        
        assert len(filtered) == 2

2. Интеграционное тестирование (Integration Testing)

Что тестировать: Взаимодействие компонентов при реализации требования.

Пример: Фильтрация + сохранение в БД

import pytest
from app import db, create_app
from app.models import Product

@pytest.fixture
def app():
    app = create_app('testing')
    with app.app_context():
        db.create_all()
        yield app
        db.session.remove()
        db.drop_all()

def test_filter_products_from_database(app):
    """AC1: Фильтр работает с реальными данными из БД"""
    with app.app_context():
        # Arrange
        db.session.add(Product(name="Товар 1", price=100))
        db.session.add(Product(name="Товар 2", price=300))
        db.session.add(Product(name="Товар 3", price=600))
        db.session.commit()
        
        # Act
        products = Product.query.filter(
            Product.price >= 100,
            Product.price <= 500
        ).all()
        
        # Assert
        assert len(products) == 2
        assert products[0].name == "Товар 1"

def test_filter_preserves_in_url(app):
    """AC5: Фильтр сохраняется в URL параметрах"""
    client = app.test_client()
    
    # Act
    response = client.get('/products?min_price=100&max_price=500')
    
    # Assert
    assert response.status_code == 200
    assert 'min_price=100' in response.request.url
    assert 'max_price=500' in response.request.url

3. End-to-End тестирование (E2E Testing)

Что тестировать: Весь путь пользователя от начала до конца.

Пример: Полный сценарий фильтрации (Playwright)

import pytest
from playwright.sync_api import sync_playwright

def test_filter_products_e2e():
    """AC: Пользователь может отфильтровать товары по цене"""
    with sync_playwright() as p:
        browser = p.chromium.launch()
        page = browser.new_page()
        
        # Arrange
        page.goto('http://localhost:3000/products')
        
        # Act: Установить фильтр
        page.fill('input[placeholder="Min price"]', '100')
        page.fill('input[placeholder="Max price"]', '500')
        page.click('button:has-text("Apply Filter")')
        
        # Assert: Проверить результаты
        products = page.query_selector_all('.product-item')
        assert len(products) == 2
        
        prices = []
        for product in products:
            price_text = product.query_selector('.price').text_content()
            prices.append(int(price_text.replace('$', '')))
        
        assert all(100 <= p <= 500 for p in prices)
        
        # Act: Обновить страницу
        page.reload()
        
        # Assert: AC5 - фильтр сохраняется
        products = page.query_selector_all('.product-item')
        assert len(products) == 2
        
        # Cleanup
        browser.close()

4. API тестирование

Что тестировать: REST API endpoints, которые реализуют требование.

Пример: Фильтрация через API

import pytest
from httpx import Client

def test_filter_products_api():
    """AC1: API возвращает отфильтрованные товары"""
    client = Client(base_url='http://localhost:8000')
    
    # Act
    response = client.get('/api/v1/products', params={
        'min_price': 100,
        'max_price': 500
    })
    
    # Assert
    assert response.status_code == 200
    data = response.json()
    assert len(data['items']) == 2
    
    for product in data['items']:
        assert 100 <= product['price'] <= 500

def test_filter_with_invalid_range():
    """AC: API обрабатывает неправильный диапазон"""
    client = Client(base_url='http://localhost:8000')
    
    # Act: min > max
    response = client.get('/api/v1/products', params={
        'min_price': 500,
        'max_price': 100
    })
    
    # Assert
    assert response.status_code == 400  # или 200 с пустым результатом
    # Зависит от требования обработки ошибок

5. Тестирование граничных случаев (Edge Cases)

Что тестировать: Нестандартные ситуации.

def test_filter_edge_cases():
    service = ProductService()
    products = [
        {"id": 1, "price": 0},
        {"id": 2, "price": 100},
        {"id": 3, "price": 999999},
    ]
    
    # Граница: цена 0
    assert service.filter_by_price(products, 0, 0) == [{"id": 1, "price": 0}]
    
    # Очень большая цена
    assert len(service.filter_by_price(products, 100, 999999)) == 2
    
    # Отрицательная цена (должна быть обработана)
    # В зависимости от требования
    
    # None значения
    assert len(service.filter_by_price(products, None, 100)) == 2

6. Performance тестирование

Что тестировать: Требование работает быстро даже при большом количестве данных.

Пример: Фильтрация 1 млн товаров

import time
import pytest

def test_filter_performance(benchmark):
    """AC3: Фильтр работает в реальном времени (< 500ms)"""
    service = ProductService()
    
    # Создать большой список
    products = [{"id": i, "price": i % 1000} for i in range(1_000_000)]
    
    # Benchmark
    result = benchmark(lambda: service.filter_by_price(products, 100, 500))
    
    # Assert
    assert len(result) > 0
    # benchmark автоматически проверит время

7. Security тестирование

Что тестировать: Требование не создаёт уязвимостей.

Пример: SQL Injection

def test_filter_sql_injection_prevention():
    """AC: Фильтр безопасен от SQL injection"""
    client = Client(base_url='http://localhost:8000')
    
    # Попытка SQL injection
    response = client.get('/api/v1/products', params={
        'min_price': "100; DROP TABLE products;",
        'max_price': 500
    })
    
    # Assert
    assert response.status_code in [400, 422]  # Ошибка валидации
    
    # Проверить, что БД не повреждена
    response = client.get('/api/v1/products')
    assert response.status_code == 200

8. UAT (User Acceptance Testing)

Что тестировать: Реальный пользователь согласен, что требование выполнено.

Процесс:

  1. Подготовить тестовую среду с реальными данными
  2. Дать доступ stakeholders
  3. Предоставить чек-лист (основан на AC)
  4. Собрать feedback
  5. Отправить на доработку или приём

Чек-лист:

  • AC1: Фильтр по цене от 100 до 500 работает
  • AC2: При первой загрузке фильтр применяется
  • AC3: При изменении чисел список обновляется мгновенно
  • AC4: При очистке фильтра показываются все товары
  • AC5: При перезагрузке страницы фильтр сохраняется

9. Регрессионное тестирование

Что тестировать: Новое требование не сломало старую функциональность.

def test_filter_does_not_break_sorting():
    """Фильтр + сортировка должны работать вместе"""
    service = ProductService()
    products = [
        {"id": 1, "price": 500},
        {"id": 2, "price": 100},
        {"id": 3, "price": 300},
    ]
    
    # Применить фильтр И сортировку
    filtered = service.filter_by_price(products, 100, 500)
    sorted_products = sorted(filtered, key=lambda x: x['price'])
    
    # Assert
    assert sorted_products[0]['price'] == 100
    assert sorted_products[1]['price'] == 300
    assert sorted_products[2]['price'] == 500

Матрица тестирования требования

Тип тестированияЧто проверяетКто проводитКогда
UnitФункции работаютРазработчикРазработка
IntegrationКомпоненты взаимодействуютQAПосле разработки
E2EПуть пользователяQAПеред UAT
APIREST endpointsQA автоматизацияНепрерывно
Edge CasesГраничные случаиQAПред-тестирование
PerformanceСкоростьQA нагрузочноеПред-production
SecurityБезопасностьSecurity teamПред-production
UATСоответствие бизнесуStakeholdersПеред релизом
RegressionНет деградацииАвтоматизацияПосле каждого изменения

Инструменты для тестирования

Unit & Integration:

  • pytest (Python)
  • Jest (JavaScript)
  • JUnit (Java)

E2E:

  • Playwright
  • Cypress
  • Selenium

API:

  • Postman
  • REST Assured
  • httpx

Performance:

  • JMeter
  • Locust
  • K6

UAT:

  • TestRail
  • Zephyr
  • HP Quality Center

Лучшие практики

  1. Пишите тесты ДО разработки (TDD) — сначала test, потом код
  2. Базируйте тесты на AC — каждый AC = минимум один тест
  3. Автоматизируйте всё, что можно — особенно регрессию
  4. Тестируйте граничные случаи — не только "happy path"
  5. Проверяйте performance — требование может быть медленным
  6. Включите UAT — реальный пользователь = окончательная проверка
  7. Документируйте результаты — Traceability Matrix

Трассируемость требований

Лучше всего создать Requirements Traceability Matrix (RTM):

ТребованиеAC1AC2AC3Unit testE2E testUATСтатус
Фильтр ценаГотово

Это показывает, что каждое требование полностью протестировано.

Вывод

Протестировать требование — значит:

  1. Определить acceptance criteria
  2. Написать unit тесты
  3. Написать интеграционные тесты
  4. Написать E2E тесты
  5. Провести UAT с пользователями
  6. Убедиться, что регрессии нет
  7. Документировать результаты

Только тогда можно быть уверенным, что требование действительно выполнено.