Testphilosophie
Jutro-Ansatz für Tests
Wir bei Jutro empfehlen Ihnen, die von der Testbibliothek vorgeschlagenen Testprinzipien zu befolgen. Kurz gesagt:
- Interagieren Sie mit Ihrer App auf die gleiche Weise wie Ihre Benutzer
- Testen Sie Ihre Anwendung, nicht Ihre Implementierungsdetails
- Verwenden Sie Selektoren, die auf Barrierefreiheit basieren, nicht auf Ihrem Wissen über die Anwendungsstruktur
Das @jutro/test-Paket bietet außerdem eine Reihe nützlicher Helfer, die das Befolgen der Grundsätze erleichtern.
Zusätzliche Informationen
- Weitere Informationen zu diesen Grundsätzen finden Sie auf der Seite zu den Leitprinzipien der Testbibliothek.
- Wir empfehlen Ihnen auch, diesen Artikel darüber zu lesen, warum es nicht sinnvoll ist, Implementierungsdetails zu testen.
- Vergessen Sie nicht die Priorität von Abfragen!
- Befürchten Sie, dass Sie Fehler machen könnten? Informieren Sie sich über einige häufige Fehler, sodass Sie sie vermeiden können.
Prinzipien in der Praxis
Interaktion
Um mit Ihrer App auf die gleiche Weise wie Ihre Benutzer zu interagieren, wählen Sie Elemente anhand von Attributen aus, mit denen der Benutzer interagiert, wie Beschriftungen oder Rollen. Vermeiden Sie die Verwendung von Implementierungsdetails, wie IDs und Klassen.
Wählen Sie eine Schaltfläche nach Text aus.
Wählen Sie eine Schaltfläche nach ID oder Position in der DOM-Struktur aus.
Um sicherzustellen, dass Ihre App richtig übersetzt ist, würden Sie nicht mit dem Bildschirmtext interagieren, sondern mit einer Übersetzung aus Ihrer Meldungsdatei. Um ein realistischeres Beispiel zu geben:
import { getTranslation } from '@jutro/test';
import { messages } from '../MyComponent.messages';
const theButton = screen.getByRole('button', {
name: getTranslation(messages.awesomeButton),
});
Sie könnten einen Komponententest wie folgt schreiben:
import { render, screen } from '@jutro/test';
test('has correct welcome text', () => {
render(
<Welcome
firstName="John"
lastName="Doe"
/>
);
expect(
screen.getByRole('heading', { name: 'Welcome, John Doe' })
).toBeInTheDocument();
});
Wenn Sie an weiteren Beispielen interessiert sind, finden Sie diese im Abschnitt Weitere Interaktionsbeispiele.
Anwendung
Um Ihre Anwendung und nicht Ihre Implementierungsdetails zu testen, konzentrieren Sie sich auf das Ergebnis in der Anwendung und nicht auf Änderungen des internen Zustands der Anwendung.
Testen Sie, ob die Schaltfläche für das Profilmenü angezeigt wird, wenn der Benutzer bei der Anwendung angemeldet ist (ein e2e-Test).
Schreibe einen Unit-Test, der Avatar.isAuthenticated auf true setzt und dann prüft, ob Avatar.isDisplaying auch auf true gesetzt ist.
test('Verify that avatar exists in the application header after login', async (t) => {
await t
.expect(
queryByRole('button', {
name: getTranslation('User Profile'),
}).exists
)
.ok();
});
Barrierefreiheit
Um Selektoren auf der Grundlage der Barrierefreiheit zu verwenden, sollten Sie sich auf aria-role und andere ARIA-Attribute stützen. Auf diese Weise testen Sie, was Ihre Anwendung für den Benutzer rendert, ohne die Details, wie es gerendert wird.
Prüfen Sie das gerenderte HTML auf eine Schaltfläche mit der Rolle „tab“, deren „aria-selected“-Attribut auf „true“ gesetzt ist.
Wählen Sie das div aus, das eine Registerkartenschaltfläche rendert, und prüfen Sie, ob es eine Klasse hat, die das Wort „active“ enthält.
Richtig gerendert sieht der HTML-Code für eine Reihe von Registerkarten so aus:
<div role="tablist">
<button
role="tab"
aria-selected="false"
class="tab">
Pending claims
</button>
<button
role="tab"
aria-selected="true"
class="active tab">
Accepted claims
</button>
<button
role="tab"
aria-selected="false"
class="tab">
Rejected claims
</button>
</div>
In diesem Fall kann Ihr Test Folgendes auswählen:
const activeTab = screen.getByRole('tab', { selected: true });
Weitere Informationen finden Sie unter Prüfung der Barrierefreiheit.
Verwendung von Komponenten-IDs nur als letztes Mittel
Wenn Sie sich in der seltenen Situation befinden, dass ein benutzerzentrierter Ansatz und Barrierefreiheit nicht ausreichend sind, können Sie das data-testid-Attribut hinzufügen. Dies ist z. B. ein guter Ansatz, wenn Sie prüfen wollen, ob eine Seite gerendert wird, und Sie das gesamte div für etwas wie eine „Willkommensseite“ auswählen möchten, die keine spezifische Funktionalität hat.
Rendern Sie Ihre Komponente wie folgt:
<div data-testid="home-page">{children}</div>
Und wählen Sie sie so aus:
const homePage = screen.getByTestId('home-page');
Automatisch generierte IDs
Jede Feldkomponente auf einer Seite erhält eine eindeutige Ganzzahl, die am Ende der ID hinzugefügt wird. Dadurch wird sichergestellt, dass jede ID eindeutig ist. Dieselben Ganzzahl wird zu Beschriftungen hinzugefügt, die sich auf die ID beziehen, damit die Verbindung nicht verloren geht.
Wenn Sie beispielsweise die ID als soup angeben, hat die HTML-Komponente eine ID wie soup_0, soup_1 und so weiter.
Um unter Verwendung der ID in einem Selektor zu testen, haben Sie die folgenden Möglichkeiten:
Test-ID
Im gerenderten HTML-Code erhält jedes Feld ein zusätzliches data-testid-Attribut, das der ID ohne die Ganzzahl am Ende entspricht. Das bedeutet, dass der Wert für einige Komponenten auf Ihrer Seite dupliziert werden kann.
Sie können die testId-Eigenschaft verwenden, um einen benutzerdefinierten Wert für das data-testid-Attribut in HTML festzulegen.
{
"id": "soup",
"type": "field",
"component": "Input",
"componentProps": {
"testId": "chowder"
}
}
Das resultierende HTML:
<input
id="soup_0"
data-testid="chowder" />
Platzhalter
Verwenden Sie einen Platzhalter im Selektor, z. B. input[id*="soup"].
Deaktivieren automatisch generierter IDs
Sie können Ihre App so einstellen, dass sie keine eindeutigen IDs erzeugt. In src/config/config.json stellen Sie dazu ein:
"generateUniqueId": false,
Standardmä ßig ist diese Option auf true eingestellt. Wenn Sie sie auf false setzen, kann es auf einigen Seiten zu doppelten IDs kommen.