Ein Team spielt einen nächtlichen Export aus, der in der Staging-Umgebung bei 999 Nutzern problemlos läuft und in der Produktion bei genau 1.000 einen Timeout erzeugt. Niemand hat „1.000“ ins Lastenheft geschrieben. Es gibt kein Formular zu validieren, keinen Altersbereich zu prüfen. Die Grenze ist real, und die Testsuite hat sie nie berührt.
Genau diese Lücke lässt die meiste Literatur zum Testen offen. Die Grenzwertanalyse (Boundary Value Analysis, BVA) wird oft als Technik beschrieben, mit der Formulareingaben an ihren Rändern getestet werden: Alter 17, 18, 19 und 64, 65, 66. Das funktioniert für das Formular, übersieht aber alles andere. In der Praxis stecken Grenzwerte in Cookie-Größen, Cron-Zeitplänen, Connection-Pools und Batch-Laufzeiten – und keiner davon steht irgendwo geschrieben, wo ein Tester nachschauen würde. Für Gründer und Produktverantwortliche sind die geschäftlichen Kosten, wenn man sie übersieht, unmittelbar spürbar: Ein Grenzwert, der in der Produktion auslöst, bedeutet einen Support-Brand, einen verlorenen Kunden und eine verzögerte Roadmap. Genau hier zahlt sich ein systematischer Durchlauf im Bereich funktionales Testing aus.
Dieser Beitrag zeigt die fünf Stellen, an denen sich Grenzwerte in einem ausgelieferten Produkt tatsächlich verstecken, und was dort jeweils zu testen ist.
Die Grenze, die niemand aufgeschrieben hat
Grenzwertanalyse im Software-Testing ist eine Testdesign-Technik, die auf die Werte an den Rändern des Systemverhaltens abzielt – den Punkt, an dem eine Regel endet und eine andere beginnt. Die Lehrbuchversion behandelt Eingabebereiche. Die nützliche Version behandelt alles andere.
Die meisten Wettbewerber hören beim Eingabeformular auf, weil die Grenze dort leicht zu erkennen ist. Ein Feld sagt „18 bis 65“. Man testet 17, 18, 65, 66. Fertig. Echte Produkte haben Hunderte von Grenzwerten, die im Lastenheft nie erwähnt werden: die Größe, auf die ein Session-Cookie anwachsen darf, bevor der Browser ihn verwirft; die Anzahl der Zeilen, die eine Lambda-Funktion verarbeiten kann, bevor die Laufzeitumgebung sie beendet; die exakte Millisekunde, in der sich ein Rate-Limit-Fenster zurücksetzt. Jeder Einzelne davon ist ein Grenzwert. Keiner sieht wie einer aus, bis er versagt.
Die Neuausrichtung, die sich durch den Rest dieses Beitrags ziehen sollte: Grenzwertanalyse ist eine Disziplin der Grenzwert-Entdeckung, keine Übung im Werte-Austauschen. Die Aufgabe des Testers ist es, herauszufinden, wo sich das Systemverhalten ändert, und dann jede dieser Stellen zu untersuchen.
Warum Off-by-One-Fehler immer noch ausgeliefert werden
Off-by-One-Fehler werden immer noch ausgeliefert, weil Anforderungsdokumente den Idealfall beschreiben, Tester das testen, was geschrieben steht, und implizite Grenzwerte erst unter Last zutage treten. Das Consortium for Information & Software Quality bezifferte die Kosten schlechter Softwarequalität in den USA in seiner jüngsten Analyse auf 2,41 Billionen US-Dollar, und ein beachtlicher Teil dieser Summe entfällt auf Grenzwerte, die niemand dokumentiert hat.
Drei Muster treiben das voran:
- Die Obergrenze von 1.000 Zeilen pro Batch steckt in der Timeout-Konfiguration des Job-Runners, nicht im PRD
- Wenn niemand schreibt: „Die Cookie-Größe muss unter 4 KB bleiben“, fügt auch niemand einen Test dafür hinzu
- Explizite Grenzwerte werden während der Entwicklung in Unit-Tests automatisiert; implizite werden von Nutzern um 2 Uhr morgens entdeckt.
Der 2025 Annual Outage Analysis des Uptime Institute zeigt, dass 85 % der durch menschliches Versagen verursachten Ausfälle darauf zurückzuführen sind, dass Mitarbeitende Verfahren nicht befolgt haben oder die Verfahren selbst fehlerhaft waren. Fehlende Tests für undokumentierte Grenzwerte fallen eindeutig in die zweite Kategorie. Hören Sie auf zu fragen: „Welchen Bereich gibt das Lastenheft vor?“ Fragen Sie stattdessen: „Wo ändert dieses System sein Verhalten?“
Grenzwertanalyse vs. Edge-Case-Testing
Die beiden Begriffe werden oft synonym verwendet, wodurch ein nützlicher Unterschied verloren geht. BVA ist numerisch und präzise: Sie liegt an einem messbaren Schwellenwert wie Zeile 999 vs. 1.000 oder Byte 4.095 vs. 4.096. Edge-Case-Testing ist breiter angelegt und deckt ungewöhnliche Zustände und Kombinationen ab, die keinen sauberen numerischen Rand haben, etwa ein Offline-Gerät, einen Nutzer ohne jegliche Berechtigungen oder einen beschädigten Upload.
Jeder Grenzwert ist ein Edge Case. Nicht jeder Edge Case ist ein Grenzwert. Wenn sich die Verhaltensänderung in einer Zahl ausdrücken lässt, ist die Grenzwertanalyse das richtige Werkzeug. Ist die Änderung eher qualitativ als quantitativ, passt Edge-Case-Testing besser und deckt einen größeren Teil dessen ab, „wo die Anforderungen enden und die Realität beginnt“.
Fünf Orte, an denen sich Grenzwerte verstecken
Im Folgenden finden Sie die fünf Kategorien, in denen Grenzwerte stecken, die das Lastenheft nicht auflistet. Jede beginnt mit einem Fehlermuster, benennt den nicht dokumentierten Grenzwert und liefert die Testfälle, die ihn zutage fördern. Ein konkretes Beispiel für eine Grenzwertanalyse findet sich in jeder Kategorie statt in nur einem einzigen Spielzeugfeld.
Infrastrukturgrenzen, die niemand dokumentiert hat
Das Session-Cookie eines Nutzers wächst nach dem Hinzufügen eines fünften OAuth-Anbieters über 4 KB hinaus, und jede weitere Anfrage verwirft die Sitzung stillschweigend. Eine URL mit 50 Filterparametern überschreitet das 8-KB-Header-Limit eines nachgelagerten Proxys, und die API liefert 400 zurück, ohne dass ein Grund protokolliert wird. Keines der beiden Limits steht im Produkt-Lastenheft. Beide stecken in einer Konfigurationsdatei.
Zu den versteckten Grenzwerten auf dieser Ebene zählen:
- Cookie-Größe, in den meisten Browsern auf rund 4 KB pro Cookie begrenzt
- HTTP-Header-Größe, je nach Server typischerweise 8 bis 16 KB
- URL-Länge, mit praktischen CDN- und Browser-Obergrenzen von rund 2 KB
- Größe des Request-Bodys, standardmäßig 1 MB in nginx
- Paket-MTU von 1.500 Byte bei Standard-Ethernet
Testfälle, die sich lohnen: eine Payload knapp unter und knapp über jeder Obergrenze, ein Session-Cookie, das sich 4 KB nähert, eine URL mit genügend Query-Parametern, um 2 KB zu überschreiten, ein Upload, dessen Größe genau das Body-Limit des Proxys trifft. Prüfen Sie die Konfiguration, nicht das Lastenheft. Tauchen diese auf der API-Ebene auf, ist API-Testing der Ort, an dem sie erkannt werden.
Zeit- und Kalenderfallen
Zeit ist die Kategorie, die Annahmen am härtesten bestraft. Ein Abonnement, das am 31. abgerechnet wird, wird im März doppelt und im April gar nicht belastet. Ein für 2:30 Uhr geplanter Cron-Job läuft bei der herbstlichen Zeitumstellung zweimal und im Frühjahr überhaupt nicht. Ein als int32 gespeichertes Zeitstempelfeld läuft am 19. Januar 2038 um 03:14:07 UTC über, und das Jahr-2038-Problem ist ein Grenzwert mit einem Datum darauf.
Zu den zeitlichen Grenzwerten, die getestet werden sollten, gehören Monatsend-Übergänge bei 28-, 29-, 30- und 31-tägigen Monaten, der Schalttag, Zeitumstellungen in beide Richtungen, Übergänge zur ISO-Woche 53 sowie Abrechnungsjahrestage, die sich verschieben, wenn ein Monat weniger Tage hat als das Jahrestagsdatum. Richten Sie ein Abonnement am 31. Januar ein, stellen Sie die Uhr bis zum 28. Februar vor, und beobachten Sie, was die Abrechnungs-Engine tut. Führen Sie einen geplanten Job über eine Zeitumstellung hinweg in einer Zeitzone aus, die diese beobachtet. Buchen Sie ein Hotel mit Check-in am 28. Februar 2028 und Check-out am 1. März.
Obergrenzen von Datentypen
Ein als INT gespeicherter Aufrufzähler erreicht 2.147.483.647, und die nächste Erhöhung springt entweder auf eine negative Zahl oder wirft einen Fehler. Ein als Float gespeichertes Währungsfeld sammelt Rundungsfehler an, sodass eine Rechnung über 100,00 $ am Ende mit 99,9999998 $ abgeglichen wird. Eine Benutzername-Spalte, die zwischen zwei Releases von VARCHAR(50) auf VARCHAR(100) verbreitert wurde, schneidet aus dem alten Schema migrierte Zeilen stillschweigend ab.
Die Grenzwerte, die sich im Schema verstecken:
Eine Zähler-Spalte (z. B. Aufrufe, Likes, Transaktionen)
Etwa 2,14 Milliarden
Der Zähler springt plötzlich auf eine negative Zahl oder wirft einen Fehler
Jede große Zahl, die an ein JavaScript-Frontend gesendet wird
Etwa 9 Billiarden
Die Zahl verliert an Präzision: Die letzten Stellen ändern sich unbemerkt während der Übertragung
Ein Preis- oder Währungsfeld, das als Dezimalnäherung gespeichert wird
Etwa 7 Stellen Genauigkeit
100,00 $ kommen als 99,9999998 $ zurück, und das Hauptbuch stimmt nicht mehr überein
Eine Textspalte mit fester Breite (Name, E-Mail, Beschreibung)
Je nachdem, auf welche Breite die Spalte eingestellt wurde
Bei einem Datenbank-Upgrade werden längere Werte ohne Warnung abgeschnitten
Automatisch generierte IDs aus einer schwachen Zufallsquelle
Früher, als die Mathematik verspricht
Zwei Datensätze erhalten dieselbe ID, und einer überschreibt den anderen
Lesen Sie das Schema, bevor Sie den Testplan schreiben. Diese Grenzwerte sind in der Benutzeroberfläche unsichtbar und in der Datenbank offensichtlich.
Paginierungs- und Batch-Abgründe
Paginierungs-Grenzwerte liegen bei der ersten Seite, der letzten Seite und dem Übergang zwischen Seiten, wenn die Gesamtzahl ein exaktes Vielfaches der Seitengröße ist. Batch-Grenzwerte liegen bei welcher Laufzeitgrenze auch immer der Executor durchsetzt – seien es die 15 Minuten von Lambda, die 60 Minuten von Cloud Run oder der 5-Minuten-Cron-Job, den das SRE-Team vor zwei Jahren eingerichtet hat.
Das klassische Muster: Ein Export verarbeitet in der Staging-Umgebung 999 Zeilen und läuft in der Produktion bei 1.000 in einen Timeout, weil der eigentliche Grenzwert das Laufzeitlimit ist, nicht die Zeilenanzahl. Ein weiteres: Eine Listenansicht zeigt 10 Einträge pro Seite an, und Seite 10 wird leer gerendert, weil die Cursor-Logik offset = page × limit lautet, wobei die Seitenzählung in der URL bei 1 und in der Datenbankabfrage bei 0 beginnt.
Testfälle zum Ergänzen: genau page_size × N Datensätze laden und Seite N sowie N+1 anfragen. Seite 0 und Seite −1 anfragen. Den Batch-Job mit einem Datensatz ausführen, der eine Zeile über der beobachteten Timeout-Schwelle liegt. Eine Tabelle mit genau dem Zeilenlimit des Tools exportieren; Google Sheets liegt bei 10 Millionen Zellen, Excel bei 1.048.576 Zeilen.
Nebenläufigkeits-Schwellenwerte
Der 5. gleichzeitige Nutzer auf einem Konto mit begrenzter Sitzungsanzahl löst den Ausschluss von Sitzung 1 aus, doch die Sperre für diesen Ausschluss verursacht einen Deadlock mit dem Login-Ablauf. Der Datenbank-Connection-Pool ist auf 20 eingestellt, und die 21. Abfrage blockiert stillschweigend, statt einen Fehler zu werfen. Ein Rate-Limiter erlaubt 100 Anfragen pro Minute; die 101. Anfrage in einem Burst liefert 429 zurück, doch der Zähler setzt sich schon eine Millisekunde nach Beginn des nächsten Zeitfensters zurück, und derselbe Client schnellt sofort wieder in die Höhe.
Zu den Nebenläufigkeits-Grenzwerten zählen die Sitzplatzgrenze des Tarifs, die Obergrenze des Datenbank-Connection-Pools, die Größe des Thread-Pools, die Grenze des Rate-Limit-Fensters (fest vs. gleitend), Schwellenwerte für Sperrkonflikte sowie die Warteschlangentiefe, ab der Konsumenten hinter den Produzenten zurückfallen. Testen Sie, indem Sie eine Sitzung mehr öffnen, als der Tarif erlaubt, und das Ausschlussverhalten beobachten. Führen Sie pool_size + 1 gleichzeitige Abfragen aus, und messen Sie, ob blockiert oder ein Fehler geworfen wird. Feuern Sie N Anfragen an der festen Fenstergrenze des Rate-Limits ab und dann eine Millisekunde nach dem Reset weitere N.
Das sind die Grenzwerte, die sich verstecken, bis der Traffic zunimmt. Die 2025 ITIC/Calyptix SMB Downtime Survey fand heraus, dass 8 % der kleinen und mittleren Unternehmen inzwischen Ausfallkosten von über 25.000 $ pro Stunde melden, und eine Nebenläufigkeitsgrenze, die um 3 Uhr morgens auslöst, ist einer der schnellsten Wege, diese Summe zu erreichen.
Wie man Grenzwerte findet, die das Lastenheft ausgelassen hat
Entdeckung ist wertvoller als das Austauschen von Werten. Vier Fragen funktionieren bei jedem zu testenden Feature:
- Wovon hängt dieses Feature ab? Cookies, Header, URLs, Request-Bodys, Timer, Datenbankspalten, Connection-Pools. Jede Abhängigkeit hat eine Grenze.
- Wo liegt die Grenze jeder Abhängigkeit? Lesen Sie die Konfigurationsdatei, das Schema, das SLA, die Kontingentseite des Cloud-Anbieters. Steht die Grenze nirgends geschrieben, finden Sie sie mit einem Lasttest heraus.
- Was passiert genau an dieser Grenze, eins darunter und eins darüber? Das ist der klassische Schachzug der Grenzwertanalyse, angewandt auf Infrastruktur statt auf ein Formularfeld.
- Was passiert, wenn sich die Grenze ändert? Eine Schema-Migration, ein Tarif-Upgrade, eine Konfigurationsänderung. Grenzwerte verschieben sich. Tests sollten sich mit ihnen verschieben.
Der Grenzwert ist real, egal ob ihn jemand aufgeschrieben hat oder nicht. Die Aufgabe des Testers ist es, ihn zu finden, bevor der Nutzer es tut.
Wo die Grenzwertanalyse in Ihr Testdesign passt
Grenzwerttests finden heraus, wo ein System sein Verhalten ändert. Äquivalenzklassenbildung zeigt Ihnen, welche der Werte zwischen den Grenzwerten Sie gefahrlos auslassen können. Zusammen komprimieren sie einen riesigen Eingaberaum zu einem kleinen, aussagekräftigen Testset, das genau die Fehler abfängt, die es zu finden lohnt.
Zwei Nachbartechniken im selben Werkzeugkasten machen die Grenzwertanalyse noch schärfer. Die Äquivalenzklassenbildung gruppiert Werte, die sich gleich verhalten, und zeigt Ihnen, welche der Werte zwischen den Grenzwerten Sie gefahrlos auslassen können. Negativtests erzeugen die schlechten Eingaben, die die Anforderungen nie vorgesehen haben, und fangen damit die Fehler ab, nach denen die Grenzwertanalyse nicht sucht. Zusammen komprimieren alle drei einen riesigen Eingaberaum zu einem kleinen, aussagekräftigen Testset, das genau die Fehler abfängt, die es zu finden lohnt.
Kartieren Sie die Grenze, bevor Ihre Nutzer es tun
Ein Tester, der versteckte Grenzwerte im Griff hat, testet keine Werte. Er kartiert die Stellen, an denen sich das Systemverhalten ändert, und untersucht dann jede Einzelne davon. Das Lastenheft ist der Ausgangspunkt der Grenzwertanalyse, nicht die vollständige Landkarte.
Wenn Ihr letzter Off-by-One-Fehler an der Testsuite vorbeigeschlüpft ist, besteht die Lösung nicht in mehr Testfällen, sondern in einem systematischen Durchgang durch die Grenzwerte, die niemand aufgeschrieben hat. Kontaktieren Sie uns, und wir schauen uns an, wo sie sich in Ihrem Produkt verstecken könnten.
FAQ
Welche Grenzwerte sollte ich zusätzlich zu Eingabebereichen testen?
Testen Sie die Grenzwerte, die das Lastenheft nicht auflistet: Cookie- und Header-Größe, URL-Länge, Obergrenzen für Request-Bodys, MTU, Zeitumstellungen und Monatsend-Übergänge, Präzisionsgrenzen von int32 und Float, VARCHAR-Breite über verschiedene Schemaversionen hinweg, Paginierung bei erster/letzter/exakt vervielfachter Seite, Batch-Laufzeitgrenzen, Obergrenzen von Connection-Pools, Ränder von Rate-Limit-Fenstern und Sitzplatzgrenzen von Tarifen. Genau dort werden Off-by-One-Fehler tatsächlich ausgeliefert.
Wie findet man Grenzwerte, die nicht in den Anforderungen stehen?
Stellen Sie bei jedem Feature vier Fragen: Wovon hängt es ab, wo liegt die Grenze jeder Abhängigkeit, was passiert an dieser Grenze und unmittelbar darum herum, und was passiert, wenn sich die Grenze ändert. Lesen Sie die Konfigurationsdatei, das Schema und die Kontingentseite des Cloud-Anbieters. Steht eine Grenze nirgends geschrieben, findet ein Lasttest sie heraus.
Was ist der Unterschied zwischen Grenzwertanalyse und Edge-Case-Testing?
Grenzwertanalyse ist numerisch und präzise; sie liegt an einem messbaren Schwellenwert wie Zeile 999 vs. 1.000. Edge-Case-Testing ist breiter angelegt und deckt ungewöhnliche Zustände oder Kombinationen ab, die keinen sauberen numerischen Rand haben, etwa ein Offline-Gerät oder einen Nutzer ohne jegliche Berechtigungen. Jeder Grenzwert ist ein Edge Case; nicht jeder Edge Case ist ein Grenzwert.
Warum werden Off-by-One-Fehler 2026 immer noch ausgeliefert?
Anforderungsdokumente beschreiben den Idealfall, Tester testen das, was geschrieben steht, und implizite Grenzwerte treten erst unter Last zutage. Explizite Grenzwerte werden während der Entwicklung automatisiert. Implizite, wie eine Lambda-Laufzeitgrenze oder ein Cookie-Größenlimit, werden von Nutzern um 2 Uhr morgens entdeckt – weil niemand einen Test für eine Grenze geschrieben hat, die niemand aufgeschrieben hat.
Erfahren Sie, wie QAwerk die Bug-Reports nach dem Launch einer Massen-SMS-App um 65 % senkte, indem systematisch die Fehler abgefangen wurden, die erst im großen Maßstab zutage treten.