Классы и границы: данные важнее количества
Строим небольшой обоснованный набор для Unicode, пробелов и длины полей.
- Выделить классы по правилам длины и типа.
- Развести кодовые точки, кодовые единицы и видимые символы.
- Проверить сгенерированные данные до использования.
Разделите оси, прежде чем просить примеры
У заголовка есть несколько независимых свойств: тип, длина и содержимое после trim при публикации. Пустая строка, null и строка из пробелов не равнозначны. Первая нарушает минимальную длину R1; null нарушает тип; пробелы могут пройти сохранение draft, но не публикацию по R5. Если попросить ИИ «десять невалидных названий», он легко смешает эти причины и оставит без внимания верхнюю границу.
Классы эквивалентности полезны, когда у элементов группы ожидается одинаковое поведение относительно выбранного правила. Для длины title это 0, диапазон 1–80 и 81+. Для description —0–2000 и 2001+. Выбор одного внутреннего значения не проверяет обе границы. Сначала назовите класс и основание, затем выберите представителя. Разные тесты могут покрывать разные условия, даже если текст на экране выглядит похоже.
Какую длину считать
OD-1 определяет кодовые точки Unicode. В JavaScript строковое length считает кодовые единицы UTF-16, поэтому для символа 😀 возвращает 2. Array.from(value).length для него даёт 1 кодовую точку. Визуально один символ тоже может состоять из нескольких кодовых точек: e плюс комбинируемый акцент — две. Нельзя без требования заменить эту модель количеством графем или выполнить нормализацию. Пример нужен не ради экзотики, а чтобы обнаружить расхождение валидаторов браузера и сервера.
Для границы 80 подготовьте строки с 79,80 и 81 кодовой точкой. Отдельно возьмите 0,1,2 у нижней границы. Строку из 80 emoji проверьте генератором, а не по подписи модели. У description аналогично проверьте 1999,2000,2001 и пустую строку. Не объединяйте одновременно невалидный title и слишком длинное description в основной проверке: иначе первый отказ скроет второй валидатор.
Проверяем фактическую длину
const cp = value => Array.from(value).length;
const title80 = '😀'.repeat(80);
console.log(title80.length); // 160 кодовых единиц
console.log(cp(title80)); // 80 кодовых точек
console.log(cp('e\u0301')); // 2, хотя выглядит как é
console.log(cp('')); // 0Минимальная модель
| Данные | Сохранение draft | Публикация |
|---|---|---|
| title="А" | Допустимо R1 | Допустимо при прочих условиях |
| title=" " | Допустимо R1 | Отказ 422 по R5 |
| title="😀"×80 | Допустимо R1 | Допустимо при прочих условиях |
| title="А"×81 | Отказ 422 | До публикации такой draft не создаётся |
| description="" | Допустимо R2 | Не мешает публикации |
Как использовать помощника
Попросите ассистента вернуть не только значения, но и правило, способ генерации и ожидаемый результат на каждой операции. Затем независимо выполните генератор и пересчитайте длину. Особенно внимательно проверьте «81 символ» и экранированные последовательности: текст \u0041 и значение A имеют разное представление и длину. Сохраните проверенные фикстуры вместе с версией OD-1.
После этого ищите пропуски по модели, а не по размеру списка. Сто случайных длин внутри 1–80 не заменяют проверку 81. С другой стороны, границы строки не покрывают доступ к чужому объекту. Для прав в следующем уроке появится другая модель. Отчёт должен честно назвать, какую именно область покрывает этот набор.
ЗАДАЧА Предложи классы и границы для двух строковых полей. КОНТЕКСТ OD-1; длина в кодовых точках Unicode, save и publish — разные операции. ВХОДНЫЕ ДАННЫЕ Учебный продукт OrbitDesk, версия правил OD-1. Все имена и данные вымышлены. R1: title — строка от 1 до 80 кодовых точек Unicode включительно. При сохранении пробелы автоматически не удаляются. R2: description — строка от 0 до 2000 кодовых точек. Пустая строка разрешена, null не является строкой. R3: новая задача получает состояние draft и автора из серверной сессии. R4: читать draft может только автор; published виден всем вошедшим участникам той же команды. Роль editor сама по себе не открывает чужой draft. R5: опубликовать draft может автор или editor из той же команды. При публикации title.trim() не должен быть пустым. trim — поведение JavaScript String.prototype.trim; сохранённое значение не изменяется. R6: публикация переводит draft в published. Повторная публикация published отклоняется с 409, состояние не меняется. R7: в учебном API проверки публикации идут в порядке: сессия 401 → существование/команда 404 → права 403 → состояние 409 → данные 422 → успех 200. Это контракт кейса, не универсальное правило API. R8: создание (create): без сессии — 401; неверный тип или длина title/description — 422 без создания; переданные клиентом authorId, teamId или state отклоняются с 422; успех — 201 и одна новая задача draft с новым ID, автором из сессии и исходными строками без trim. Чтение (read): без сессии — 401; неизвестный объект, чужая команда или чужой draft — 404 без содержимого задачи; разрешённое чтение — 200 с объектом. R9: отказ в create/read/publish не меняет объекты; read не меняет данные. Успешный publish меняет только состояние существующей задачи, сохраняя ID, автора, title и description; дополнительная задача не создаётся. Акторы и фикстуры: Анна — user, автор t1, команда A; Борис — user, не автор t1, команда A; Вера — editor, не автор t1, команда A; Глеб — editor, команда B. Дина — editor и автор отдельной задачи t2 команды A для проверки сочетания автор-editor. Если не указано иное, t1 — draft с title="Проверить экспорт" и description="". Обозначения t1/t2 — учебные псевдонимы фактически полученных ID, а не требование к генератору ID. Перед независимым тестом фикстура восстанавливается. ОГРАНИЧЕНИЯ Не считай UTF-16 length эквивалентом кодовых точек. Не объединяй два невалидных поля в основном тесте. ОЖИДАЕМЫЙ ФОРМАТ Таблица: правило, класс, генератор, фактическая длина, операция, ожидаемый результат. Отдельно список непокрытых рисков.
Используйте разрешённый ИИ-сервис. Не отправляйте рабочие секреты и персональные данные.
Источники и проверка фактов
ISTQB — CTFL v4.0, программа и материалыРазделы анализа и проектирования тестов; курс использует собственные учебные примеры, не является подготовкой к сертификации.ECMAScript: обработка строк и trimПервичный источник JavaScript: строковый итератор и String.prototype.trim. Единица длины в самом OrbitDesk задаётся учебным R1/R2.Авторский учебный материал · Редакция QA Orbit · версия 2026-10-28.1