Files
healthlog/docs/conventions/testing.md
T
av 1b649ba3d5 добавлен словарь категориальных значений HAE → коды HealthKit
- фазы сна, контекст пульса и имена тренировок попадают в реестр
  `category_value` (миграция 00010): строка хранится дословно, выведенный код
  лежит рядом отдельной записью, а не полем внутри точки
- словарь и синонимы кодов живут в бинаре (`internal/healthkit`); локаль из
  `Accept-Language` сужает поиск, но в ключ реестра не входит — заголовков в
  сыром архиве нет
- наблюдение входит в отпечаток витрины, выведенный код — нет: он производная
  от словаря, а не от журнала
2026-08-04 07:32:19 +03:00

42 lines
4.7 KiB
Markdown

# Тесты
- Тесты на разбор формата HAE держим на **реальных пакетах**, сложенных в
`testdata` (с вычищенными токенами). Документация формата ненадёжна —
источником истины служат живые данные.
- Проверяем идемпотентность: повторный разбор того же пакета не меняет
витрину.
- **Где код выбирает между двумя версиями одних данных, тест обязан прогнать
обе стороны и хотя бы одну перестановку трёх.** Пример на паре доказывает
коммутативность и молчит про ассоциативность, а сломаться правило может
именно на ней: полнота — частичный порядок, тай-брейк — тотальный, и их
попарная свёртка дала нетранзитивное отношение победы, из-за которого одна
и та же доставка меняла витрину при каждой пересборке. Ревью дизайна этого
не увидело, ревью кода увидело только перебором троек. Правилом линтера не
выражается — отсюда проза.
- **В тот же перебор обязана входить версия с содержимым, равным одной из уже
присланных, и пара «равная каноническая форма, разные байты».** Три версии с
разными хешами ветку «содержание равно» не посещают ни разу — а именно на ней
устаревал провенанс, и живая витрина расходилась с пересборкой молча. Пара с
равной формой ловит другое: неединственный минимум, при котором победителем
оказывается просто первый в срезе, то есть порядок элементов на проводе.
- **Изменение правила разбора или слияния сопровождается замером на живом
архиве, и ответ «пересворачивать нечего» произносится с числом.** Утверждение
без числа не отличается от предположения, а цена ошибки здесь — необратимое
решение о судьбе тел.
- **Значение, попадающее в ключ витрины или в словарь, приёмочный тест берёт из
`testdata`, а не из литерала в тесте.** Литерал, набранный руками, не
воспроизводит невидимые символы источника — Apple шлёт неразрывные пробелы
внутри своих строк (находка 24), — и совпадение теста с реализацией доказывает
только согласие автора с самим собой.
- **Утверждение о таблице-константе обходит саму таблицу, а не её видимые
следствия.** Проверка «таблица синонимов плоская», написанная через
экспортированные функции, обходит лишь записи, достижимые из словаря: с
неплоской таблицей она остаётся зелёной (воспроизведено). Такие утверждения
живут во внутреннем тесте пакета и перебирают саму структуру.
- **Тест «в логе нет значения» проверяет запись без служебных полей, а не сырой
буфер.** Метка времени содержит доли секунды, поэтому искомая подстрока
находится в ней сама: проверка на «5.1» краснела примерно раз на сотню
прогонов от хода часов, а не от утечки. Разбираем запись, выбрасываем `time`
и ищем в остатке. Правило общее — таких тестов будет больше (токены, тела
запросов, координаты объектов).