Перейти до основного змісту

Jest 14.0: Тестування знімками React

· 5 хвилин читання

Одним з принципів Jest є надання інтегрованого досвіду "нульової конфігурації". Ми хочемо зробити написання якісних тестів якомога більш безпроблемним. Ми помітили, що коли розробники забезпечені готовими інструментами, вони пишуть більше тестів, що в результаті призводить до стабільної бази коду.

Одне зі значних відкритих питань полягало в тому, як ефективно писати тести React. Існує багато інструментів, таких як ReactTestUtils та enzyme. Обидва інструменти чудові й активно використовуються. Однак від розробників часто чулось, що вони витрачають більше часу на написання тесту, ніж самого компоненту. В результаті, багато людей взагалі припинили писати тести, що врешті-решт призвело до нестабільності. Розробники пояснили нам: все, чого вони хотіли - це переконатися, що їхні компоненти не змінюються несподівано.

Разом з командою React, ми створили новий відтворювач тестів для React та додали тестування знімками в Jest. Розглянемо наступний приклад тесту для простого компоненту Link:

import renderer from 'react-test-renderer';
test('Link renders correctly', () => {
const tree = renderer
.create(<Link page="http://www.facebook.com">Facebook</Link>)
.toJSON();
expect(tree).toMatchSnapshot();
});

Під час першого запуску цього тесту, Jest створює снепшот файл, який виглядає наступним чином:

exports[`Link renders correctly 1`] = `
<a
className="normal"
href="http://www.facebook.com"
onMouseEnter={[Function bound _onMouseEnter]}
onMouseLeave={[Function bound _onMouseLeave]}>
Facebook
</a>
`;

Знімок варто додавати в систему контролю версій разом зі змінами коду. Ми використовуємо pretty-format, щоб зробити знімки зручними для читання під час перевірки коду. Під час наступних запусків теста Jest просто порівняє результат роботи компонента зі збереженим знімком. Якщо вони співпадуть, тест пройде. Якщо вони не збігаються, реалізація змінилась та треба оновити знімок за допомогою jest -u, або ж під час виконання тесту у вашому коді знайдено помилку, яку потрібно виправити.

Якщо ми змінимо адресу, на яку в нашому прикладі вказує компонент Link, Jest виведе на екран:

snapshot-testing

Тепер ви знаєте, що вам необхідно прийняти зміни за допомогою jest -u або виправити компонент, якщо зміни були неочікуваними. Аби спробувати цей функціонал, зробіть клон прикладу знімку, змініть компонент Link і запустіть Jest. Ми оновили React Tutorial з новою інструкцією для тестування знімками.

Ця функцію розробили Ben Alpert і Cristian Carlesso.

Експериментальна підтримка React Native

Створивши відтворювач тестів, який не націлений на конкретну платформу, ми нарешті мали змогу підтримувати повну, не імітовану версію React Native. Ми раді запустити експериментальну підтримку React Native для Jest за допомогою пакету jest-react-native.

Ви можете почати використовувати Jest з react-native, запустивши yarn add --dev jest-react-native та додавши пресет до конфігурації Jest:

"jest": {
"preset": "jest-react-native"
}
info

Наразі, пресет реалізує мінімальний набір конфігурацій, необхідний для початку тестування з React Native. Ми сподіваємося на внески спільноти для покращення цього проєкту. Будь ласка, спробуйте цю опцію та повідомте нас про проблеми або зробіть свій внесок!

Чому тестування знімками?

Для глобальних програм Facebook ми використовуємо систему під назвою "тестування знімками": тестову систему, що відтворює UI компоненти, робить знімок і згодом порівнює записаний знімок зі змінами, зробленими розробниками. Якщо знімки не збігаються, є два варіанти: зміни є неочікуваними або знімок можна оновити згідно з новою версією UI компонента.

Хоча це було бажане рішення для вебдодатків, ми також знайшли багато проблем системних тестів, які вирішуються тестами з інтеграцією знімків:

  • Однорідність: Через те, що тести запускаються у командному рядку замість реального браузера або телефону, виконавець тестів не повинен чекати збірки, запускати браузер, завантажувати сторінку та інтерфейс для отримання очікуваного стану компонента, який, як правило, неоднорідний, тож результати тестів виходять нечіткими.
  • Велика швидкість ітерації: Замість того, щоб чекати хвилини чи навіть години, розробники хочуть отримати результати менш ніж за секунду. Якщо тести запускаються не так швидко, як в більшості системних фреймворків, розробники взагалі їх не запускатимуть або ж не писатимуть в першу чергу.
  • Налагодження: Можна з легкістю перейти до коду тесту інтеграції в JS замість спроб відтворити сценарій тестового знімка та проводити налагодження на основі візуальної різниці.

Оскільки ми вважаємо, що тестування знімками може принести користь не тільки в Jest, ми виділили цю функцію в пакет jest-snapshot. Ми раді співпрацювати зі спільнотою, щоб зробити її універсальнішою, аби її можна було використовувати з іншими виконавцями тестів, а також ділитися з ними концепціями та інфраструктурою.

Також, хотілося б навести цитату розробника Facebook, який описує як тестування знімками змінило його досвід модульного тестування:

“Один з найскладніших аспектів мого проєкту - синхронізоване зберігання вхідних і вихідних файлів для кожного тестового випадку. Кожна маленька зміна функціоналу може призвести до зміни всіх вихідних файлів. З тестуванням знімками мені не потрібні вихідні файли, Jest вільно створює знімки! Я можу просто перевіряти, як Jest оновлює знімки, замість внесення змін вручну.” - Kyle Davis працює над fjs.

Що буде далі для Jest

Нещодавно Aaron Abramov повноцінно приєднався до команди Jest для вдосконалення наших системної та інтеграційної тестової інфраструктури для рекламних продуктів Facebook. Протягом наступних кількох місяців команда Jest планує значні покращення в наступних сферах:

  • Заміна Jasmine: Jasmine вповільнює нас і не розвивається достатньо активно. Ми почали заміну всіх матчерів Jasmin та з нетерпінням очікуємо початку додавань нових функцій, аби видалити цю залежність.
  • Покриття коду: Коли Jest створювався, інструменти, подібні до babel, не існували. Наша підтримка покриття коду має купу крайніх випадків та не завжди працює належним чином. Ми переписуємо цей момент, щоб розв'язати поточні проблеми з покриттям.
  • Досвід розробника: Від покращення процесу налаштування та налагодження до покращення командного рядка та поповнення документації.
  • Імітація: Система імітацій, особливо ручних, заплутана та працює неідеально. Ми сподіваємося зробити її більш строгою та зрозумілою.
  • Продуктивність: В роботі подальші покращення продуктивності, особливо для великих кодових баз.

Як завжди, якщо у вас є питання або якщо ви готові допомогти, будь ласка, зв'яжіться з нами!