🧪 Vom Leben-nicht-Testen zum Verhaltenstest
vom 2. August 2026
KI hat das Schreiben von Tests billig gemacht. Die Schwierigkeit besteht nun darin, auszuwählen, was ein Orakel verdient.
Ihre KI schreibt Tests. Sind diese Tests überhaupt sinnvoll?
Das ist keine rhetorische Floskel. Es ist die Frage, hier schwache Tests mittlerweile ein Risiko darstellen. Programmierer ändern Code schneller, als menschliche Prüfer nachverfolgen können. Die Testsuite ist die Versicherung für jede Änderung. Wenn die Suite nur beweist, dass Mocks in der richtigen Reihenfolge aufgerufen wurden, dass await() einmal ausgeführt wurde oder dass etwas DTO-ähnliches zurückgegeben wurde, dann ist die Versicherung reine Show.
Sebastian Bergmann sagt im Grunde dasselbe, nur mit anderen Worten. Hinter jedem grünen Balken verbirgt sich ein Testorakel: das Verfahren, das entscheidet, ob ein Ergebnis korrekt ist. Ein bestandener Test bedeutet nicht, dass das Produkt richtig ist. Er bedeutet lediglich, dass das von Ihnen – bewusst oder unbewusst – gewählte Orakel zufrieden war.
Dieser Artikel ist kein PHPUnit-Tutorial. Er ist keine Abhandlung über testgetriebene Entwicklung (TDD). Er ist kein Vergleich von ReactPHP und AMP.
Es handelt sich um einen subjektiven Einblick in ein kleines Begleitprojekt – nolife-tests (unter Darkwood content/) –, das Darkwood Flow verwendet, um eine architektonische Behauptung zu konkretisieren:
Jobs sind Geschäftsprozesse. Treiber sind Laufzeitumgebungen. Anwendungssuiten sollten erstere priorisieren und letztere ignorieren.
Wenn Sie nach dem Lesen dieses Textes immer noch stolz auf alle erfolgreichen Tests in Ihrem Repository sind, habe ich versagt. Wenn Sie ihn hingegen beenden und dabei stillschweigend einige Tests löschen oder deren Assertions umschreiben, war das Experiment erfolgreich.
Die wirtschaftlichen Verhältnisse haben sich umgekehrt
Vor der Einführung von Agenten waren gute Tests teuer. Ihre Erstellung war zeitaufwendig, und niemand wollte dafür freiwillig aufkommen. Die Teams verzichteten daher darauf und lebten mit dem Risiko.
Heutzutage ist das Schreiben von Tests kostengünstig. Testagenten füllen Pull Requests gerne mit Tests. Potencier merkt an, dass die alte Kritik – „Testagenten schreiben leere Assertions und Mocks bis ins kleinste Detail“ – mit den aktuellen Modellen größtenteils überholt ist. Testagenten können auch bestehende Testsuiten ergänzen: Sie finden nicht zugesichertes Verhalten, fixieren es und schlagen aus dem richtigen Grund fehl.
Sind die Tests also gelöst?
NEIN.
Was knapp wurde, war Urteilsvermögen: welche Verhaltensweisen eine Versicherung verdienen, welche Aussagen eine Refaktorisierung überstehen, welche Doppelungen einen Design-Geruch verbergen, welche grünen Balken immer noch bestehen würden, wenn die Produktbedeutung verloren ginge.
Diese Unterscheidung ist der Kern des Artikels.
Before AI → Cost of writing tests ≫ Cost of choosing oracles
With coding agents → Cost of writing tests ≪ Cost of choosing oracles
Volumen ohne Prognosen ist eine trügerische Sicherheit. Geschwindigkeit ohne Urteilsvermögen führt zu einer trügerischen Sicherheit, die sowohl in der Produktion als auch im Umgang mit Agenten versagt.
Wie „Testen ohne Leben“ aussieht
Ich nenne es Testen ohne Lebenszyklus: eine grüne Testsuite, die Implementierung, Aufrufreihenfolge und Laufzeitumgebung sichert, die geschäftliche Bedeutung aber unbestätigt lässt. Die Tests laufen in der CI-Pipeline. Die Versicherung ist tot.
Das zugehörige Repository enthält eine bewusst lehrreiche Testsuite namens tests/Bad/. Führen Sie sie aus:
cd nolife-tests
composer install
composer test:bad # green, low value
composer test:good # behavioral oracles
Drei Ablenkungsmanöver. Gleicher Arbeitsablauf. Drei verschiedene Arten zu lügen.
1. Implementierungskopplung – Mocks bis zum Ende
ImplementationCoupledTest erstellt einen Ablauf aus vier simulierten JobInterface-Instanzen und prüft, ob diese in der richtigen Reihenfolge mit vordefinierten Rückgabewerten aufgerufen wurden. Es fragt nie nach der Bedeutung des Auszugs.
$fetch->expects($this->once())->method('__invoke')->with($request)->willReturn($raw);
$parse->expects($this->once())->method('__invoke')->with($raw)->willReturn($parsed);
$excerpt->expects($this->once())->method('__invoke')->with($parsed)->willReturn($draft);
$validate->expects($this->once())->method('__invoke')->with($draft)->willReturn($result);
$flow = (new Flow($fetch))->fn($parse)->fn($excerpt)->fn($validate);
($flow)(new Ip($request));
$flow->await();
$this->assertTrue(true); // Green. We never asserted meaning.
Tausche den echten ParseJob gegen eine fehlerhafte Implementierung aus. Liefere fehlerhaftes HTML-Parsing aus. Diese Testsuite bleibt fehlerfrei. Die Mock-Funktionen rufen den echten Job nie auf.
Die entscheidende Frage lautet: Würde der Status „grün“ bleiben, wenn ein fehlerhaftes, echtes ParseJob ausgeliefert würde? Ja. Der Versicherungsanspruch bezieht sich also auf die Ausführungsreihenfolge unter doppelter Qualität – nicht auf die Genauigkeit der Auszüge.
2. Laufzeitkopplung – Testen der Möbel
RuntimeCoupledTest umschließt FiberDriver und zählt die await()-Aufrufe. Es beweist, dass der Event-Loop-Wrapper ausgeführt wurde. Es beweist jedoch nicht, dass der Codeausschnitt korrekt ist.
public function await(array &$stream): void
{
++$this->counter->awaitCalls;
$this->inner->await($stream);
}
// ...
$this->assertSame(1, $counter->awaitCalls);
ReactPHP benötigt keine Anwendungstests. Amp benötigt sie ebenfalls nicht. Flows CI-Paketierung kann Treiberfehler verursachen. Ihre Produkt-Suite sollte nicht protokollieren, wie oft der Treiber seinen Stream geleert hat.
Würde Fiber → Amp diesen Test selbst dann nicht bestehen, wenn der Auszug korrekt ist? Ja. Das ist die Definition von Möbeltests.
3. Berichterstattungstheater – Form ohne Bedeutung
CoverageTheaterTest prüft, ob eine Instanz von ExcerptResult vorliegt, der Titel nicht null ist und der String-Auszug korrekt ist. Ein Agent bevorzugt dieses Muster: hohe Testabdeckung, kein Oracle. Ändert man den Auszugsalgorithmus so, dass er "lorem ipsum" zurückgibt, bleibt die CI-Testumgebung aktiv.
$this->assertInstanceOf(ExcerptResult::class, $result);
$this->assertNotNull($result->title);
$this->assertIsString($result->excerpt);
// Never asked: is the excerpt faithful to the document?
Bergmanns Argumentation wiederholt sich: Das Orakel wählte die „Form“. Form ist nicht Produktwahrheit.
Ablauf in einem Diagramm: Jobs vs. Treiber
Darkwood Flow ist keine DAG-Bibliothek für Knoten/Kanten. Arbeitsabläufe werden als Informationspakete (Ip) durch eine zusammengesetzte Sequenz von Jobs transportiert. Parallelverarbeitung erfolgt durch Paketplanung (IpStrategy) und eine austauschbare Coroutine-Laufzeitumgebung (Driver).
flowchart TD
Req[DocumentRequest] --> Fetch[FetchJob]
Fetch --> Parse[ParseJob]
Parse --> Excerpt[ExcerptJob]
Excerpt --> Validate[ValidateJob]
Validate --> Result[ExcerptResult]
subgraph behavior [Business behavior - test this]
Fetch
Parse
Excerpt
Validate
end
subgraph furniture [Runtime furniture - do not pin in app tests]
D1[FiberDriver]
D2[AmpDriver]
D3[ReactDriver]
D4[… future runtime]
end
behavior -.->|scheduled by| furniture
| Konzept | Bedeutung | Gehört in App-Tests? |
|---|---|---|
| Aufgabe | Transformation T1 → T2 (Parsen, Auszug, Validierung) |
Ja - Unit- und Workflow-Orakel |
| IP | Unveränderlicher Träger aktueller Daten | Indirekt (Eingabe-/Ausgabepakete) |
| Ablauf | Geordnete Phasen, zusammengesetzt mit fn |
Als Workflow-Orakel, nicht über Aufrufreihenfolge-Mocks |
| Treiber | Wie Async implementiert wird | Kein Rauch in Flows eigener CI |
| Port | E/A-Grenze (DocumentSource) |
Hier Platzhalter einfügen |
Die Architektur beinhaltet bereits die Lektion fürs Testen. Geschäftsprozesse sind in Jobs implementiert. Die Laufzeitumgebung ist austauschbar. Wenn Ihre Tests beim Austausch des Treibers fehlschlagen, haben sie nie das Produkt getestet.
Im zugehörigen Projekt wird der Workflow einmalig zusammengestellt:
return (new FlowFactory($driver))->create(static function () use ($source, $maxExcerptLength, $minExcerptLength) {
yield new FetchJob($source);
yield new ParseJob();
yield new ExcerptJob($maxExcerptLength);
yield new ValidateJob($minExcerptLength);
});
Gleiche Kette. Übergeben Sie entweder FiberDriver oder AmpDriver. Die Jobs wissen nicht, welchen.
php bin/excerpt.php fiber
php bin/excerpt.php amp
Gleicher Titel. Gleicher Auszug. Andere Möbel.
Wo das Geschäft ansässig ist: Testen Sie die Jobs
ParseJob, ExcerptJob und ValidateJob sind gewöhnliche Funktionen. Kein Flow erforderlich. Kein Treiber erforderlich. Genau das ist der Punkt.
JobBehaviorTest behauptet die Bedeutung:
$parsed = (new ParseJob())(new RawDocument('doc://1', $html));
$this->assertSame('Hello Flow', $parsed->title);
$this->assertSame('Jobs transform packets. Drivers schedule them.', $parsed->body);
$draft = (new ExcerptJob(40))(new ParsedDocument('doc://1', 'T', $longBody));
$this->assertSame('Jobs transform information packets into…', $draft->excerpt);
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('too short');
(new ValidateJob(20))(new ExcerptDraft('doc://1', 'T', 'too short'));
Diese Tests wären auch dann noch gültig, wenn Flow morgen nicht mehr verfügbar wäre. Sie wären auch dann noch gültig, wenn Sie die Jobs in einem Symfony Messenger Worker, einem CLI-Skript ausführen würden. Sie schützen beobachtbare Transformationen, nicht die Orchestrierungsinfrastruktur.
Das ist die erste Hälfte des mentalen Modells:
Wenn Sie einen Job per Unit-Test prüfen können, ohne einen Flow zu erstellen, haben Sie das Geschäftsverhalten gefunden.
Workflows fördern diese Trennung. Wenn Phasen als Transformationen mit typisierten Paketen benannt werden, verliert die Frage „Was sollen wir bestätigen?“ ihre Abstraktion. Sie bestätigen, was das Paket nach der Phase bedeutet.
Das Workflow-Orakel
Unit-Jobs sind notwendig, aber nicht ausreichend. Auch die Komposition kann fehlerhaft sein: falsche Reihenfolge, fehlende Validierung, ein Port, der nie aufgerufen wird.
WorkflowBehaviorTest durchläuft die gesamte Kette durch Flow und überprüft die Genauigkeit anhand von fixtures/article.html:
$result = FlowCollector::run($flow, new Ip(new DocumentRequest('fixture://article')));
$this->assertSame('Darkwood Flow Notes', $result->title);
$this->assertStringContainsString('Jobs transform information packets', $result->excerpt);
$this->assertStringContainsString('Drivers schedule', $result->excerpt);
$this->assertLessThanOrEqual(121, mb_strlen($result->excerpt));
Ein zweiter Fall verarbeitet ein dünnes Dokument und erwartet einen Validierungsfehler – keine Überprüfung der Form im Normalfall.
Beachten Sie, was nicht behauptet wird: Aufrufreihenfolge, Treibertyp, await()-Zähler, Mock-Erwartungen an Jobs.
Ehrlichkeit über IP
Ip::$data ist schreibgeschützt. Flow verändert Ihr ursprüngliches Paket nicht; jede Stufe umschließt ein neues Ip. Die Annahme, das Eingabepaket habe sich geändert, ist ein häufiges, aber falsches Muster.
FlowCollector fügt einen Terminal-Job hinzu, der die endgültige Nutzlast speichert – dieselbe Integrität, die auch Flows eigene Tests verwenden:
$flow->fn(static function (mixed $data) use ($box): mixed {
$box->value = $data;
return $data;
});
($flow)($ip);
$flow->await();
return $box->value;
Optionale Flow-Wunschliste (nicht erforderlich für das Argument): ein synchroner run(Ip): mixed-Helfer für Tests. Bis dahin bitte explizit sammeln. Keine Mutationen erfinden, die das Modell nicht enthält.
Die Laufzeitumgebung austauschen. Die Tests beibehalten.
Hier ist die Kernaussage des Repositorys – und dieses Artikels.
MultiDriverBehaviorTest führt identische Assertions unter Fiber und Amp aus:
#[DataProvider('provideDrivers')]
public function testSameExcerptUnderDifferentDrivers(DriverInterface $driver): void
{
$flow = (new ExcerptWorkflowFactory())->create($driver, $source, maxExcerptLength: 120);
$result = FlowCollector::run($flow, new Ip(new DocumentRequest('fixture://article')));
$this->assertSame('Darkwood Flow Notes', $result->title);
$this->assertStringContainsString('Jobs transform information packets', $result->excerpt);
$this->assertStringEndsWith('…', $result->excerpt);
}
public static function provideDrivers(): iterable
{
yield 'fiber' => [new FiberDriver()];
yield 'amp' => [new AmpDriver()];
}
flowchart LR
Oracle[Same behavioral oracle] --> Fiber[FiberDriver]
Oracle --> Amp[AmpDriver]
Fiber --> Green1[Green]
Amp --> Green2[Green]
Bad[await / driver spies] --> Fiber
Bad --> Red[Red after swap]
Wenn die Änderung der Laufzeitumgebung das Umschreiben der Tests erfordert, wurden die Tests an die Implementierung gekoppelt.
Dieser Satz gilt nicht nur für Flow:
| Wenn Sie von… wechseln | …und Ihre Suite nicht mehr funktioniert, während die Produktbedeutung unverändert bleibt… |
|---|---|
| Sequentielles PHP | Sie haben den Aufrufstapel getestet, nicht das Ergebnis |
| ReactPHP | Du hast Promises / Schleifenelemente getestet |
| Amp | Sie haben Amp-Typen getestet, keine Domänenpakete |
| Jede zukünftige Laufzeit | Gleiche Diagnose |
Deshalb ist ein Artikel zum Thema „ReactPHP vs. Amp“ der falsche Rahmen für Tests. Performance, Entwicklererfahrung und das Ökosystem sind für die Wahl der Laufzeitumgebung entscheidend. Sie sollten in Anwendungs-Orakeln so gut wie nie vorkommen.
Flows Design macht das Experiment kostengünstig: Der Treiber wird an der Werksgrenze eingebunden. Die Jobs bleiben portabel. Die Suite bleibt stabil.
Mocks unter Agenten
Mocks sind nicht böse. Ungeprüfte Mocks unter dem Einfluss der Agentengeschwindigkeit hingegen schon.
Bergmanns Unterscheidung zwischen Stubs und Mocks gewinnt an Bedeutung, wenn ein Agent bis zu fünfzig Erwartungsobjekte pro Minute generieren kann. Ein Stub an einem Port ersetzt eine I/O-Grenze durch ein kontrolliertes Fake-Objekt und erhält die echten Jobs. Eine Mock-Kette ersetzt Kollaboratoren durch Erwartungsobjekte und verschleiert oft das Verhalten, das eigentlich geschützt werden sollte.
In nolife-tests ist der Port DocumentSource. Die korrekte Testsuite verwendet einen Stub dafür:
$source = new InMemoryDocumentSource(['fixture://article' => $html]);
FetchJob läuft weiterhin. ParseJob läuft weiterhin. Das Netzwerk jedoch nicht.
Im Gegensatz dazu wird beim Mocken von FetchJob selbst die Ausführung der URI → RawDocument-Zuordnung gestoppt. Der Agent wird außerdem aufgefordert, den nächsten Job und so weiter zu mocken, bis nichts mehr Reales übrig ist – Potenciers „durchgehendes Mocken“, das nun in Maschinengeschwindigkeit ausgeführt wird.
Faustregel für die zugehörigen Fertigkeiten:
| Tun | Nicht tun |
|---|---|
Stub DocumentSource / verwende InMemoryDocumentSource |
Mock DriverInterface in App-Tests |
Unit-Test für App\Job\*-Transformationen |
Überprüfung der Reihenfolge simulierter Aufrufe entlang der Jobkette |
Führe composer test:good als erforderliche CI aus |
Behandle composer test:bad als Absicherung |
Wenn sich Mock-ups häufen, fragen Sie sich, ob sie ein Designproblem verschleiern. Wenn Sie keinen Port benennen können, existiert möglicherweise keiner – und der Test erfindet eine Isolation, die die Architektur nie verdient hat.
Die Entscheidung einem Drucktest unterziehen, nicht die Suite generieren
Guillaume Moigneus Fähigkeit pressure-test-decisions ist ein sokratisches Protokoll für schwierige Entscheidungen: die Entscheidung formulieren, Annahmen überprüfen, reale Optionen generieren, den Abschluss in einem Protokoll festhalten / experimentieren / Informationen-Aktions-Protokoll erzwingen.
Die Testmitarbeiter sollten nicht nur Tests schreiben. Sie sollten die Testentscheidung kritisch hinterfragen, bevor sie weitere grüne Balken ausgeben.
Die zugehörigen Repository-Anbieter bieten diese Fähigkeit und fügen eine Spezialisierung hinzu: „Drucktests für Testentscheidungen“. Dieselbe Disziplin; der Bereich umfasst das Beibehalten, Überschreiben, Löschen und Experimentieren mit Tests, Mocks, Oracles und Laufzeitkopplung.
npx skills add . --list
# pressure-test-decisions
# pressure-test-testing-decisions
Beispielhafte Eingabeaufforderungen für dieses Repository:
Use $pressure-test-testing-decisions on tests/Bad/ImplementationCoupledTest.php —
should we keep, rewrite, or delete it?
Use $pressure-test-testing-decisions: stub DocumentSource or mock FetchJob?
Die Fachbegriffe sind bewusst auf den Artikel abgestimmt:
| Begriff | Bedeutung |
|---|---|
| Orakel | Aussage, die fehlschlägt, wenn die geschäftliche Bedeutung falsch ist |
| Möbel | Laufzeit-/Treiber-/Aufrufauftragsdetail, das nicht das Produkt ist |
| Coverage-Theater | Shape-/null-/instanceof-Prüfungen, die bei falscher Bedeutung grün bleiben |
| Treibertausch | Gleicher Workflow unter Glasfaser vs. Ampere; Geschäftstests bestehen weiterhin |
Eine zusammengefasste Sitzung anhand der Beispiele im Repository endet für den implementierungsgekoppelten Test folgendermaßen:
| Feld | Eintrag |
|---|---|
| Entscheidung | Nur als pädagogisch schlecht beibehalten / niemals Torfusionen darauf |
| Produktfehler, der grün bleiben würde | Defekter ParseJob / falsche Bedeutung des Auszugs |
| Nächster Schritt | Bestätigen Sie, dass composer test:good der erforderliche CI-Job ist |
Das ist der Wandel: von „Tests generieren“ zu „den Versicherungsanspruch verteidigen“.
Potenciers Rat für neue Projekte gilt weiterhin: Lassen Sie den Agenten den Test zuerst schreiben und beobachten Sie, wie er aus dem richtigen Grund fehlschlägt. Die Drucktestebene fügt die vorherige Frage hinzu: Ist dies der richtige Grund, sich darum zu kümmern?
Nützliche Grillfragen, eine nach der anderen:
Sollte das überhaupt getestet werden?
- Welches Verhalten schützen wir? Würde dieser Test aus dem richtigen Grund fehlschlagen?
- Bleibt diese Aussage auch nach einer Refaktorisierung gültig?
- Schützen wir die Architektur oder die Implementierung?
- Verbergen diese Mockups ein Designproblem?
- Wenn wir Fiber durch Amp ersetzen würden, würde das fehlschlagen – und sollte es das?
- In sechs Monaten: Anzug grün, Produkt fehlerhaft – welcher Test hat gelogen?
Was Sie einen Makler fragen sollten
Wenn Sie nach dem Lesen dieses Textes nur eine Gewohnheit ändern, dann ändern Sie die Aufgabenstellung, die Sie dem Agenten geben.
Schwache Untermauerung
Fügen Sie Unit-Tests für den Auszug-Workflow hinzu. Streben Sie eine hohe Testabdeckung an.
Starkes Briefing
Prüfen Sie, ob ein neuer Test erforderlich ist. Falls ja, erstellen Sie ein Verhaltensorakel für die Bedeutung von Jobs oder Workflows. Verwenden Sie einen Stub für DocumentSource. Mocken Sie keine Jobs. Führen Sie keine Assertions auf dem Treiber durch. Überprüfen Sie die Genauigkeit von Auszügen vor jeder Implementierungsänderung.
Ordnen Sie das Briefing den Suiten des Repos zu:
flowchart TD
Ask[Agent proposes a test] --> PT{Pressure-test decision}
PT -->|furniture / theatre| Del[Delete or park under Bad]
PT -->|Job meaning| Job[JobBehaviorTest style]
PT -->|composition meaning| Wf[WorkflowBehaviorTest style]
PT -->|runtime claim| Swap[Prove it with MultiDriverBehaviorTest - same assertions]
TDD funktioniert weiterhin. Zuerst das Jobverhalten überprüfen. Niemals Treiber-Spione überprüfen. Oracles stärken, nicht die Abdeckungsprozentsätze.
Bergmanns angrenzende Warnungen passen zur gleichen Haltung: Langsame Testsuiten werden zu einer Abdeckungsgrenze für LLM-Reviewer (verworfene Hypothesen hinterlassen kein Ticket); „schneller als verstehen“ bedeutet, dass Agenten in Minuten tippen, wofür Menschen Stunden brauchen, um es zu überprüfen; unberührte Tests sind die halbe Wahrheit – wenn eine Korrektur die Suite neu schreibt, diagnostizieren Sie die Kopplung, bevor Sie feiern.
Ehrliche Grenzen
Dieser Begleiter beweist nicht alles. Die Benennung der Grenzen sorgt für eine ehrliche Argumentation.
- **Noch kein Synchronisierungstreiber in Flow für den Einzeiler
run(Ip).FlowCollectorist die explizite Umgehungslösung. - Stubs an Ports bleiben nützlich. Es wird nicht behauptet, alle Duplikate aufzugeben. Es wird behauptet, dass Mock-Ketten, die Jobs löschen, aufgegeben werden.
Treiberbibliotheken benötigen weiterhin Tests – im Flow-Paket, nicht in jeder Anwendungssuite. Jeder Treiber sollte nur dann in die Produkt-CI aufgenommen werden, wenn das Produkt der Treiber ist.
Die Leistung von Verstärker und Glasfaser wurde nicht gemessen. Es geht um das Überleben der Orakel, nicht um einen Vergleichsmaßstab.
Parallelitätsstrategien (
MaxIpStrategyusw.) gehören in die Flow-eigenen Verträge. Anwendungstests sollten Parallelität nur dann berücksichtigen, wenn Parallelität das Produktverhalten ist. - KI kann gute Tests schreiben. Das Risiko liegt im Umfang ohne Orakel – einer falschen Versicherung aufgrund der hohen Geschwindigkeit der Agenten – nicht in der Unmöglichkeit echter Tests.
Was der Prototyp tatsächlich zeigt: einen lesbaren Workflow, zwei Laufzeitumgebungen, drei wertlose grüne Werte, drei Verhaltensorakel und Fähigkeiten, die die Entscheidung zwischen Beibehalten/Umschreiben/Löschen erschweren, bevor weitere PHPUnit-Dateien erscheinen.
Klonen. Zerstören. Entscheiden.
Das Repository ist kein Anhang. Es ist das Labor für diesen Artikel.
composer install
composer test:good # behavioral insurance
composer test:bad # educational false insurance
php bin/excerpt.php fiber
php bin/excerpt.php amp
Öffnen Sie anschließend tests/Bad/ImplementationCoupledTest.php, führen Sie absichtlich einen Fehler im eigentlichen ParseJob aus und beobachten Sie, welche Testsuiten dies erkennen. Dieses Experiment, bei dem der Code absichtlich zum Absturz gebracht wird, ist aussagekräftiger als ein weiterer Coverage-Bericht.
Erkunden Sie skills/ und führen Sie einen Drucktest mit einem Ihrer eigenen grünen Tests durch. Speichern Sie das Ergebnis. Löschen Sie Einträge, die lediglich Möbel polieren.
Abschluss
Die meisten Unit-Tests in von Agenten beeinflussten Codebasen testen das Falsche – nicht weil PHPUnit schwach ist, sondern weil das Orakel Implementierung und Laufzeit über Bedeutung gestellt hat.
Flow zieht bereits eine klare Trennlinie: Jobs transformieren Pakete; Treiber planen sie. Workflows machen das Verhalten als Kette benannter Transformationen sichtbar. Diese Transparenz ist ein Vorteil beim Testen, wenn man sie nutzt – und eine Falle, wenn man die Kette bis zur Unkenntlichkeit simuliert.
KI hat die Wirtschaft verändert. Das Schreiben von Tests ist nicht mehr der Engpass. Die Auswahl vertrauenswürdiger Experten ist es.
Eine Versicherung, die einen Fahrerwechsel übersteht, ist eine Versicherung für Ihr Produkt. Alles andere ist nur Möbelpolitur.
Ihre KI schreibt Tests. Stellen Sie sicher, dass es sich lohnt, diese einzufordern.
Quellen
- Sebastian Bergmann : Die Wahrheit erkennen: Testorakel
- Sebastian Bergmann : Die Scheinintervention
- Sebastian Bergmann : Schneller als Verstehen
- Sebastian Bergmann : Geschwindigkeit als Sicherheitsmerkmal
- Sebastian Bergmann : Beyond Best Practices
- Guillaume Moigneu : pressure-test-decisions (Agent Skills)
- Darkwood : Flow-Dokumentation
- GitHub-Repository : NoLife Tests