Edge Case Tests mit Claude generieren: Grenzfälle systematisch finden
AI generated
Claude
>_
Claude AI · Testing/QA · Edge Cases · PHPUnit
Edge Case Tests mit Claude generieren
Grenzfälle finden, bevor sie zum Produktionsbug werden

Die meisten Bugs entstehen nicht in der Mitte der Logik, sondern an ihren Rändern: leere Listen, negative Mengen, abgelaufene Tokens, gleichzeitige Zugriffe. Claude hilft, diese Edge Cases systematisch aus Code, Spezifikation und Domänenwissen abzuleiten, statt sie dem Zufall im Review zu überlassen.

17 Min. Lesezeit Edge Case Tests · Grenzwertanalyse · PHPUnit · Claude Code Praxisbeispiele aus Magento-Projekten

1. Warum Edge Cases in der Praxis übersehen werden

Ein Edge Case ist ein Eingabewert oder Systemzustand an der Grenze des erwarteten Verhaltens, dort wo Annahmen aus dem Happy Path nicht mehr gelten. Entwickler schreiben zuerst Tests für den Normalfall, weil dieser am einfachsten zu formulieren ist und die Anforderung am direktesten abbildet. Die Randbereiche, in denen ein Warenkorb leer ist, ein Rabatt genau die Bestellsumme erreicht oder ein Zeitstempel exakt auf Mitternacht fällt, bleiben dabei häufig unberücksichtigt, obwohl genau dort ein großer Teil der Produktionsfehler entsteht.

Das Problem verschärft sich mit der Komplexität des Systems. Je mehr Zustände, Berechtigungsstufen und externe Abhängigkeiten ein Feature hat, desto mehr Kombinationen von Randbedingungen ergeben sich, und desto unwahrscheinlicher ist es, dass ein Mensch sie alle im Kopf durchspielt. Claude kann hier als systematischer Sparringspartner dienen: Statt sich auf die Intuition eines einzelnen Entwicklers zu verlassen, lässt sich der Code oder die Spezifikation gezielt nach Edge Cases befragen, mit dem Ergebnis einer strukturierten Liste statt einer zufälligen Auswahl.

Wichtig ist dabei die Erwartungshaltung: Edge Case Tests mit Claude generieren bedeutet nicht, dass die KI die Fachlogik vollständig versteht und automatisch korrekt bewertet. Es bedeutet, dass Claude aus Code-Struktur, Typen, Validierungslogik und Domänenbegriffen eine breite Kandidatenliste ableitet, die ein Mensch anschließend priorisiert und gegen die tatsächliche Anforderung prüft. Diese Arbeitsteilung ist der Kern eines produktiven Einsatzes.

2. Wie Claude Edge Cases systematisch identifiziert

Claude arbeitet bei der Suche nach Edge Cases im Kern mit Mustererkennung über bekannte Kategorien: numerische Grenzwerte, leere Collections, Nullwerte, ungültige Typen, Zeichenkodierung, Zeitzonen, Nebenläufigkeit und Berechtigungsgrenzen. Wird Claude ein Funktionssignatur oder eine Klasse vorgelegt, geht das Modell diese Kategorien der Reihe nach durch und prüft, welche davon auf die konkrete Implementierung zutreffen. Das Ergebnis ist deutlich breiter als das, was ein einzelner Entwickler unter Zeitdruck durchdenkt.

Entscheidend ist die Eingabequalität. Ein Prompt, der nur nach "Edge Cases für diese Funktion" fragt, liefert generische Antworten. Wird dagegen der vollständige Funktionskörper inklusive Typannotationen, Validierungsregeln und angrenzender Aufrufer mitgegeben, kann Claude spezifische Randbedingungen ableiten, etwa dass ein Rabattcode-Feld auf 8 Zeichen begrenzt ist und damit sowohl leere Strings als auch überlange Eingaben getestet werden sollten. Diese Präzision entsteht nicht durch Zauberei, sondern durch die Menge an Kontext, die dem Modell zur Verfügung steht.

