Пользовательский интерфейс Keboola Connection (keboola/kbc-ui) восходит к 2015 году, а некоторые компоненты React написаны на Coffeescript. Мы решили переписать эти компоненты на JSX.
Поскольку не существует конвертера, способного выполнять эту работу автоматически (или с удовлетворительным результатом), мы согласились делать это вручную, небольшими шагами. Когда нам нужно что-то изменить (или исправить) в .coffee
файле, мы переписываем его в .jsx
, если это возможно.
Давайте назовем компонент React черным ящиком. Этот черный ящик отвечает за одну работу — визуализацию дерева React (в основном HTML). Этот так называемый HTML-вывод может отличаться в зависимости от переданных реквизитов, поэтому мы хотим стабилизировать это поведение и быть уверенными, что оно не изменится со временем (особенно при переписывании на JSX).
Итак, как мы это делаем? С написанием тестов.
Мы используем библиотеку Jest для запуска тестов. В этом случае одна специальная функция поможет нам протестировать упомянутое выше поведение черного ящика — Тестирование моментальных снимков. работает как прежде.
Решил переписать CurrentUser
компонент. Он отвечает за отображение информации о пользователе (аватар, имя и адрес электронной почты) и простое «выпадающее меню» (сейчас это не так важно).
Поэтому я написал для него тест.
import React from 'react'; import CurrentUser from './CurrentUser'; import { fromJS } from 'immutable'; // few variables defined here, used later to pass as props describe('<CurrentUser />', function() { it('should render 40x40 icon, with email, no admin links, no maintainers, dropup false (no mode passed)', function() { shallowSnapshot( <CurrentUser user={user} maintainers={fromJS([])} urlTemplates={urlTemplates} canManageApps={false} dropup={true} /> ); }); // more tests here, not mentioned for simplicity });
Функция shallowSnapshot
отвечает за рендеринг снимка и сравнение его с существующим. Первый запуск теста создаст снимок (файл .snap
), который будет сохранен в каталоге __snapshots__
.
Вот предварительный просмотр снимка:
exports[`<CurrentUser /> should render 40x40 icon, with email, no admin links, no maintainers, dropup false (no mode passed) 1`] = ` <div className="kbc-user" onClick={[Function]}> <img className="kbc-user-avatar" height={40} src="/user.png" width={40} /> <div> <strong> dev user </strong> <DropdownButton ... </div> `;
В Jest есть режим часов. Это режим, в котором тесты выполняются каждый раз, когда обнаруживается изменение связанных файлов.
Мы запускаем этот режим, запуская команду yarn tdd
(наш псевдоним для jest
с параметром --watch
).
А дальше начинается скучная часть, с этого момента мы можем начать переписывать на JSX.
После нескольких итераций, когда мы увидели, что тесты не пройдены, мы должны получить новый файл JSX и увидеть, что тесты снова пройдены.
TL;DR
- Напишите тесты и убедитесь, что вы охватили достаточное количество случаев, особенно случаев без передачи необязательных реквизитов.
- Запустите Jest в режиме просмотра (при первом запуске создаются снимки)
- Переписывайте, пока не увидите, что тесты снова проходят
- Выгода! :)