Thema: testing
-
Eine Änderung benchmarken: Aufwärmphase, Wiederholungen, Streuung und was zu berichten ist
Ein Zeitvergleich ist nur dann ein Ergebnis, wenn er dem Rauschen standhält: die Arbeitslast fixieren, Aufwärmläufe verwerfen, viele Wiederholungen jeder Variante verschachteln, die Statistik vor der Datenbetrachtung festlegen und die Streuung sowie die Umgebung zu jeder Zahl mit angeben. Ein Unterschied, der kleiner ist als die Streuung zwischen Läufen, ist kein Befund.
-
Refactoring in kleinen, verifizierten Schritten
Refactoring ändert die Struktur, ohne das Verhalten zu ändern; dies in winzigen Schritten mit zwischen den Schritten grünen Tests zu tun und Refactoring-Commits von Verhaltensänderungen zu trennen, hält es sicher und überprüfbar.
-
Einen brauchbaren Fehlerbericht schreiben
Ein Fehlerbericht ist brauchbar, wenn eine fremde Person den Fehler ohne Rückfrage nachstellen kann: eine präzise Überschrift, Umgebung mit Versionen, nummerierte Schritte zum Nachstellen, erwartetes und tatsächliches Ergebnis getrennt, die wörtliche Fehlermeldung und ein möglichst kleines Beispiel. Vermutungen zur Ursache stehen in einem eigenen Abschnitt.
-
Seed-Daten und Fixtures für lokale Datenbanken: klein, idempotent und mit dem Schema versioniert
Referenzdaten (überall benötigt), Beispieldaten (Entwicklung und Demos) und Testdaten (von Tests erzeugt) trennen; den Seed als idempotenten Code mit Upserts auf natürlichen Schlüsseln schreiben, den Beispieldatensatz klein und benannt halten, ihn sowohl im Setup-Skript als auch in der CI nach den Migrationen ausführen, und Entwicklermaschinen nie mit rohen Produktionsdaten seeden.
-
Property-based Testing mit generierten Eingaben
Statt handverlesener Beispiele formuliert ein Property-based Test eine Invariante und lässt eine Bibliothek viele Eingaben generieren, wobei Fehlschläge auf minimale Gegenbeispiele verkleinert (shrinking) werden; Hypothesis ist die Referenzimplementierung für Python.
-
Generieren, kritisieren, überarbeiten: wann sich eine Selbstprüfschleife lohnt
Eine Schleife, in der das Modell seine eigene Ausgabe kritisiert und überarbeitet, verbessert Ergebnisse, wenn die Kritik über ein externes Signal verfügt (Tests, ein Validator, eine Quelle) und über eine feste Bewertungsvorgabe; ohne beides zeigen veröffentlichte Ergebnisse, dass sie Antworten verschlechtern kann, und jede Runde kostet mindestens zwei zusätzliche Aufrufe, deren Eingabe mit dem Entwurf mitwächst.
-
Einen Unit-Test in JUnit 5 und xUnit.net schreiben: Annotationen, Lifecycle und parametrisierte Fälle im Vergleich
JUnit Jupiter markiert Tests mit @Test, führt standardmässig @BeforeEach und @AfterEach um jeden Test auf einer frischen Instanz aus und steuert datengetriebene Fälle mit @ParameterizedTest plus einer Source-Annotation; xUnit.net verwendet [Fact], den Konstruktor und IDisposable für das Setup je Test auf einer frischen Instanz, [Theory] mit [InlineData] für Fälle sowie Fixtures für geteilten, teuren Kontext. Tests in beiden mit derselben Form zu schreiben, hält die Konventionen eines mehrsprachigen Teams im Gleichlauf.
-
Eine Continuous-Integration-Pipeline gestalten
Eine CI-Pipeline sollte schnell, selbsttestend und für jede Änderung identisch sein: aus einem sauberen Checkout bauen, Linter und Tests in Stufen ausführen, laut fehlschlagen und die Gesamtzeit so kurz halten, dass Personen darauf warten.
-
Kurzlebige Datenbanken in Containern für Integrationstests
Die echte Datenbank-Engine wird für jeden Testlauf in einem Wegwerf-Container gestartet, die Daten liegen im Arbeitsspeicher, Migrationen werden einmal auf eine Vorlagendatenbank angewendet und pro Testdatei kopiert; so prüfen Tests den echten Planer, die echten Constraints und das Isolationsverhalten statt eines In-Memory-Ersatzes.
-
Property-Tests für Parser einsetzen
Parser-Invarianten über generierte Eingaben ausdrücken und minimierte Fehlschläge als fokussierte Regressionsbeispiele behalten.
-
pass^k über wiederholte Durchläufe sagt Produktionsvorfälle von Agenten besser voraus als pass@k
Hypothese: Bei Agenten, die auf repetitiven Aufgaben eingesetzt werden, korreliert die Rate, mit der alle Durchläufe bestehen (pass^k), stärker mit der Rate fehlgeschlagener oder eskalierter Produktionsläufe als die Rate, mit der irgendein Durchlauf besteht (pass@k), weil die Produktion pro Aufgabe nur einen Versuch gibt.
-
Reproduzierbarkeit eines Machine-Learning-Experiments: Seeds, Umgebung, Daten und die Grenzen des Determinismus
Ein Experiment erneut auszuführen und dieselbe Zahl zu erhalten, verlangt explizit übergebene feste Zufallszustände, festgepinnte Bibliotheksversionen, einen identifizierten Datensatz samt Split sowie das Wissen, dass GPU-Kernel und Bibliotheksversionen Ergebnisse dennoch verändern können; das Protokoll macht Durchläufe reproduzierbar, wo das möglich ist, und macht explizit, wo nicht.
-
Einen Agenten-Workflow als Red Team angreifen, bevor er echte Berechtigungen erhält
Den Agenten so angreifen, wie es Inhalte und Nutzer tun werden: indirekte Prompt-Injection über jede Eingabe, die er liest, Manipulation von Tool-Argumenten, Exfiltration über Tool-Aufrufe und Budgeterschöpfung; skriptgesteuerte Sonden plus manuelle Versuche fahren, festhalten, was der Agent getan hat, und die Grenze reparieren, nicht nur den Prompt.
-
Testdaten ohne personenbezogene Produktivdaten
Entwicklungs-, CI- und Staging-Umgebungen realistische Daten geben, indem man sie generiert: Spalten klassifizieren, geseedete Generatoren schreiben, die die Validatoren der Anwendung bestehen, Volumen mit generate_series erzeugen, aus der Produktion nur Verteilungen übernehmen, generierte Datensätze erkennbar markieren und den Abkürzungsweg «einfach Prod dumpen» entfernen.
-
Wie viel Testabdeckung reicht für einen kleinen Dienst?
Offene Frage: Welches Abdeckungsniveau und welche Testmischung haben sich für einen Dienst mit ein paar tausend Zeilen, einer Datenbank und einer HTTP-API als geeignet erwiesen, um akzeptable Fehlerraten zu halten, ohne Änderungen zu verlangsamen?
-
Strukturierte Extraktion aus Dokumenten mit JSON Schema, Validierung und begrenzten Wiederholungsversuchen
Den Zieldatensatz als JSON Schema mit additionalProperties false definieren, das Modell genau um diese Form bitten, jede Antwort mit einem echten Validator prüfen, mit der Validierungsfehlermeldung im Prompt eine begrenzte Anzahl Male erneut versuchen und weiterhin Fehlschlagendes an eine Person weiterleiten statt zu raten.
-
Von einem KI-Agenten geschriebenen Code überprüfen
Ein vorgeschlagenes Review-Protokoll für generierte Änderungen: den Diff mit der Anfrage abgleichen, die Existenz jeder API und Abhängigkeit bestätigen, Testbehauptungen durch Ausführen und gezieltes Scheiternlassen der Tests verifizieren, Tests vor der Implementierung lesen, nach verschluckten Fehlern suchen und festhalten, was geprüft wurde.
-
Der testgetriebene Entwicklungszyklus
Einen fehlschlagenden Test schreiben, ihn mit der einfachsten Änderung bestehen lassen und danach bei grünen Tests refaktorieren; der Zyklus hält Designentscheidungen klein und gibt jeder Zeile einen Grund zu existieren.
-
Stabile Selektoren und Auto-Waiting in Browser-End-to-End-Tests
Zwei Ursachen dominieren flackernde Browser-Tests: Selektoren, die brechen oder das falsche Element treffen, und Sleeps, die von einem angenommenen Timing ausgehen. Elemente über Rolle, Label oder Test-ID auffinden, jeden Locator auf genau ein Element treffen lassen und über wiederholende Assertions und Actionability-Prüfungen synchronisieren statt über Zeit.
-
Mutation Testing durchführen, ohne in Survivors zu ertrinken
Ein Mutation-Testing-Werkzeug auf ein Modul anwenden, jeden überlebenden Mutanten als fehlende Assertion, fehlenden Fall oder äquivalenten Mutanten einordnen, die ersten beiden beheben, den dritten ausschliessen und die Laufzeit mit inkrementellen oder auf den Diff begrenzten Läufen beschränken; den Score als Ratsche je Modul verwenden statt als globales Ziel.
Maschinenlesbar: JSON