Ein bewährtes Vorgehen ist die zweistufige Abfrage: Zunächst lässt man sich eine Kategorienliste ohne konkrete Testfälle ausgeben, etwa "Grenzwerte", "Nebenläufigkeit", "Fehlerhafte Eingabetypen". Erst im zweiten Schritt, nach kurzer manueller Prüfung der Kategorien, generiert man für jede relevante Kategorie konkrete Testfälle. Dieses zweistufige Vorgehen verhindert, dass Claude Zeit auf irrelevante Kategorien verwendet, und erhöht die Trefferquote der eigentlichen Testfallgenerierung erheblich.


# Two-step edge case discovery with Claude Code CLI
# Step 1: category discovery only, no test code yet
claude -p "Read src/Model/PriceCalculator.php and list edge case
categories relevant to calculateFinalPrice(). Only category names
with one-sentence justification, no test code yet."

# Step 2: after manual review, generate concrete test cases
# for the selected categories
claude -p "For PriceCalculator::calculateFinalPrice(), generate
PHPUnit test cases for these categories: boundary values,
empty collections, negative quantities. One test method per case."

3. Prompt-Strategien für die Grenzwertanalyse

Die Grenzwertanalyse, im Englischen Boundary Value Analysis, ist eine der ältesten und zuverlässigsten Testtechniken überhaupt: Fehler häufen sich statistisch an den Rändern eines gültigen Wertebereichs, nicht in seiner Mitte. Für Claude lässt sich diese Technik direkt als Prompt-Muster formulieren, indem man explizit nach den Werten unmittelbar unterhalb, am, und unmittelbar oberhalb einer Grenze fragt. Ein Prompt wie "Nenne für den Parameter quantity mit gültigem Bereich 1 bis 100 die Grenzwerte und je einen Testfall darunter, darauf und darüber" liefert präzisere Ergebnisse als eine offene Frage nach "Edge Cases für quantity".

Eine zweite wirksame Prompt-Strategie ist das explizite Benennen von Fehlerzustandsklassen: Timeout, doppelter Request, abgelaufene Session, gleichzeitige Schreibzugriffe auf denselben Datensatz. Claude kann für jede dieser Klassen passende Testszenarien vorschlagen, wenn die Klasse konkret benannt wird, statt sich auf eine implizite Erwartung zu verlassen, dass das Modell diese Kategorie von selbst priorisiert. Die Formulierung "Was passiert, wenn zwei Requests gleichzeitig denselben Warenkorb ändern" ist konkreter und ergiebiger als "Finde alle Edge Cases".

Drittens hilft es, Claude explizit nach dem schlechtesten realistischen Fall zu fragen: Was ist die unwahrscheinlichste, aber noch plausible Eingabe, die ein Angreifer oder ein fehlerhafter Client senden könnte? Diese Frage bringt regelmäßig Testfälle hervor, die weder im Happy Path noch in der klassischen Grenzwertanalyse auftauchen, etwa negative Preise durch eine manipulierte API-Anfrage oder ein Datum im Jahr 9999 durch einen fehlerhaften Client.

4. Praxisbeispiel: Edge Cases für eine Preisberechnung

Als konkretes Beispiel dient eine Preisberechnung für einen Warenkorb mit Mengenrabatt und Gutscheincode, ein typisches Muster in Magento-Shops. Die Kernfunktion nimmt Menge, Einzelpreis, Rabattstaffel und optionalen Gutscheincode entgegen und berechnet den Endpreis. Auf den ersten Blick wirkt die Logik simpel, doch schon eine kurze Abfrage bei Claude zeigt mehr als ein Dutzend Randbedingungen, die im ursprünglichen Test fehlten.


<?php
declare(strict_types=1);

namespace Mironsoft\Pricing\Test\Unit;

use Mironsoft\Pricing\Model\PriceCalculator;
use PHPUnit\Framework\TestCase;

/**
 * Edge case suite generated with Claude for PriceCalculator.
 * Categories: boundary values, empty input, invalid discount codes.
 */
