TL;DR: Разбиение на классы эквивалентности группирует входные данные в классы с одинаковым поведением, затем тестирует по одному представителю от каждого класса. В сочетании с анализом граничных значений обеспечивает эффективное покрытие.

Тестирование каждого возможного входного значения невозможно. Простое поле пароля, принимающее 8-32 символа, имеет миллиарды потенциальных входов. Силлабус ISTQB Foundation Level определяет разбиение на классы эквивалентности как одну из четырёх основных техник проектирования тестов методом чёрного ящика. Согласно исследованиям IEEE Computer Society, эта техника сокращает тестовые наборы на 60-80% при сохранении сопоставимого уровня обнаружения дефектов. Борис Бейзер в фундаментальной работе Software Testing Techniques продемонстрировал, что систематическое разбиение выявляет 85% дефектов, связанных с вводом данных, при использовании лишь малой части тест-кейсов, которые потребовало бы исчерпывающее тестирование. Как тестировать всесторонне, не тратя годы на написание тест-кейсов?

Встречайте Разделение на Классы Эквивалентности (EP) — фундаментальную технику проектирования тест-кейсов и подход тестирования черного ящика, которая делит входные данные на логические группы (классы), где все значения в классе должны вести себя одинаково. Тестируя одно представительное значение из каждого класса, вы достигаете широкого покрытия с минимальным количеством тест-кейсов.

Разделение на классы эквивалентности является ключевым элементом стратегии автоматизации тестирования, позволяя систематически подходить к выбору тестовых данных. Эта техника особенно эффективна в сочетании с исследовательским тестированием для обнаружения граничных случаев, а также при интеграции в CI/CD пайплайны для обеспечения качества релизов.

Основная Концепция

Принцип Разделения на Классы Эквивалентности: Если одно значение из класса работает правильно, все значения в этом классе должны работать правильно. И наоборот, если одно значение не работает, все значения в этом классе должны не работать.

“Разбиение на классы эквивалентности — самая эффективная по времени техника тестирования, которую большинство QA-инженеров недоиспользует. Когда я вижу 50 тест-кейсов для одного поля ввода, это почти всегда потому, что никто не идентифицировал классы эквивалентности.” — Yuri Kan, Senior QA Lead

Вместо тестирования:

Ввод возраста: 5, 10, 15, 18, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80...

Вы тестируете:

Классы возраста:

- Невалидный (слишком молод): Тестовое значение = 10
- Валидный (взрослый): Тестовое значение = 40
- Невалидный (слишком стар): Тестовое значение = 75

Три тест-кейса вместо десятков, с такой же или лучшей обнаруживаемостью дефектов.

Как Применять Разделение на Классы Эквивалентности

Шаг 1: Определить Входные Условия

Перечислите все входы и их требования:

Пример: Система Бронирования Билетов

Вход: Количество билетов
Требование: Должно быть между 1 и 10 (включительно)

Шаг 2: Определить Классы Эквивалентности

Разделите входное пространство на валидные и невалидные классы:

Тип КлассаДиапазонОписание
Невалидный< 1Слишком мало билетов
Валидный1-10Приемлемый диапазон
Невалидный> 10Слишком много билетов

Шаг 3: Выбрать Тестовые Значения

Выберите одно представительное значение из каждого класса:

КлассТестовое ЗначениеОжидаемый Результат
Невалидный (< 1)0Ошибка: “Требуется минимум 1 билет”
Валидный (1-10)5Бронирование успешно
Невалидный (> 10)15Ошибка: “Максимум 10 билетов разрешено”

Результат: 3 тест-кейса покрывают все сценарии

Валидные vs Невалидные Классы

Каждый вход обычно имеет:

Валидные Классы

  • Входы, которые система должна принять
  • Ожидается, что они приведут к успешным результатам
  • Часто есть один валидный класс, но сложные входы могут иметь несколько

Невалидные Классы

  • Входы, которые система должна отклонить
  • Ожидается, что они приведут к ошибкам
  • Обычно несколько невалидных классов (ниже диапазона, выше диапазона, неправильный тип, null и т.д.)

Пример: Поле Email

Валидные Классы:

- ✅ Стандартный email: "user@example.com"
- ✅ Email с числами: "user123@test.com"
- ✅ Email с поддоменом: "user@mail.example.com"

Невалидные Классы:

- ❌ Отсутствует @: "userexample.com"
- ❌ Отсутствует домен: "user@"
- ❌ Отсутствует локальная часть: "@example.com"
- ❌ Несколько @: "user@@example.com"
- ❌ Пустая строка: ""
- ❌ Специальные символы: "user name@example.com"
- ❌ Слишком длинный: [email > 254 символов]

Стратегия Тестирования: Выберите 1-2 значения из валидных классов, 1 значение из каждого невалидного класса.

Пример Тест-Кейса EP

**Функция**: Регистрация Пользователя - Поле Возраста
**Требование**: Возраст должен быть 18-65 лет

**Классы Эквивалентности:**

| ID Класса | Тип Класса | Диапазон | Тестовое Значение | Ожидаемый Результат |
|----------|-----------|---------|------------------|-------------------|
| EP1 | Невалидный | Возраст < 18 | 15 | Ошибка: "Вам должно быть 18 или больше" |
| EP2 | Валидный | 18 ≤ Возраст ≤ 65 | 30 | Регистрация успешна |
| EP3 | Невалидный | Возраст > 65 | 70 | Ошибка: "Превышен лимит возраста" |
| EP4 | Невалидный | Нечисловой | "abc" | Ошибка: "Возраст должен быть числом" |
| EP5 | Невалидный | Отрицательный | -5 | Ошибка: "Возраст должен быть положительным" |
| EP6 | Невалидный | Десятичный | 25.5 | Ошибка: "Возраст должен быть целым числом" |
| EP7 | Невалидный | Пустой | "" | Ошибка: "Требуется возраст" |

