====== LU16b - Testing ====== Testing stellt sicher, dass eine Web-Applikation so funktioniert, wie erwartet – bevor sie in Production gelangt. Es gibt vier Testarten, die sich in Umfang, Geschwindigkeit und Aufwand unterscheiden. {{:de:modul:m291:learningunits:lu16:theorie:test-pyramid.png?direct&600| Testing-Pyramide: Unit → API/Integration → UI/E2E → Manuell }}\\ //Testing-Pyramide mit vier Ebenen// Die Pyramide zeigt die empfohlene Gewichtung: * **Unten (breit):** Viele schnelle Unit Tests – testen einzelne isolierte Funktionen. * **Mitte:** Weniger Integration Tests – testen das Zusammenspiel von Funktionen. * **Oben (schmal):** Wenige, langsame End-to-End Tests – aufwändig, aber realitätsnah. * **Wolke:** Manuelles Testen – nicht automatisierbar, aber unverzichtbar. ===== Unit Test ===== Ein Unit Test prüft eine **einzelne, isolierte Funktion** – ohne Abhängigkeiten von aussen (kein Browser, keine API, keine Datenbank). {{:de:modul:m291:learningunits:lu16:theorie:scap_20260628210743_1.png?nolink&600 | Vitest – Unit Test Screenshot }} //Screenshot Vitest-Output im Terminal mit grünem PASS// **Werkzeug:** [[https://vitest.dev|Vitest]] **Beispiel:** Eine Funktion, die langen Text abkürzt. // textHelpers.js export function truncateText(text, maxLength) { if (text.length <= maxLength) return text return text.slice(0, maxLength) + '...' } // textHelpers.spec.js import { truncateText } from './textHelpers.js' import { test, expect } from 'vitest' test('kürzt langen Text ab', () => { expect(truncateText('Was ist Vue.js?', 6)).toBe('Was is...') }) test('lässt kurzen Text unverändert', () => { expect(truncateText('Hallo', 10)).toBe('Hallo') }) ^ Eigenschaft ^ Unit Test ^ | Geschwindigkeit | Sehr schnell (Millisekunden) | | Browser nötig? | Nein | | Echte API nötig? | Nein | | Testet | Eine einzelne Funktion | ===== Integration Test ===== Ein Integration Test prüft das **Zusammenspiel mehrerer Teile** – zum Beispiel wie eine Funktion einen API-Aufruf durchführt und die Antwort verarbeitet. {{:de:modul:m291:learningunits:lu16:theorie:integration_test_fetch.png?nolink&600| Vitest – Integration Test}}\\ //Vitest mit Integration Test// **Werkzeug:** [[https://vitest.dev|Vitest]] **Beispiel:** Die ''fetchFaqs()''-Funktion abrufen und prüfen, ob die Daten korrekt ankommen. // fetchFaqs.spec.js import { test, expect, vi } from 'vitest' import { fetchFaqs } from './fetchFaqs.js' vi.stubGlobal('fetch', () => Promise.resolve({ json: () => Promise.resolve([{ id: '1', question: 'Was ist Vue?' }]) })) test('gibt FAQ-Daten zurück', async () => { const data = await fetchFaqs('https://mockapi.io/faqs') expect(data[0].question).toBe('Was ist Vue?') }) **Warum ''fetch'' mocken?** Im Test soll nicht die echte MockAPI.io aufgerufen werden. Mit ''vi.stubGlobal'' wird ''fetch'' durch eine Fake-Version ersetzt, die sofort antwortet – ohne Internetverbindung. ^ Eigenschaft ^ Integration Test ^ | Geschwindigkeit | Schnell (Millisekunden) | | Browser nötig? | Nein | | Echte API nötig? | Nein (gemockt) | | Testet | Fetch + Datenverarbeitung zusammen | ===== End-to-End Test (E2E) ===== Ein E2E Test öffnet einen **echten Browser** und simuliert, wie eine Nutzerin oder ein Nutzer mit der App interagiert – Klicks, Formular-Eingaben, Navigation. {{:de:modul:m291:learningunits:lu16:theorie:e2e_playwright.gif | Playwright – UI mit laufendem Test }}\\ //Screenshot Playwright Test Runner mit Browserfenster und Testergebnis// **Werkzeug:** [[https://playwright.dev|Playwright]] **Beispiel:** Prüfen, ob das FAQ-Accordion korrekt öffnet und schliesst. // accordion.spec.js import { test, expect } from '@playwright/test' test.beforeEach(async ({ page }) => { await page.goto('http://localhost:5173', { waitUntil: 'networkidle' }) }) test('Antwort ist standardmässig nicht sichtbar', async ({ page }) => { await expect( page.getByText('Your laptop has absorbed your energy...') ).not.toBeVisible() }) test('Antwort erscheint nach Klick auf die Frage', async ({ page }) => { await page .getByRole('button', { name: 'Why does my code work on my machine?' }) .click() await expect( page.getByText('Your laptop has absorbed your energy...') ).toBeVisible() }) ^ Eigenschaft ^ E2E Test ^ | Geschwindigkeit | Langsam (Sekunden pro Test) | | Browser nötig? | Ja (Chromium, Firefox, WebKit) | | Echte API nötig? | Ja (oder Staging-URL) | | Testet | Vollständige Interaktion eines Users im Browser | ===== Manuelles Testen ===== Manuelles Testen kann nicht vollständig automatisiert werden – es erfordert menschliches Urteilsvermögen. Typische Aufgaben: * Responsive Design auf verschiedenen Bildschirmgrössen prüfen * Cross-Browser-Kompatibilität testen (Chrome, Firefox, Edge) * Visuelle Qualität und Nutzererlebnis beurteilen * Accessibility mit Tastatur und Screenreader prüfen {{:de:modul:m291:learningunits:lu16:theorie:screenshot_2026-06-28_at_23.07.29.png?direct&1100| Chrome DevTools – Responsive Design Mode }}\\ //Screenshot Chrome DevTools mit aktivierter Device Toolbar// **Werkzeug: Chrome DevTools (im Browser integriert)** Öffnen Sie die DevTools mit **F12**, dann klicken Sie auf das **Geräte-Symbol** oben links oder drücken Sie **Ctrl+Shift+M**. Sie können nun die Breite frei einstellen oder ein Gerät aus der Liste wählen. Empfohlene Testbreiten: ^ Gerät ^ Breite ^ | Mobile (z.B. iPhone SE) | bis 375px | | Tablet (z.B. iPad) | 768px | | Desktop | ab 1280px | ==== Testprotokoll ==== Für das manuelle Testen wird ein **Testprotokoll** geführt. Es dokumentiert, was getestet wurde, was erwartet wurde und was tatsächlich passiert ist. ^ # ^ Testfall ^ Erwartetes Resultat ^ Effektives Resultat ^ Status ^ | 1 | Seite aufrufen | FAQ-Liste wird geladen und angezeigt | | ☐ ✅ ☐ ❌ | | 2 | Auf eine Frage klicken | Antwort wird sichtbar | | ☐ ✅ ☐ ❌ | | 3 | Nochmals auf dieselbe Frage klicken | Antwort schliesst sich | | ☐ ✅ ☐ ❌ | | 4 | Tab-Taste: durch Fragen navigieren | Fokus-Rahmen springt sichtbar von Frage zu Frage | | ☐ ✅ ☐ ❌ | | 5 | Enter auf fokussierter Frage | Antwort öffnet sich | | ☐ ✅ ☐ ❌ | | 6 | DevTools: 375 px | Layout passt sich an, kein horizontales Scrollen | | ☐ ✅ ☐ ❌ | | 7 | Echtes Smartphone | App funktioniert, Klick öffnet die Antwort | | ☐ ✅ ☐ ❌ | | 8 | Firefox oder Edge | App lädt und verhält sich gleich wie in Chrome | | ☐ ✅ ☐ ❌ |