Ответ
Для эффективного и полного покрытия тестами я применяю следующие основные техники тест-дизайна:
-
Эквивалентное Разделение (Equivalence Partitioning):
- Цель: Уменьшить количество тест-кейсов, сгруппировав входные данные в классы, где поведение системы ожидается одинаковым.
- Пример для поля "Возраст пользователя" (допустимый диапазон: 18-65):
- Валидный класс:
[18, 65](например, 30) - Невалидный класс "меньше":
<18(например, 10) - Невалидный класс "больше":
>65(например, 70)
- Валидный класс:
-
Анализ Граничных Значений (Boundary Value Analysis):
- Цель: Тестирование на границах классов эквивалентности, где чаще всего возникают ошибки.
- Пример для того же поля (18-65):
- Границы валидного класса: 17, 18, 19 и 64, 65, 66.
-
Таблица Принятия Решений (Decision Table):
- Цель: Систематически проверить комбинации условий и соответствующих действий.
-
Пример для функции скидки: Зарегистрирован? Сумма > 1000? Ожидаемая скидка Да Да 10% Да Нет 5% Нет Да 5% Нет Нет 0%
-
Попарное Тестирование (Pairwise):
- Цель: Резко сократить количество комбинаций, тестируя каждую пару значений параметров хотя бы один раз. Эффективно для систем с множеством параметров.
Пример кода на Python (pytest) для проверки граничных значений:
# Функция, которую тестируем
def is_age_valid(age: int) -> bool:
return 18 <= age <= 65
# Тесты для граничных значений
def test_age_boundary_values():
# Нижняя граница (минимум, ниже, выше)
assert not is_age_valid(17) # Невалидно, ниже минимума
assert is_age_valid(18) # Валидно, минимум
assert is_age_valid(19) # Валидно, чуть выше минимума
# Верхняя граница (ниже, максимум, выше)
assert is_age_valid(64) # Валидно, чуть ниже максимума
assert is_age_valid(65) # Валидно, максимум
assert not is_age_valid(66) # Невалидно, выше максимума Ответ 18+ 🔞
О, смотри-ка, пришёл человек с умным видом и спрашивает про тест-дизайн. Ну что ж, расскажу, как мы тут, в нашем ебучем цифровом зоопарке, зверей проверяем, чтобы они не насрали посреди ковра. Техники, блядь, основные, без которых — нихуя не выловишь.
Первое, что у нас есть — это Эквивалентное Разделение. Суть проще пареной репы, но мозги выносит у многих. Берёшь все возможные вводы и делишь на кучки, где система должна вести себя одинаково. Зачем? Да чтобы не тестировать каждое число от минус бесконечности до плюс, ёпта! Пример? Пожалуйста. Поле «Возраст», от 18 до 65.
- Нормальная кучка (валидный класс): от 18 до 65. Сюда тыкаем, скажем, 30. Должно работать.
- Левая невалидная кучка (меньше): всё, что до 18. Тыкаем 10. Должно ругаться.
- Правая невалидная кучка (больше): всё, что после 65. Тыкаем 70. Должно тоже ругаться, ибо пенсия, блядь.
Второе — Анализ Граничных Значений. Это, сука, святое! Потому что все баги, как тараканы, сидят именно на границах. Не в середине диапазона, а вот на этих самых стыках, где 17 превращается в 18, а 65 — в 66. Вот их и долбим:
- Около нижней границы: 17 (нет), 18 (да), 19 (да).
- Около верхней границы: 64 (да), 65 (да), 66 (нет).
Третья штука — Таблица Принятия Решений. Когда логика ветвится, как рога у ёбаного оленя, и нужно понять, какая комбинация условий к какому действию приводит. Чтоб не получилось, что скидку дали тому, кто не зарегистрирован и купил на 500 рублей. Составляем табличку, блядь, как в школе:
| Зарегистрирован? | Сумма > 1000? | Чё будет? |
|---|---|---|
| Да | Да | 10% скидки, красава |
| Да | Нет | 5%, так, сойдёт |
| Нет | Да | 5%, и на том спасибо |
| Нет | Нет | 0%, иди нахуй |
И наконец, четвёртое — Попарное Тестирование. Это для совсем уже ебнутых случаев, когда параметров — овердохуища. Комбинаций всех возможных — миллиард, тестировать до второго пришествия. А тут приходит эта техника и говорит: «А давайте проверим не все комбинации, а так, чтобы каждая пара значений хоть разок встретилась». И, сука, работает! Вылавливает кучу багов, а тестов в разы меньше.
Ну и куда же без кода, чтобы не быть голословным, как этот... Герасим, блядь. Вот тебе пример, как эти границы на Python (с pytest) прощупать:
# Функция, которую тестируем
def is_age_valid(age: int) -> bool:
return 18 <= age <= 65
# Тесты для граничных значений
def test_age_boundary_values():
# Нижняя граница (минимум, ниже, выше)
assert not is_age_valid(17) # Невалидно, ниже минимума
assert is_age_valid(18) # Валидно, минимум
assert is_age_valid(19) # Валидно, чуть выше минимума
# Верхняя граница (ниже, максимум, выше)
assert is_age_valid(64) # Валидно, чуть ниже максимума
assert is_age_valid(65) # Валидно, максимум
assert not is_age_valid(66) # Невалидно, выше максимума
Вот так вот, нехитрыми приёмами и находим, где у нас софт спотыкается на ровном месте. А то бывает — вроде всё работает, а на границе в 65 лет и 1 день система считает тебя древним старцем и отправляет на свалку истории. Пиздец, а не логика.