**Всего Тест-Кейсов**: 7 (вместо тестирования всех возрастов 0-999)

Комбинирование EP с Анализом Граничных Значений (BVA)

Разделение на Классы Эквивалентности и Анализ Граничных Значений работают идеально вместе:

Только EP:

Валидный класс (18-65): Тестовое значение = 30

EP + BVA:

Валидный класс (18-65):

- Тестовое значение = 18 (нижняя граница)
- Тестовое значение = 30 (средний диапазон)
- Тестовое значение = 65 (верхняя граница)

Пример: Уровни Скидок

Требование: Скидки при покупке на основе суммы

  • $0-$99: Без скидки
  • $100-$499: 10% скидка
  • $500-$999: 15% скидка
  • $1000+: 20% скидка

Классы EP:

КлассДиапазонТестовое Значение EPТестовые Значения EP+BVA
Уровень 1$0-$99$50$0, $50, $99
Уровень 2$100-$499$300$100, $300, $499
Уровень 3$500-$999$750$500, $750, $999
Уровень 4$1000+$1500$1000, $1500, $5000

Только EP: 4 тест-кейса EP + BVA: 12 тест-кейсов (более тщательно)

Примеры из Реального Мира

Пример 1: Валидация Пароля

Требования:

  • Длина: 8-20 символов
  • Должен содержать: заглавную букву, строчную букву, цифру, специальный символ
  • Не может содержать: имя пользователя, общие слова

Классы Эквивалентности:

Валидный Класс:
EP-V1: Валидный пароль, удовлетворяющий всем критериям
  Тест: "MyP@ssw0rd"

Невалидные Классы:
EP-I1: Слишком короткий (< 8 символов)
  Тест: "Pass1!"

EP-I2: Слишком длинный (> 20 символов)
  Тест: "MyVeryLongP@ssw0rd123456"

EP-I3: Отсутствует заглавная буква
  Тест: "myp@ssw0rd1"

EP-I4: Отсутствует строчная буква
  Тест: "MYP@SSW0RD1"

EP-I5: Отсутствует цифра
  Тест: "MyP@ssword"

EP-I6: Отсутствует специальный символ
  Тест: "MyPassword1"

EP-I7: Содержит имя пользователя
  Тест: "JohnP@ssw0rd" (если имя пользователя "john")

EP-I8: Общее слово
  Тест: "Password123!"

EP-I9: Пустой
  Тест: ""

Автоматизация Тестов:

import pytest

@pytest.mark.parametrize("password,expected,reason", [
    # Валидный класс
    ("MyP@ssw0rd", True, "Валидный пароль"),

    # Невалидные классы
    ("Pass1!", False, "Слишком короткий"),
    ("MyVeryLongP@ssw0rd123456", False, "Слишком длинный"),
    ("myp@ssw0rd1", False, "Отсутствует заглавная"),
    ("MYP@SSW0RD1", False, "Отсутствует строчная"),
    ("MyP@ssword", False, "Отсутствует цифра"),
    ("MyPassword1", False, "Отсутствует спец. символ"),
    ("Password123!", False, "Общее слово"),
    ("", False, "Пустой"),
])
def test_password_validation(password, expected, reason):
    result = validate_password(password)
    assert result == expected, f"Не прошло: {reason}"

Типичные Ошибки

❌ Ошибка 1: Пересекающиеся Классы

Плохо:

- Класс 1: Возраст 0-50
- Класс 2: Возраст 50-100

Проблема: Возраст 50 в обоих классах!

Хорошо:

- Класс 1: Возраст 0-49
- Класс 2: Возраст 50-100

❌ Ошибка 2: Отсутствующие Невалидные Классы

Плохо (только тестирование валидных):

- Класс: Валидный возраст (18-65)
- Тест: 30

Хорошо (тестирование валидных + невалидных):

- Класс 1: Слишком молод (< 18)
- Класс 2: Валидный (18-65)
- Класс 3: Слишком стар (> 65)

Преимущества EP

  1. Сокращает Тест-Кейсы: С тысяч до десятков
  2. Систематическое Покрытие: Обеспечивает тестирование всех классов входов
  3. Обнаружение Дефектов: Один тест на класс обнаруживает сбои всего класса
  4. Поддерживаемость: Легко обновлять при изменении требований
  5. Эффективность: Максимизирует покрытие с минимальными усилиями

Заключение

Разделение на Классы Эквивалентности — это фундаментальная техника проектирования тестов, которая:

  • Делит входные данные на логические группы
  • Тестирует одно представительное значение на группу
  • Резко сокращает тест-кейсы, сохраняя покрытие
  • Работает лучше всего в сочетании с Анализом Граничных Значений

Помните: Если вы тестируете одно значение из класса и оно работает, весь класс должен работать. Этот принцип позволяет вам тестировать умнее, а не усерднее.

FAQ

Что такое разбиение на классы эквивалентности?

Разбиение на классы эквивалентности делит входные данные на группы с одинаковым поведением. Техника определена в стандарте ISTQB как фундаментальный метод разработки тестов.

В чём разница между валидными и невалидными классами?

Валидные классы — значения, которые система должна принять. Невалидные — значения, которые система должна отклонить.

Как анализ граничных значений дополняет разбиение на классы?

Разбиение идентифицирует классы, анализ граничных значений тестирует их края.

Когда использовать разбиение на классы?

Когда входные данные имеют широкий диапазон значений, которые можно разделить на значимые категории.

Смотрите также

Официальные ресурсы