tradein/frontend: у фронтенда trade-in ноль проверок поведения — при том что сегодня через него прошли три видимых пользователю изменения #2766

Closed
opened 2026-08-06 23:31:02 +00:00 by bot-backend · 2 comments
Collaborator

Найдено при аудите охвата проверок (#2722). Не дефект и не регресс — пробел, который стоит назвать, потому что он единственный такого размера.

Замер

Три корпуса проверок, 8 792 штуки:

backend/tests                  226 файлов
tradein-mvp/backend/tests      233 файла
tradein-mvp/browser              7 файлов   (подключены к сборке вчера, #2726)

frontend/src/**/__tests__       32 файла, 264 проверки, все зелёные

tradein-mvp/frontend            ТЕСТОВ НЕТ ВООБЩЕ

У фронтенда trade-in исполняются только проверка типов и статический анализ. Ноль проверок поведения.

Для сравнения: у соседнего фронтенда (Site Finder) — 264 проверки в 32 файлах, и ни одна не пропускается.

Почему это стоит внимания именно сейчас

Сегодня через фронтенд trade-in прошли изменения, которые видит пользователь:

  • гейт «медианного торга» — показываемых чисел стало вдвое меньше (64 → 32 группы); проверено на бэкенде, на фронте — глазами;
  • поле серии дома выводится на экран и всегда пусто (#2700) — обнаружено разбором данных, не проверкой;
  • сообщение о слишком частых попытках входа обрабатывается фронтом (#2712) — проверено чтением кода.

Каждое из трёх — ровно то, что ловится дешёвой проверкой компонента и не ловится ничем другим, кроме внимательного человека.

Что предлагается

Не «покрыть фронтенд тестами» — это задача не на один заход и не факт что окупится целиком. Предлагается начать с того, что уже ломалось:

  1. Отображение отсутствующего значения — что показывает карточка, когда поле пусто (случай серии дома). Класс «пришло пусто, нарисовали пусто» встречался сегодня трижды.
  2. Гашение недостоверного числа — что видит пользователь вместо «медианного торга», когда гейт его погасил, и что написано в объяснении.
  3. Обработка отказа по частоте на форме входа.

Три компонента, три проверки. Инфраструктура уже есть — vitest настроен и работает у соседнего фронтенда, конфигурацию можно взять оттуда.

Оговорка

Пробел «тестов нет» отличается от сегодняшних находок «тесты есть и молча не исполняются» (#2722, #2740, #2729). Тот класс опаснее: там проверка создаёт ложную уверенность. Здесь уверенности нет, и это честнее — просто дороже в эксплуатации.

Связано: #2722, #2672, #2700, #2712.

Найдено при аудите охвата проверок (#2722). Не дефект и не регресс — пробел, который стоит назвать, потому что он единственный такого размера. ## Замер Три корпуса проверок, 8 792 штуки: ``` backend/tests 226 файлов tradein-mvp/backend/tests 233 файла tradein-mvp/browser 7 файлов (подключены к сборке вчера, #2726) frontend/src/**/__tests__ 32 файла, 264 проверки, все зелёные tradein-mvp/frontend ТЕСТОВ НЕТ ВООБЩЕ ``` У фронтенда trade-in исполняются только проверка типов и статический анализ. **Ноль проверок поведения.** Для сравнения: у соседнего фронтенда (Site Finder) — 264 проверки в 32 файлах, и ни одна не пропускается. ## Почему это стоит внимания именно сейчас Сегодня через фронтенд trade-in прошли изменения, которые видит пользователь: - гейт «медианного торга» — **показываемых чисел стало вдвое меньше** (64 → 32 группы); проверено на бэкенде, на фронте — глазами; - поле серии дома выводится на экран и всегда пусто (#2700) — обнаружено разбором данных, не проверкой; - сообщение о слишком частых попытках входа обрабатывается фронтом (#2712) — проверено чтением кода. Каждое из трёх — ровно то, что ловится дешёвой проверкой компонента и не ловится ничем другим, кроме внимательного человека. ## Что предлагается Не «покрыть фронтенд тестами» — это задача не на один заход и не факт что окупится целиком. Предлагается **начать с того, что уже ломалось**: 1. Отображение отсутствующего значения — что показывает карточка, когда поле пусто (случай серии дома). Класс «пришло пусто, нарисовали пусто» встречался сегодня трижды. 2. Гашение недостоверного числа — что видит пользователь вместо «медианного торга», когда гейт его погасил, и что написано в объяснении. 3. Обработка отказа по частоте на форме входа. Три компонента, три проверки. Инфраструктура уже есть — vitest настроен и работает у соседнего фронтенда, конфигурацию можно взять оттуда. ## Оговорка Пробел «тестов нет» отличается от сегодняшних находок «тесты есть и молча не исполняются» (#2722, #2740, #2729). Тот класс опаснее: там проверка **создаёт ложную уверенность**. Здесь уверенности нет, и это честнее — просто дороже в эксплуатации. Связано: #2722, #2672, #2700, #2712.
Author
Collaborator

Working on this in PR #2769 — три проверки (SaleShareList / StreetDealsCard+mapHistory / LoginPage 429) + шаг npm test в ci-tradein.yml. Каждая проверена на слом продуктового кода.

Working on this in PR #2769 — три проверки (SaleShareList / StreetDealsCard+mapHistory / LoginPage 429) + шаг `npm test` в `ci-tradein.yml`. Каждая проверена на слом продуктового кода.
Author
Collaborator

ЗАКРЫТО — три проверки живут, бегут блокирующе и КРАСНЕЮТ на сломанном продуктовом коде

Наличия тестов недостаточно: задача сама предупреждала, что опаснее всего проверка, создающая ложную уверенность. Поэтому проверял двумя шагами.

1. Сьют существует и зелёный

Собрал чистое дерево фронтенда trade-in (без локального node_modules), поставил зависимости так же, как это делает сборка (npm install --legacy-peer-deps), и прогнал:

✓ src/components/trade-in/__tests__/SaleShareList.test.tsx   (5 tests) 124ms
✓ src/components/trade-in/__tests__/StreetDealsCard.test.tsx (4 tests)  88ms
✓ src/app/login/__tests__/LoginPage.test.tsx                 (4 tests) 242ms

Test Files  3 passed (3)      Tests  13 passed (13)

Ноль пропусков — что для vitest важно отдельно: сторожа пропусков, как skip_allowlist.txt на бэкенде, тут нет.

Шаг блокирующий: .forgejo/workflows/ci-tradein.yml, job frontend-checks, run: npm test — между type-check и lint, срабатывает по фильтру tradein-mvp/frontend/**.

2. Проверка на слом — сломал продуктовый код сам

Взял ровно тот класс дефекта, ради которого писался тест №1 («пришло пусто, нарисовали пусто»): убрал .filter(Boolean) из склейки колонки «Дом» в SaleShareList.tsx.

FAIL  SaleShareList — колонка «Дом» при пустом поле
      > пустая серия не съедает остальные поля дома

AssertionError: expected ' ·  · 9 эт. · ' to be '9 эт.'

Test Files  1 failed (1)      Tests  4 failed | 1 passed (5)

Тест назвал именно висящий разделитель — то самое, что отличает «нарисовали пусто» от «нарисовали дыру», и что toContain пропустил бы. Сторож различает два состояния кода, а не подтверждает сам себя.

Что это меняет по числу

Было: tradein-mvp/frontend — ноль проверок поведения при 8 792 в остальных корпусах. Стало: 13 проверок в 3 файлах, блокирующие до мержа. Это не «покрыт фронтенд», а ровно то, что предлагала задача — начать с того, что уже ломалось.

PR: #2769.

## ЗАКРЫТО — три проверки живут, бегут блокирующе и КРАСНЕЮТ на сломанном продуктовом коде Наличия тестов недостаточно: задача сама предупреждала, что опаснее всего проверка, создающая ложную уверенность. Поэтому проверял двумя шагами. ### 1. Сьют существует и зелёный Собрал чистое дерево фронтенда trade-in (без локального `node_modules`), поставил зависимости так же, как это делает сборка (`npm install --legacy-peer-deps`), и прогнал: ``` ✓ src/components/trade-in/__tests__/SaleShareList.test.tsx (5 tests) 124ms ✓ src/components/trade-in/__tests__/StreetDealsCard.test.tsx (4 tests) 88ms ✓ src/app/login/__tests__/LoginPage.test.tsx (4 tests) 242ms Test Files 3 passed (3) Tests 13 passed (13) ``` Ноль пропусков — что для vitest важно отдельно: сторожа пропусков, как `skip_allowlist.txt` на бэкенде, тут нет. Шаг блокирующий: `.forgejo/workflows/ci-tradein.yml`, job `frontend-checks`, `run: npm test` — между type-check и lint, срабатывает по фильтру `tradein-mvp/frontend/**`. ### 2. Проверка на слом — сломал продуктовый код сам Взял ровно тот класс дефекта, ради которого писался тест №1 («пришло пусто, нарисовали пусто»): убрал `.filter(Boolean)` из склейки колонки «Дом» в `SaleShareList.tsx`. ``` FAIL SaleShareList — колонка «Дом» при пустом поле > пустая серия не съедает остальные поля дома AssertionError: expected ' · · 9 эт. · ' to be '9 эт.' Test Files 1 failed (1) Tests 4 failed | 1 passed (5) ``` Тест назвал именно висящий разделитель — то самое, что отличает «нарисовали пусто» от «нарисовали дыру», и что `toContain` пропустил бы. Сторож различает два состояния кода, а не подтверждает сам себя. ### Что это меняет по числу Было: `tradein-mvp/frontend` — ноль проверок поведения при 8 792 в остальных корпусах. Стало: 13 проверок в 3 файлах, блокирующие до мержа. Это не «покрыт фронтенд», а ровно то, что предлагала задача — начать с того, что уже ломалось. PR: #2769.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#2766
No description provided.