final class PriceCalculatorEdgeCaseTest extends TestCase
{
    private PriceCalculator $calculator;

    protected function setUp(): void
    {
        $this->calculator = new PriceCalculator();
    }

    public function testZeroQuantityReturnsZeroPrice(): void
    {
        $result = $this->calculator->calculateFinalPrice(0, 19.99, null);
        $this->assertSame(0.0, $result);
    }

    public function testNegativeQuantityThrowsException(): void
    {
        $this->expectException(\InvalidArgumentException::class);
        $this->calculator->calculateFinalPrice(-1, 19.99, null);
    }

    public function testQuantityExactlyAtDiscountThresholdApplies(): void
    {
        // Threshold is 10 units — boundary value, not 9 or 11
        $result = $this->calculator->calculateFinalPrice(10, 10.00, null);
        $this->assertEqualsWithDelta(90.00, $result, 0.01);
    }

    public function testQuantityOneBelowThresholdDoesNotApply(): void
    {
        $result = $this->calculator->calculateFinalPrice(9, 10.00, null);
        $this->assertEqualsWithDelta(90.00, $result, 0.01);
    }

    public function testEmptyCouponCodeIsTreatedAsNoCoupon(): void
    {
        $result = $this->calculator->calculateFinalPrice(1, 50.00, '');
        $this->assertEqualsWithDelta(50.00, $result, 0.01);
    }

    public function testCouponCodeWithMaxLengthIsAccepted(): void
    {
        $maxLengthCode = str_repeat('A', 8); // field limit is 8 chars
        $result = $this->calculator->calculateFinalPrice(1, 50.00, $maxLengthCode);
        $this->assertIsFloat($result);
    }
}

Die Testfälle zeigen ein wiederkehrendes Muster: Claude prüft konsequent den Wert genau an der Grenze, nicht nur davor oder danach, und behandelt leere Strings, Nullwerte und maximale Feldlängen als eigenständige Kategorien statt als Sonderfall des Normalpfads. Ohne diese systematische Abfrage wäre im Beispiel vermutlich nur die Rabattgrenze getestet worden, nicht aber der Leerstring-Gutschein oder die maximale Codelänge.

5. Boundary Value Analysis mit Claude kombinieren

Die klassische Grenzwertanalyse unterscheidet zwischen einfachen Grenzen (ein Minimum, ein Maximum) und robusten Grenzen, bei denen auch Werte knapp außerhalb des gültigen Bereichs betrachtet werden. Claude kann beide Varianten auf Zuruf anwenden, wenn man explizit sagt, welche Variante gewünscht ist. Für sicherheitskritische Bereiche wie Zahlungsabwicklung empfiehlt sich grundsätzlich die robuste Variante, weil dort auch geringfügig ungültige Eingaben, etwa ein Preis von minus einem Cent, zu inakzeptablen Ergebnissen führen können.

Ein praktischer Kniff ist, Claude zu bitten, die Grenzwerte tabellarisch mit der jeweiligen Testerwartung auszugeben, bevor der eigentliche Testcode geschrieben wird. Diese Zwischentabelle lässt sich in wenigen Minuten von einem Entwickler gegenlesen und korrigieren, deutlich schneller als das Gegenlesen von fertigem Testcode. Erst wenn die Tabelle fachlich korrekt ist, wird sie in PHPUnit-, Jest- oder Pytest-Code übersetzt. Dieses Zwischenprodukt reduziert die Wahrscheinlichkeit, dass ein fachlich falscher Testfall unbemerkt in die Suite gelangt.

6. Null-, Leer- und Fehlerzustände abdecken

Eine der ergiebigsten Kategorien für Edge Case Tests sind Null- und Leerzustände: eine leere Bestellung, ein Kundenkonto ohne Adresse, eine Produktvariante ohne Preis. Diese Zustände sind fachlich meist erlaubt, werden aber in der Implementierung oft implizit ausgeschlossen, weil der Entwickler beim Schreiben des Happy Path unbewusst von einem gefüllten Zustand ausgeht. Claude lässt sich gezielt bitten, für jede Collection und jedes Optionale Feld im Code den Leer- beziehungsweise Nullfall zu benennen und daraus einen Testfall abzuleiten.

