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

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

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

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

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

Разом з командою React, ми створили новий відтворювач тестів для React та додали тестування знімками в Jest. Consider this example test for a simple Link component:

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();
});

The first time this test is run, Jest creates a snapshot file that looks like this:

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

Знімок варто додавати в систему контролю версій разом зі змінами коду. We use pretty-format to make snapshots human-readable during code review. Під час наступних запусків теста Jest просто порівняє результат роботи компонента зі збереженим знімком. Якщо вони співпадуть, тест пройде. If they don't match, either the implementation has changed and the snapshot needs to be updated with jest -u, or the test runner found a bug in your code that should be fixed.

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

snapshot-testing

Now you know that you either need to accept the changes with jest -u, or fix the component if the changes were unintentional. To try out this functionality, please clone the snapshot example, modify the Link component and run Jest. We updated the React Tutorial with a new guide for snapshot testing.

This feature was built by Ben Alpert and Cristian Carlesso.

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

Створивши відтворювач тестів, який не націлений на конкретну платформу, ми нарешті мали змогу підтримувати повну, не імітовану версію React Native. We are excited to launch experimental React Native support for Jest through the jest-react-native package.

You can start using Jest with react-native by running yarn add --dev jest-react-native and by adding the preset to your Jest configuration:

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

Наразі, пресет реалізує мінімальний набір конфігурацій, необхідний для початку тестування з React Native. Ми сподіваємося на внески спільноти для покращення цього проєкту. Please try it and file issues or send pull requests!

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

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

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

  • No flakiness: Because tests are run in a command line runner instead of a real browser or on a real phone, the test runner doesn't have to wait for builds, spawn browsers, load a page and drive the UI to get a component into the expected state which tends to be flaky and the test results become noisy.
  • Fast iteration speed: Engineers want to get results in less than a second rather than waiting for minutes or even hours. Якщо тести запускаються не так швидко, як в більшості системних фреймворків, розробники взагалі їх не запускатимуть або ж не писатимуть в першу чергу.
  • Debugging: It's easy to step into the code of an integration test in JS instead of trying to recreate the screenshot test scenario and debugging what happened in the visual diff.

Because we believe snapshot testing can be useful beyond Jest we split the feature into a jest-snapshot package. Ми раді співпрацювати зі спільнотою, щоб зробити її універсальнішою, аби її можна було використовувати з іншими виконавцями тестів, а також ділитися з ними концепціями та інфраструктурою.

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

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

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

Recently Aaron Abramov has joined the Jest team full time to improve our unit and integration test infrastructure for Facebook's ads products. Протягом наступних кількох місяців команда Jest планує значні покращення в наступних сферах:

  • Replace Jasmine: Jasmine is slowing us down and is not being very actively developed. Ми почали заміну всіх матчерів Jasmin та з нетерпінням очікуємо початку додавань нових функцій, аби видалити цю залежність.
  • Code Coverage: When Jest was originally created, tools such as babel didn't exist. Наша підтримка покриття коду має купу крайніх випадків та не завжди працює належним чином. Ми переписуємо цей момент, щоб розв'язати поточні проблеми з покриттям.
  • Developer Experience: This ranges from improving the setup process, the debugging experience to CLI improvements and more documentation.
  • Mocking: The mocking system, especially around manual mocks, is not working well and is confusing. Ми сподіваємося зробити її більш строгою та зрозумілою.
  • Performance: Further performance improvements especially for really large codebases are being worked on.

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