Тестування з допомогою знімків
Тестування з використанням знімків - це дуже корисний інструмент, коли ви хочете бути впевнені, що у вашому UI не відбулося несподіваних змін.
Типовий тестовий сценарій для тестування знімками виконує рендер UI компонента, робить знімок файлової системи та порівнює його з файлом знімку, який зберігається разом з тестом. Тест викличе помилку, якщо два зображення не збігаються: відбулась неочікувана зміна або знімок повинен бути оновлений відповідно до нової версії UI компонента.
Тестування знімками з Jest
Аналогічний підіхід може бути використано, коли заходить мова про тестування React компонентів. Instead of rendering the graphical UI, which would require building the entire app, you can use a test renderer to quickly generate a serializable value for your React component. Consider this example test for a Link component:
import {render} from '@testing-library/react';
import Link from '../Link';
it('renders correctly', () => {
const {container} = render(
<Link page="http://www.facebook.com">Facebook</Link>,
);
expect(container.firstChild).toMatchSnapshot();
});
The first time this test is run, Jest creates a snapshot file that looks like this:
exports[`renders correctly 1`] = `
<a
aria-label="normal
class="normal"
href="http://www.facebook.com"
>
Facebook
</a>
`;
Знімок повинен бути доданий до системи конролю версій разом зі змінами коду, що дозволить переглянути його в процесі code review. Jest uses pretty-format to make snapshots human-readable during code review. Під час наступних запусків тесту, Jest порівняє результат роботи компонента зі збереженим знімком. Якщо вони співпадуть, тест пройде. If they don't match, either the test runner found a bug in your code (in the <Link> component in this case) that should be fixed, or the implementation has changed and the snapshot needs to be updated.
The snapshot is directly scoped to the data you render – in our example the <Link> component with page prop passed to it. This implies that even if any other file has missing props (say, App.js) in the <Link> component, it will still pass the test as the test doesn't know the usage of <Link> component and it's scoped only to the Link.js. Also, rendering the same component with different props in other snapshot tests will not affect the first one, as the tests don't know about each other.
More information on how snapshot testing works and why we built it can be found on the release blog post. We recommend reading this blog post to get a good sense of when you should use snapshot testing. We also recommend watching this egghead video on Snapshot Testing with Jest.
Оновлення знімків
Дуже просто помітити, коли тест з використанням знімків падає після того, як з’явилася помилка в коді. Коли таке трапляється, просто виправте помилку і переконайтеся, що ваші тести знову проходять успішно. Тепер давайте поговоримо про випадок, коли тест зі знімком падає внаслідок навмисної зміни коду.
Така ситуація може виникнути, якщо ми навмисно змінимо адресу, на яку вказує компонент Link з нашого прикладу.
// Updated test case with a Link to a different address
it('renders correctly', () => {
const {container} = render(
<Link page="http://www.instagram.com">Instagram</Link>,
);
expect(container.firstChild).toMatchSnapshot();
});
В цьому випадку Jest видасть наступний вивід:

Оскільки ми щойно оновили наш компонент, щоб він вказував на іншу адресу, логічно очікувати зміну знімка цього компонента. Наш тест зі знімком падає, оскільки знімок для оновленого компонента більше не співпадає зі збереженим знімком для цього теста.
To resolve this, we will need to update our snapshot artifacts. You can run Jest with a flag that will tell it to re-generate snapshots:
jest --updateSnapshot
Просто прийміть зміни запустивши команду вище. You may also use the equivalent single-character -u flag to re-generate snapshots if you prefer. Це перегенерує знімки для всіх тестів, які впали через неспівпадіння знімків. Якби у нас були тести зі знімками, які падали через помилку в коді, нам варто було б виправити ці проблеми до перегенерації знімків, щоб запобігти створенню знімків для неправильної поведінки.
If you'd like to limit which snapshot test cases get re-generated, you can pass an additional --testNamePattern flag to re-record snapshots only for those tests that match the pattern.
You can try out this functionality by cloning the snapshot example, modifying the Link component, and running Jest.