Fehlerzustände gehen einen Schritt weiter: Was passiert, wenn eine externe Abhängigkeit, etwa eine Zahlungs-API, einen Fehler zurückgibt, einen Timeout auslöst oder eine unerwartete Antwortstruktur liefert? Claude kann für solche Szenarien Mocks und Stubs vorschlagen, die genau diese Fehlerpfade simulieren, statt sich nur auf den erfolgreichen Rückgabewert zu konzentrieren. In der Praxis zeigt sich, dass gerade Fehlerpfade in Integrationstests häufig komplett fehlen, weil sie beim ersten Schreiben des Features nicht im Vordergrund standen.


<?php
declare(strict_types=1);

namespace Mironsoft\Payment\Test\Unit;

use Mironsoft\Payment\Model\PaymentGateway;
use Mironsoft\Payment\Model\PaymentGatewayClientInterface;
use PHPUnit\Framework\TestCase;

/**
 * Edge case suite for error paths of an external payment dependency.
 * Generated with Claude after specifying the failure classes explicitly.
 */
final class PaymentGatewayErrorPathTest extends TestCase
{
    public function testGatewayTimeoutIsTranslatedToRetryableException(): void
    {
        $client = $this->createMock(PaymentGatewayClientInterface::class);
        $client->method('charge')->willThrowException(new \RuntimeException('timeout'));

        $gateway = new PaymentGateway($client);

        $this->expectException(\Mironsoft\Payment\Model\Exception\RetryablePaymentException::class);
        $gateway->charge(19.99, 'tok_test');
    }

    public function testUnexpectedResponseShapeDoesNotCrashSilently(): void
    {
        $client = $this->createMock(PaymentGatewayClientInterface::class);
        // Response missing the expected "status" field entirely
        $client->method('charge')->willReturn(['unexpected_field' => true]);

        $gateway = new PaymentGateway($client);

        $this->expectException(\Mironsoft\Payment\Model\Exception\MalformedResponseException::class);
        $gateway->charge(19.99, 'tok_test');
    }
}

7. Edge Cases für APIs und Schnittstellen

Bei REST- und GraphQL-Schnittstellen verschiebt sich der Fokus von internen Funktionsgrenzen zu externen Vertragsverletzungen: fehlende Pflichtfelder, falscher Content-Type, überlange Payloads, unerwartete Zeichenkodierungen. Claude eignet sich gut, um aus einer OpenAPI-Spezifikation oder einem GraphQL-Schema systematisch die Menge an ungültigen Anfragen abzuleiten, die ein Client theoretisch senden könnte, auch wenn die eigene Anwendung solche Anfragen normalerweise nicht erzeugt.

Besonders wertvoll ist dieser Ansatz bei API-Versionierung und Abwärtskompatibilität: Claude kann anhand zweier Schema-Versionen konkrete Testfälle formulieren, die prüfen, ob ein älterer Client mit fehlenden neuen Feldern noch korrekt bedient wird. Solche Kompatibilitätslücken werden in der Praxis selten manuell getestet, weil sie kognitiv aufwendig zu durchdenken sind, aber genau deshalb profitieren sie stark von einer strukturierten KI-gestützten Analyse.


{
  "edge_case_requests": [
    {
      "name": "missing_required_field",
      "payload": { "sku": "TEST-001" },
      "expected_status": 422,
      "reason": "quantity field is required but omitted"
    },
    {
      "name": "quantity_at_upper_boundary",
      "payload": { "sku": "TEST-001", "quantity": 999 },
      "expected_status": 201,
      "reason": "999 is the documented maximum order quantity"
    },
    {
      "name": "quantity_above_boundary",
      "payload": { "sku": "TEST-001", "quantity": 1000 },
      "expected_status": 422,
      "reason": "one unit above the documented maximum"
    },
    {
      "name": "duplicate_idempotency_key",
      "payload": { "sku": "TEST-001", "quantity": 1, "idempotency_key": "abc-123" },
      "expected_status": 409,
      "reason": "same idempotency key sent twice in a row"
    }
  ]
}

