Тестирование UI компонента формы - это сложный интеграционный тест с высоким уровнем хрупкости.
Поэтому при тестировании форм необходимо сфокусироваться на более простом тестировании логики формы.
Оглавление
Большинство библиотек для работы с формами позволяют эмулировать взаимодействие пользователя с формой без необходимо рендеринга формы в DOM
. Благодаря этому в тестах есть возможность вызывать для конкретного поля такие события как: focus, blur, change…
Пример:
describe('useBookForm', () => {
describe('Автозаполнение полей формы', () => {
it('Происходит при изменении поля name', async () => {
const { result } = rtl.renderHook(() => useBookForm());
const sut = result.current;
rtl.act(() => {
sut.form.setValue('name', faker.person.firstName());
});
const { genre, author } = sut.form.getValues();
expect(genre).toEqual(fakeBook.genre);
expect(author).toEqual(fakeBook.author);
});
});
});
Тестировать валидацию необходимо в контексте выполнения тестируемой формы
Данное условие необходимо для того, чтобы тест отображал действительность и проверял интеграцию описанной валидации и логики формы.
describe('Соавтор', () => {
it('Обязателен, если isPresentCoAuthor=true', () => {
...
});
});
Тестами необходимо покрывать только ту часть валидации, которая содержит логику
Дана схема валидации, используемая в форме:
const validationSchema = v.object<BookFormValues>({
name: v.string(),
genre: v.object<BookFormValues['genre']>({
id: v.string(),
name: v.string(),
description: v.optional(v.string()),
}),
pageCount: v.number(),
author: v.object<BookFormValues['author']>({
name: v.string(),
surname: v.string(),
}),
isPresentCoAuthor: v.optional(v.boolean()),
coAuthor: v.when({
is: (_, ctx) => Boolean(ctx.values.isPresentCoAuthor),
then: v.object<BookFormValues['author']>({
name: v.string(),
surname: v.string(),
}),
otherwise: v.any(),
}),
});
В данном случае в тесте формы необходимо проверить только логику валидации coAuthor
: