← На главную

foldkit: Story-тесты update и Scene-эмуляция UI без браузера

24.07.2026 15:24 · hackernews

Библиотека foldkit предлагает два вида тестов для приложений на Elm-подобной архитектуре — Story и Scene. Первый проверяет бизнес-логику в изоляции, второй симулирует действия пользователя и сверяет экран. Оба работают на vitest, а весь код остаётся в одном рантайме без поднятия браузера.

В тесте Story разработчики запускают функцию update с начальной моделью через Story.with(model). Затем в систему посылается сообщение SubmittedWeatherForm(). Сразу после этого проверяется, что model.weather._tag сменился на 'WeatherLoading'. Дальше foldkit ждёт, что update вернёт ровно одну команду — FetchWeather, — и ловит её через Story.Command.expectExact. Когда тест вручную резолвит команду успешным ответом SucceededFetchWeather({ weather }), модель оказывается в состоянии 'WeatherSuccess'. Вся последовательность — отправка сообщения, проверка модели, ожидание команды и резолв — записывается цепочкой в Story.story.

Тест Scene, напротив, идёт через view. Он стартует с начальной model, а затем эмулирует реальный сценарий: Scene.type вводит в поле с label 'Zip code' строку '90210', а Scene.click жмёт на кнопку с ролью button и именем 'Get Weather'. Сразу после клика Scene.expect убеждается, что на экране появилась кнопка с текстом 'Loading...'. Параллельно Scene.Command.expectExact фиксирует, что была отправлена та же команда FetchWeather. После ручного резолва команды результатом SucceededFetchWeather({ weather }), тест сужает область до элемента с ролью 'article' и внутри находит конкретные строки: 'Beverly Hills, California' и '72°F'. Так за один проход проверяется и анимация загрузки, и финальный вывод данных.

Оба подхода используют одни и те же сущности — модель, сообщения и команды — без дополнительных моков. Story фокусируется на переходах состояний, а Scene — на том, что видит пользователь после каждого действия. Эта комбинация позволяет покрыть логику и вёрстку одновременно, не теряя скорость юнит-тестов.

Читать оригинал →