8. Integration in bestehende Testsuiten

Edge Case Tests, die mit Claude generiert werden, sollten nicht als isolierte Sonderdatei neben der bestehenden Testsuite existieren, sondern als reguläre Testklassen in dieselbe Verzeichnisstruktur und CI-Pipeline integriert werden. Ein bewährtes Muster ist ein eigener Namenszusatz wie EdgeCaseTest, der in Reports klar erkennbar bleibt, aber technisch genauso behandelt wird wie jeder andere PHPUnit- oder Jest-Test. So verschwinden die generierten Tests nicht in einem separaten, irgendwann vergessenen Skript.

Zur Nachvollziehbarkeit empfiehlt sich, in jedem generierten Testfall per Kommentar zu dokumentieren, welche Edge-Case-Kategorie abgedeckt wird und dass der Testfall ursprünglich mit Unterstützung von Claude entstanden ist. Diese Dokumentation hilft künftigen Code-Reviewern, die Absicht hinter einem scheinbar exotischen Testfall nachzuvollziehen, statt ihn versehentlich als überflüssig zu löschen. Gerade bei Randfällen, die selten auftreten, ist dieser Kontext entscheidend für die langfristige Wartbarkeit der Suite.


# Run only the generated edge case suite in CI, separate report target
vendor/bin/phpunit --testsuite EdgeCases \
  --log-junit var/log/edge-case-results.xml

# Combine with the regular suite for the full coverage report
vendor/bin/phpunit --testsuite Unit,EdgeCases \
  --coverage-html var/log/coverage-html

9. Grenzen: Was Claude nicht zuverlässig findet

Claude kennt die geschriebene Spezifikation und den Code, aber nicht das ungeschriebene Domänenwissen, das nur im Kopf erfahrener Kolleginnen und Kollegen existiert, etwa eine historisch gewachsene Sonderregel für einen einzelnen Großkunden. Solche impliziten Randfälle findet keine KI zuverlässig, weil sie in keiner Quelle dokumentiert sind, die dem Modell zugänglich ist. Ebenso schwer fällt Claude die Priorisierung nach Geschäftsrisiko: Das Modell listet Kategorien mit ähnlichem Gewicht, während ein erfahrener Tester weiß, welcher Randfall im letzten Quartal tatsächlich zu einem Produktionsvorfall geführt hat.

Ansatz Abdeckung Geschwindigkeit Domänenwissen
Nur manuell Lückenhaft, abhängig von Erfahrung Langsam Hoch
Nur Claude Breit, systematisch Schnell Fehlt implizites Wissen
Claude plus manuelle Priorisierung Breit und relevant Schnell Hoch

Die Tabelle zeigt den entscheidenden Punkt: Weder die rein manuelle noch die rein KI-gestützte Variante liefert das beste Ergebnis. Erst die Kombination aus Claudes systematischer Breite und der fachlichen Priorisierung durch das Team führt zu einer Testsuite, die sowohl viele Randfälle abdeckt als auch die tatsächlich riskanten davon zuerst behandelt.

Mironsoft

KI-gestützte Testautomatisierung für Magento und Hyvä

Edge Cases in eurer Anwendung systematisch aufdecken?

Wir kombinieren Claude-gestützte Testfallgenerierung mit fachlicher Priorisierung und bauen daraus belastbare PHPUnit- und E2E-Suiten für euren Magento-Shop.

Edge-Case-Audit

Bestehenden Code systematisch mit Claude auf Grenzfälle prüfen

Testfallgenerierung

PHPUnit-Suiten mit Fokus auf Boundary Values und Fehlerpfade

CI-Integration

Generierte Tests sauber in bestehende Pipelines einbetten

