Storybook + Tests = Принудительная изоляция как система
Хороший и удобный инструмент, соединяющий дизайнеров с командой разработки и тестировщиками, да может и проджект заглянет потестить интерфейс.
Завершая практический аспект, расскажем и о тестировании.
Итак, пристегнулись, поехали!
Редизайн, а точнее его несколько итераций, убивал фронтенд на проекте (где работал наш лидер команды, пара фуллстек JS разработчиков и ПМ/QA).
Storybook его спас.
1. Storybook задаёт правила. Тесты их проверяют.
1.1 Пример разработки без изоляции:
Тест падает не из-за бага в кнопке.
Тест падает из-за бага в системе.
1.2 Пример разработки с использованием Storybook:
В Storybook компонент живёт один.
Или с явно указанными зависимостями.
Это не просто фича.
Это архитектурное ограничение.
1.3 Разница в тестировании на конкретном примере с кнопкой:
В качестве промежуточного итога, отметим что, раньше была система из 156 UI компонентов, которую мы пытались тестировать, так что бы написанные на Jest тесты перекрывали друг друга. А теперь, после разбиения компонентов на простые и следуя правилам Storybook, мы тестируем каждый элемент/юнит системы и тем самым покрываем все элементы, избегая нахлеста и зазоров в тестировании.
2. «Зачем тесты, если в Storybook уже есть Actions?»
2.1 Хороший вопрос. Но Actions ≠ Tests. После заведения (и поддержания в актуальном состоянии ваших UI компонентов в Storybook, а это та еще работа!) в интерфейсе Storybook необходимых юнитов, по каждому из них можно открыть вкладку Actions. Имея поведение юнита (например кнопки, поля ввода и тд), то есть заранее прописав в кодовой базе проекта события взаимодействия с юнитами в файлах с постфиксом .storybook (чтобы они автоматически подтянулись в Storybook интерфейсе), мы только обозначаем то, что мы отслеживаем/обрабатываем конкретное взаимодействие с юнитом.
Actions в Storybook:
Тесты:
Actions демонстрируют поведение.
Тесты гарантируют корректность.
Actions покажут зелёную галочку.
Тесты покажут красный крестик, если что-то сломано.
2.2 Одна система. Две роли: демонстрация и проверка
По итогу получаем систему, которая описывает ожидаемое взаимодействие с UI компонентом в Storybook, то есть например мы явно указали, что кнопка кликабельна или нет, и это взаимодействие служит чеклистом для написания тестов.
Разработчик следуя демо (ожидаемому взаимодействию) пишет тест, таким образом Actions показывают, тесты проверяют.
3. Что это даёт?
Для целей тестирования:
- Тесты не падают из-за соседних компонентов;
- Каждый тест проверяет одну вещь;
- Все состояния и взаимодействия уже описаны в стори.
Для целей рефакторинга:
- Меняешь реализацию → стори прежние;
- Storybook показывает: внешне выглядит согласно дизайну;
- Тесты подтверждают: внутри работает ожидаемо.
4. Почему это работает?
4.1 Декомпозиция по умолчанию (Storybook заставляет нас разбивать на юниты)
Сложную стори не сделать → сложный компонент не сделать.
4.2 Явные зависимости (в Storybook явно указано стилевые зависимости и варианты)
Нужен ThemeProvider → он в стори. Не указан → не нужен.
4.3 Actions для демонстрации визуала, тесты - для гарантий.
5. Правила
Если компонента нет в Storybook - его нет в коде.
Если состояния нет в Storybook - его нет в компоненте.
Если теста нет на стори - состояния не существует.
6. Итог
Storybook это система принудительной изоляции.
Изолированный компонент:
1. Легко тестировать
2. Легко изменять
3. Легко выбросить
Неизолированный компонент - технический долг.
Который убивает фронтенд.
Вы уже тестируете систему. Не просто кнопку, а каждый вариант из Storybook. Каждое состояние. Каждый пропс. Это и есть система.