Testy komponentów — warstwa między unit a E2E

Testy komponentów bierz na stany UI, które nie potrzebują całej podróży. E2E zostaw ścieżkom, które jej potrzebują.

Ten wpis jest częścią serii Architektura testów. Jeśli pominąłeś poprzedni, przeczytaj Część 4 — Projektowanie pod testowalność.


Wprowadzenie — podróż jest złym rozmiarem

Wyłączony przycisk zapłaty nie potrzebuje przeglądarki, użytkownika i trzech usług. Test jednostkowy funkcji „wyłącz” nie dowodzi, że na ekranie jest ten przycisk. Testy komponentów siedzą w luce: komponent jest prawdziwy, strony wokół niego nie ma.

Co ta warstwa posiada

Bierz test komponentu, gdy zachowanie jest widoczne i lokalne:

  • stany pusty, ładowanie, błąd i sukces jednego komponentu
  • błąd pola, który pojawia się przy tym polu
  • przycisk, który włącza się, gdy wejścia komponentu na to pozwalają
  • klawiatura wewnątrz jednego widgetu, na przykład menu albo dialogu

Nie bierz całej kasy. Gdy test potrzebuje routingu, sesji i drugiej strony, to jest E2E. Gdy nie potrzebuje rysowania, to jest unit.

Jeden przykład

Runner zależy od frameworka UI. Kształt jest ten sam: zamontuj komponent, daj propsy, sprawdź dostępną nazwę.

import { test, expect } from '@playwright/experimental-ct-react';
import { PayButton } from './PayButton';

test('stays disabled when the price is missing', async ({ mount }) => {
  const component = await mount(<PayButton price={null} />);
  await expect(component.getByRole('button', { name: 'Pay' })).toBeDisabled();
});

test('explains a refused payment', async ({ mount }) => {
  const component = await mount(<PayButton price={20} status="refused" />);
  await expect(component.getByRole('alert')).toHaveText('Payment was refused');
});

Dwa testy, bez logowania i bez sieci. Jeśli PayButton nie daje się zamontować bez całej aplikacji, to problem projektu z części 4, a nie powód, żeby oba przypadki wpychać do E2E.

Jak to zmienia piramidę

Testy E2E zostają przy podróżach: logowanie, płatność, zamówienie. Testy komponentów biorą stany widgetów, przez które te podróże przechodzą. Skasujesz testy UI, które istniały tylko po to, żeby dojść do komunikatu błędu. Nie skasujesz jednej podróży, która dowodzi, że kawałki są spięte.

Policz je. Jeśli testów komponentów jest dziesięć razy więcej niż unitów, rysujesz po to, żeby testować logikę. Jeśli nie masz testów komponentów, a masz dziesiątki E2E na copy i wyłączone przyciski, warstwy brakuje.

Co je psuje

  • import prawdziwego klienta API w zakresie modułu komponentu
  • asercje na klasach CSS zamiast roli i nazwy
  • montowanie korzenia aplikacji i nazywanie tego testem komponentu

Test komponentu, który podnosi router, jest testem E2E z dodatkowymi krokami.

Podsumowanie

Lokalne stany UI połóż w testach komponentów. Ścieżkę, którą idzie użytkownik, w E2E. Czyste reguły w unitach. Warstwa zarabia na siebie, gdy zmiana stanu nie kosztuje już całej podróży.

Zadanie na ten tydzień: Wybierz jeden test E2E, którego jedyną asercją jest błąd przy polu albo wyłączony przycisk. Zamontuj ten komponent bezpośrednio. Podróż zostaw dla ścieżki sukcesu.


To kończy serię Architektura testów.