10. Zusammenfassung

Edge Case Tests mit Claude generieren heißt, Code, Spezifikation und Domänenbegriffe systematisch nach bekannten Kategorien wie Grenzwerten, Leerzuständen, Fehlerpfaden und Nebenläufigkeit abzufragen, statt sich auf zufällige Intuition zu verlassen. Die zweistufige Abfrage, zuerst Kategorien, dann konkrete Testfälle, liefert präzisere Ergebnisse als eine offene Frage nach Edge Cases. Konkrete Beispiele wie die Preisberechnung zeigen, dass Claude zuverlässig Grenzwerte, leere Eingaben und maximale Feldlängen als eigene Testfälle vorschlägt.

Der größte Nutzen entsteht durch die Kombination aus Claudes systematischer Breite und der fachlichen Priorisierung durch das Team: Claude findet die Kandidaten, Menschen entscheiden, welche davon geschäftlich relevant sind. Wer generierte Edge Case Tests sauber in bestehende PHPUnit-Suiten und CI-Pipelines integriert und die Herkunft jedes Testfalls dokumentiert, baut damit eine Testsuite auf, die deutlich mehr Randfälle abdeckt als eine rein manuell geschriebene.

Edge Case Tests mit Claude generieren — Das Wichtigste auf einen Blick

Zweistufige Abfrage

Erst Kategorien identifizieren lassen, dann pro Kategorie konkrete Testfälle generieren. Präziser als eine offene Frage.

Boundary Value Analysis

Werte knapp unterhalb, an und oberhalb einer Grenze explizit anfragen. Fehler häufen sich statistisch an den Rändern.

Null- und Leerzustände

Leere Collections und optionale Felder gezielt benennen lassen. Fehlerpfade externer Abhängigkeiten mocken.

Grenzen kennen

Implizites Domänenwissen und Geschäftsrisiko-Priorisierung bleiben Aufgabe des Teams, nicht der KI.

11. FAQ: Edge Case Tests mit Claude generieren

1Was ist ein Edge Case im Softwaretest?
Ein Eingabewert oder Systemzustand an der Grenze des erwarteten Verhaltens, etwa eine leere Liste oder ein Grenzwert, an dem Annahmen des Normalfalls nicht mehr gelten.
2Findet Claude Edge Cases vollständig automatisch?
Nein. Claude liefert eine breite Kandidatenliste, die priorisiert werden muss. Implizites Domänenwissen kann die KI nicht kennen.
3Warum zweistufig abfragen?
Erst Kategorien, dann Testfälle je Kategorie. Verhindert Zeitverschwendung auf irrelevante Kategorien.
4Was ist Boundary Value Analysis?
Prüfung von Werten knapp unterhalb, an und oberhalb einer Grenze, da sich Fehler statistisch an den Rändern häufen.
5Wie formuliert man einen guten Grenzwert-Prompt?
Parameter, gültigen Bereich und gewünschte Testerwartung konkret benennen, statt offen nach Edge Cases zu fragen.
6Welche Kategorien deckt Claude typischerweise ab?
Grenzwerte, leere Collections, Nullwerte, ungültige Typen, Zeitzonen, Nebenläufigkeit und Berechtigungsgrenzen.
7Wie integriert man generierte Tests?
Als reguläre Testklassen mit erkennbarem Namenszusatz in dieselbe CI-Pipeline, mit Kommentar zur Herkunft.
8Funktioniert das auch für APIs?
Ja, aus OpenAPI- oder GraphQL-Schemas lassen sich ungültige Anfragen und Kompatibilitätslücken systematisch ableiten.
9Was findet Claude nicht zuverlässig?
Ungeschriebenes Domänenwissen und Priorisierung nach tatsächlichem Geschäftsrisiko bleiben Teamaufgabe.
10Ersetzt das manuelles Testdesign?
Nein, es ergänzt es. Beste Ergebnisse entstehen aus der Kombination von Claudes Breite und fachlicher Priorisierung.