Тестирование 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: