API Teststrategien: Ein praktischer Leitfaden für zuverlässige APIs
API-Teststrategien: Ein praktischer Leitfaden für zuverlässige APIs
Die meisten API-Fehler sind nicht exotisch: ein fehlendes Feld, ein falscher Statuscode, ein Timeout unter Last oder eine Breaking Change, die ausgeliefert wurde, weil niemand den Vertrag geprüft hat. Ad-hoc-Tests finden manche dieser Fehler zufällig. Eine API-Teststrategie findet sie absichtlich.
Apidog noch heute ausprobieren
Eine API-Teststrategie definiert, was Sie testen, auf welcher Ebene Sie testen und wann diese Tests im Lieferzyklus laufen. Sie legt fest, welche Checks bei jedem Commit ausgeführt werden, welche nächtlich laufen und welche vor einem Release Pflicht sind. Ziel ist maximale Abdeckung bei minimalem Wartungsaufwand.
Was eine API-Teststrategie tatsächlich bedeutet
Beantworten Sie diese vier Fragen, bevor Sie Assertions schreiben.
1. Was testen Sie?
Testen Sie zuerst Endpunkte und Abläufe mit hohem geschäftlichem Risiko. Beispiele:
- Checkout-API
- Zahlungsstatus
- Benutzerregistrierung
- Authentifizierung
- Berechtigungsprüfungen
- Datenexporte
Ein Health-Check-Endpunkt braucht weniger Abdeckung als ein Zahlungsfluss. Priorisieren Sie nach Risiko, Traffic und Schadenspotenzial, nicht danach, welcher Endpunkt am einfachsten zu testen ist.
2. Auf welcher Ebene testen Sie?
Nicht jeder Test gehört auf die höchste Ebene. Eine einzelne Anfrage kann Statuscode, Schema und Feldwerte prüfen. Ein Integrationsszenario prüft mehrere Dienste. Ein End-to-End-Test prüft einen vollständigen Workflow. Wenn Sie alles als End-to-End-Test bauen, wird die Suite langsam, fragil und schwer zu debuggen.
3. Wann laufen die Tests?
Teilen Sie die Suite nach Geschwindigkeit und Zweck auf:
- Schnelle Tests: bei jedem Push
- Mittlere Tests: bei jedem Merge oder nächtlich
- Langsame Tests: vor Releases oder geplant
- Last- und Sicherheitstests: separat und kontrolliert
So bleibt Feedback schnell, ohne wichtige Abdeckung zu verlieren.
4. Was zählt als erfolgreich?
Ein Test, der nur 200 OK prüft, ist kaum nützlich. Definieren Sie mindestens:
- erwarteten Statuscode
- erwartetes Antwortschema
- Pflichtfelder
- relevante Feldwerte
- Fehlerformat
- Antwortzeitgrenzen, wenn relevant
Beispiel:
GET /api/users/42 HTTP/1.1
Host: api.example.com
Authorization: Bearer <token>
Assertions:
- Status ist 200
- Body entspricht dem User-Schema
idist 42emailist ein gültiger E-Mail-String- Antwortzeit liegt unter dem definierten Grenzwert
Warum eine Strategie Ad-hoc-Tests schlägt
Ad-hoc-Tests bedeuten: Anfrage senden, Antwort visuell prüfen, weitermachen. Das reicht für eine Demo, aber nicht für einen echten Dienst.
Ad-hoc-Tests sind nicht wiederholbar – Die nächste Person kann Ihre manuelle Prüfung nicht exakt reproduzieren. Automatisierte Tests laufen dagegen bei jeder Änderung gleich.
Ad-hoc-Tests testen meistens nur den Happy Path – Manuell testen Teams oft nur den erwarteten Erfolgsfall. Was häufig fehlt:
- fehlende Pflichtfelder
- ungültige Datentypen
- abgelaufene Tokens
- falsche Scopes
- große Payloads
- leere Listen
- Grenzwerte
Genau diese Fälle brechen häufig in Produktion.
Ad-hoc-Tests skalieren nicht – Ein Dienst mit 40 Endpunkten und 5 Umgebungen erzeugt schnell 200 manuelle Prüfungen pro Release. Das macht niemand dauerhaft von Hand. Eine Strategie ersetzt wiederholte manuelle Arbeit durch automatisierte Abdeckung: Tests einmal schreiben, dann bei jeder Änderung ausführen.
Die API-Testpyramide
Die Testpyramide hilft Ihnen, die richtige Menge an Tests pro Ebene zu planen.
/\
/ \ End-to-End- / Workflow-Tests
/ \ (wenige, langsam, hoher Wert)
/------\
/ \ Integrations- / Vertrags-Tests
/ \ (einige, mittlere Geschwindigkeit)
/------------\
/ \ Unit- / Single-Request-Tests
/ \ (viele, schnell, günstig)
/__________________\
Untere Ebene: Single-Request-Tests
Diese Tests rufen einen Endpunkt auf und prüfen die Antwort. Sie sind:
- schnell
- günstig zu schreiben
- leicht zu debuggen
- ideal für CI bei jedem Commit
Die meisten API-Tests sollten hier liegen.
Mittlere Ebene: Integrations- und Vertragstests
Diese Tests prüfen:
- ob Dienste korrekt miteinander kommunizieren
- ob Datenformate zwischen Anbieter und Konsument stabil bleiben
- ob Abläufe über mehrere Systeme funktionieren
Sie sind langsamer als Single-Request-Tests, fangen aber Fehler ab, die isolierte Tests nicht sehen.
Obere Ebene: End-to-End-Workflows
Diese Tests prüfen komplette Benutzerreisen. Beispiel:
- Bestellung erstellen
- Zahlung auslösen
- Zahlungsstatus prüfen
- Bestellstatus prüfen
Sie liefern hohes Vertrauen, sind aber teuer in Wartung und Ausführung. Halten Sie sie deshalb bewusst klein und fokussieren Sie sich auf kritische Pfade.
Der häufigste Fehler ist eine umgedrehte Pyramide: viele langsame End-to-End-Tests und kaum schnelle Tests. Verschieben Sie Abdeckung so weit wie möglich nach unten, wenn eine niedrigere Ebene denselben Fehler erkennen kann.
Testarten und wann Sie sie einsetzen
Eine belastbare API-Teststrategie kombiniert mehrere Testarten. Jede deckt eine andere Fehlerklasse ab.
Funktionale Tests
Funktionale Tests prüfen, ob ein Endpunkt gemäß Spezifikation funktioniert. Typische Assertions:
- Statuscode
- Antwortschema
- Feldwerte
- Header
- Fehlerformat
Beispiel:
GET /api/users/42 HTTP/1.1
Host: api.example.com
Authorization: Bearer <token>
Assertions:
- Status ist 200
- Body entspricht dem User-Schema
idist 42emailist ein gültiger E-Mail-String
Funktionale Tests sind die Basis Ihrer Suite und sollten für jeden wichtigen Endpunkt automatisiert werden. Mehr dazu: API-Funktionstests
Integrationstests
Integrationstests prüfen, ob Endpunkte und abhängige Systeme gemeinsam korrekt funktionieren. Beispiele:
- API schreibt korrekt in die Datenbank
- API ruft einen Zahlungsanbieter korrekt auf
- Ein Service verarbeitet die Antwort eines anderen Service richtig
- Ein Workflow über mehrere APIs liefert das erwartete Ergebnis
Ein funktionaler Test kann mit einer gemockten Abhängigkeit bestehen, aber mit der echten Integration fehlschlagen. Integrationstests schließen diese Lücke. Mehr dazu: API-Integrationstests
Regressionstests
Regressionstests führen bestehende Tests nach Änderungen erneut aus. Ziel: sicherstellen, dass bereits funktionierendes Verhalten nicht kaputt gegangen ist. Sie schreiben nicht zwingend separate Regressionstests. Ihre automatisierte Suite wird zur Regressionstest-Suite, sobald sie regelmäßig läuft:
- bei jedem Commit
- vor Merges
- vor Releases
- geplant, zum Beispiel nachts
Mehr dazu: Regressionstests
Vertragstests
Vertragstests prüfen, ob Anbieter und Konsument einer API dasselbe Verständnis von Requests und Responses haben. Sie erkennen Breaking Changes wie:
- umbenannte Felder
- entfernte Felder
- geänderte Datentypen
- geänderte Statuscodes
- entfernte Endpunkte
- neue Pflichtfelder
Wenn andere Teams oder Kunden Ihre API nutzen, sind Vertragstests ein zentraler Bestandteil der Strategie. Mehr dazu: API-Vertragstests
Last- und Performance-Tests
Lasttests messen, wie sich Ihre API unter gleichzeitigem Traffic verhält. Wichtige Metriken:
- Antwortzeit im 95. Perzentil
- Fehlerrate
- Durchsatz
- Timeouts
- Sättigungspunkte
- Verhalten bei Traffic-Spitzen
Führen Sie Lasttests aus:
- vor Launches
- vor erwarteten Traffic-Peaks
- regelmäßig zur Erkennung schleichender Performance-Probleme
Lasttests gehören nicht in jeden Commit. Sie benötigen eigene Tools und separate Infrastruktur. Mehr dazu: Lasttest-Tools
Sicherheitstests
Sicherheitstests prüfen, ob Ihre API unsichere oder unerlaubte Anfragen korrekt ablehnt. Testen Sie mindestens:
- Anfragen ohne Token
- abgelaufene Tokens
- falsche Scopes
- Zugriff auf fremde Daten
- ungültige Rollen
- Injektionsversuche
- unsichere Fehlerausgaben
Jeder Endpunkt mit sensiblen Daten braucht Authentifizierungs- und Autorisierungsprüfungen. Mehr dazu: API-Sicherheitstests
Wann welche Testart laufen sollte
| Testart | Fängt ab | Läuft |
|---|---|---|
| Funktionale Tests | Falscher Status, falsches Schema, falsche Werte | Jeder Commit |
| Integrationstests | Defekte Service-zu-Service-Abläufe | Jeder Commit oder nächtlich |
| Regressionstests | Neu defektes bestehendes Verhalten | Jeder Commit und vor Release |
| Vertragstests | Breaking Changes an der Schnittstelle | Jeder Anbieter-Commit |
| Lasttests | Langsamkeit und Ausfälle unter Traffic | Vor Launches und geplant |
| Sicherheitstests | Auth-Probleme, Injektion, Datenexposition | Vor Release und geplant |
Positive, negative und Grenzfälle
Für jeden wichtigen Endpunkt sollten Sie drei Eingabeklassen abdecken.
Positive Fälle
Positive Tests senden gültige Eingaben und erwarten Erfolg.
Beispiel:
POST /api/users HTTP/1.1
Content-Type: application/json
{
"email": "user@example.com",
"name": "Ada Lovelace"
}
Erwartung:
- Status 201
- Benutzer wird erstellt
- Response enthält eine ID
- Response entspricht dem Schema
Negative Fälle
Negative Tests senden ungültige Eingaben und erwarten einen kontrollierten Fehler. Beispiele:
- fehlendes Pflichtfeld → 400
- ungültiger Token → 401
- falscher Scope → 403
- Zugriff auf fremde Ressource → 403 oder 404
- ungültiger Datentyp → 400
Beispiel:
POST /api/orders HTTP/1.1
Content-Type: application/json
{
"customerId": "c_123",
"quantity": -5
}
Erwartung:
- Status 400
- Body enthält einen klaren Validierungsfehler
- Fehler benennt
quantity - API erstellt keine Bestellung
Wenn diese Anfrage 201 oder 500 zurückgibt, haben Sie einen Fehler gefunden, den ein Happy-Path-Test nie erkannt hätte.
Grenzfälle
Grenzfälle testen die Ränder gültiger Eingaben. Beispiele:
- leere Liste
- maximale Stringlänge
null- negative Zahl
- sehr große Zahl
- Unicode-Name
- Zeitstempel an einer Sommerzeitgrenze
- exakt erlaubter Maximalwert
- Wert direkt über dem Maximalwert
Praktische Regel: Schreiben Sie für jeden positiven Test mindestens einen negativen Test. Wenn ein Bestell-Endpunkt nur den Happy Path prüft, aber keine negative Menge oder fehlende Kunden-ID testet, ist die Abdeckung dünner, als sie aussieht.
Testdaten und Umgebungen
Tests sind nur vertrauenswürdig, wenn Daten und Umgebung kontrolliert sind.
Verwenden Sie dedizierte Testdaten
Testen Sie nicht gegen Produktionsdaten und verlassen Sie sich nicht auf zufällig vorhandene Datensätze. Besser:
- Testdaten vor dem Test erzeugen
- Fixtures initialisieren
- IDs dynamisch aus vorherigen Antworten übernehmen
- Testdaten nach dem Lauf bereinigen
Für realistische Eingaben hilft ein Generator: wie man realistische API-Testdaten erstellt
Machen Sie Tests unabhängig
Jeder Test sollte:
- seinen Zustand selbst vorbereiten
- die eigentliche Prüfung ausführen
- erzeugte Daten bereinigen oder isolieren
Vermeiden Sie Tests, die von der Ausführungsreihenfolge abhängen. Wenn eine ID oder ein Token von einer Anfrage zur nächsten gebraucht wird, übergeben Sie diesen Wert explizit innerhalb des Szenarios.
Isolieren Sie Umgebungen
Nutzen Sie getrennte Umgebungen für:
- lokale Entwicklung
- CI
- Staging
- Produktion
Speichern Sie je Umgebung:
- Base URL
- Tokens
- API Keys
- Testnutzer
- Feature Flags
- Timeouts
So läuft derselbe Test gegen verschiedene Ziele, ohne dass Sie den Test selbst ändern müssen. Mehr dazu: Sandbox vs. Testumgebung
Parametrisieren Sie mit Variablen
Hardcodieren Sie keine Hosts, Tokens oder Geheimnisse. Stattdessen:
{{baseUrl}}/api/users/{{userId}}
Authorization: Bearer {{accessToken}}
Das macht Tests portabel und CI-tauglich.
Shift Left: früher testen, nicht nur mehr testen
„Shift Left“ bedeutet: Tests früher im Lieferzyklus ausführen, näher an dem Zeitpunkt, an dem Code geschrieben wird. Je später ein Fehler gefunden wird, desto teurer ist seine Behebung. Eine Schema-Inkonsistenz im API-Design ist oft in Minuten behoben. Dieselbe Inkonsistenz in Produktion kann ein Incident sein.
1. Vertrag zuerst entwerfen
Definieren Sie Requests und Responses, bevor Sie den Endpunkt implementieren. Das ermöglicht:
- frühe Reviews
- Mocking
- Vertragstests
- parallele Frontend-Entwicklung
- frühere Fehlererkennung
2. Gegen Mocks testen
Wenn das Backend noch nicht fertig ist, können Konsumenten trotzdem gegen einen Mock testen. Ein Mock-Server aus dem Schema hilft bei:
- Frontend-Entwicklung
- Integrationsvorbereitung
- früher Validierung von Response-Formaten
- schnellerem Feedback
3. Schnelle Checks bei jedem Commit ausführen
Funktionale Tests und Vertragstests, die in Sekunden laufen, gehören in die Entwickler-Feedback-Schleife. Je früher ein Entwickler einen roten Test sieht, desto günstiger ist die Korrektur.
Mehr dazu: Shift-Left-Testing in der API-Entwicklung
Tests in CI automatisieren
Eine Strategie ist erst dann real, wenn sie ohne manuelle Ausführung läuft. Ziel:
- Tests laufen bei jedem Push
- fehlgeschlagene Assertions blockieren Merges
- Reports sind im CI-System sichtbar
- Exit-Codes steuern den Build-Status
Typische CI-Stufen
Bei jedem Push:
- schnelle funktionale Tests
- Vertragstests
- Build schlägt bei Fehlern fehl
Nächtlich oder vor Release:
- Integrationssuiten
- End-to-End-Workflows
- Sicherheitsprüfungen
- Lasttests
Immer maschinenlesbare Reports erzeugen:
- JUnit XML veröffentlichen
- HTML-Report als Artefakt speichern
Minimaler GitHub-Actions-Job
name: api-tests
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Run API tests
run: npm test
Das Muster bleibt unabhängig vom Tool gleich:
- Code auschecken
- Runtime einrichten
- Tests ausführen
- Nicht-Null-Exit-Code lässt den Build fehlschlagen
- Report veröffentlichen
Mehr dazu: wie man API-Tests in CI/CD automatisiert
Wie Apidog in die Strategie passt
Die Strategie ist grundsätzlich tool-agnostisch. Sie können Design, Tests, Mocking und Dokumentation mit separaten Tools abbilden. Der Nachteil: Drift.
Typische Drift-Probleme:
- Spezifikation sagt etwas anderes als Tests
- Mock antwortet anders als echte API
- Dokumentation ist veraltet
- Vertrag und Implementierung laufen auseinander
Apidog bündelt diese Teile an einem Ort:
- API-Vertrag entwerfen
- Testszenarien gegen den Vertrag schreiben
- Mock aus demselben Schema erzeugen
- Dokumentation aus derselben Quelle veröffentlichen
Da Tests und Mock aus demselben Vertrag entstehen, werden Vertrags- und Shift-Left-Tests einfacher in den normalen Workflow integriert.
Apidog CLI in CI verwenden
Die Apidog CLI führt gespeicherte Szenarien und Suiten headless aus. Sie ist ein Node-Paket und passt damit in CI-Systeme, die Node ausführen können.
Installation:
npm install -g apidog-cli
Comments
No comments yet. Start the discussion.