- In dem von Meta im Februar veröffentlichten Paper „Automated Unit Test Improvement using Large Language Models at Meta“ wurde ein Tool namens TestGen-LLM vorgestellt.
- Ziel dieses Tools ist es, die Testabdeckung vollautomatisch zu erhöhen und dabei sicherzustellen, dass gegenüber der bestehenden Codebasis eine Verbesserung erzielt wird.
- Da Meta den Code von TestGen-LLM nicht veröffentlicht hat, wurde entschieden, es direkt als Teil des Open-Source-Projekts Cover-Agent zu implementieren.
- Hier werden der Implementierungsprozess, gewonnene Erkenntnisse und die Probleme geteilt, auf die man beim Einsatz von TestGen-LLM in realen Codebasen gestoßen ist.
Maßstäbe für automatische Testgenerierung
- Automatische Testgenerierung mit generativer KI ist nichts Neues.
- Die meisten LLMs sind gut in der Codegenerierung und können auch Tests erzeugen.
- Das häufigste Problem, auf das Entwickler bei der Testgenerierung mit LLMs stoßen, ist, dass die meisten erzeugten Tests entweder nicht funktionieren oder keinen Mehrwert liefern.
- Um das zu überwinden, schlagen die Autoren von TestGen-LLM für Regressionstests auf Unit-Ebene folgende Maßstäbe vor:
- Lässt sich der Test korrekt kompilieren und ausführen?
- Erhöht der Test die Codeabdeckung?
- Wenn diese beiden grundlegenden Fragen nicht beantwortet werden können, gibt es keinen Grund, von einem LLM erzeugte Tests zu akzeptieren oder weiter zu analysieren.
- Werden diese Fragen bestanden, folgt anschließend eine manuelle Prüfung.
- Wie gut ist der Test geschrieben?
- Wie viel tatsächlichen Mehrwert bringt er?
- Erfüllt er zusätzliche Anforderungen?
Ansatz von TestGen-LLM und berichtete Ergebnisse
- TestGen-LLM (und Cover-Agent) läuft vollständig Headless.
- Zunächst werden viele Tests erzeugt, dann werden diejenigen herausgefiltert, die sich nicht bauen oder ausführen lassen; nicht bestehende Tests werden verworfen, ebenso solche, die die Codeabdeckung nicht erhöhen.
- In stark kontrollierten Fällen liegt das Verhältnis zwischen generierten Tests und solchen, die alle Schritte bestehen, bei 1:4; in realen Szenarien berichten die Meta-Autoren von einem Verhältnis von 1:20.
- Nach dem automatisierten Prozess lässt Meta menschliche Reviewer die Tests annehmen oder ablehnen.
- Die Autoren des Papers geben an, dass im besten Fall eine Annahmerate von 73 % erreicht wurde, bei einem durchschnittlichen Annahmeverhältnis von 1:2.
- Wie im Paper beschrieben, erzeugt das TestGen-LLM-Tool bei jedem Lauf einen einzelnen Test, der zu einer bestehenden Test-Suite hinzugefügt wird, die zuvor von erfahrenen Entwicklern geschrieben wurde.
- Außerdem wird nicht zwangsläufig für jede gegebene Test-Suite ein Test erzeugt.
Implementierung von Cover-Agent
- Cover-Agent v0.1 wurde wie folgt implementiert:
- Eingaben vom Nutzer entgegennehmen (zu testende Quelldatei, bestehende Test-Suite zur Verbesserung, Coverage-Report, Build- und Ausführungsbefehle für die Test-Suite, Zielwert für die Codeabdeckung und maximale Anzahl an Iterationen, zusätzlicher Kontext und Prompt-Optionen)
- Weitere Tests im gleichen Stil erzeugen
- Diese Tests mithilfe der Laufzeitumgebung validieren (ob sie sich bauen lassen und erfolgreich durchlaufen)
- Metriken wie den Anstieg der Codeabdeckung prüfen, um festzustellen, ob die Tests Mehrwert liefern
- Bestehende Test-Suite und Coverage-Report aktualisieren
- Wiederholen, bis der Code die Kriterien erreicht (Schwellenwert für Codeabdeckung erreicht oder maximale Anzahl an Iterationen erreicht)
Probleme bei der Implementierung und Überprüfung von TestGen-LLM
- In den im Paper gezeigten Beispielen wird Kotlin zum Schreiben von Tests verwendet, wo Whitespace keine Rolle spielt.
- In Sprachen wie Python hingegen sind Tabs und Leerzeichen nicht nur wichtig, sondern für den Parser essenziell.
- Weniger ausgefeilte Modelle wie GPT 3.5 liefern selbst mit expliziten Prompts nicht konsistent korrekt eingerückten Code zurück.
- Ein Beispiel, bei dem das Probleme verursacht, sind in Python geschriebene Testklassen, in denen jede Testfunktion eingerückt werden muss.
- Das musste über den gesamten Entwicklungslebenszyklus hinweg berücksichtigt werden, was zusätzliche Komplexität rund um die Preprocessing-Bibliothek erzeugte.
- Um Cover-Agent in solchen Szenarien robust zu machen, gibt es noch viel Verbesserungspotenzial.
- Als Teil des Cover-Agent-Workflows wurde eine Funktion hinzugefügt, mit der Nutzer dem LLM zusätzliche Eingaben oder Anweisungen geben können (
--additional-instructions-Option).
- Dadurch können Entwickler Cover-Agent anpassen, indem sie zusätzliche projektspezifische Informationen bereitstellen.
- So kann man Cover-Agent etwa mit solchen Anweisungen dazu bringen, ein aussagekräftiges Test-Set mit relevanten Edge Cases zu erstellen.
- Im Einklang mit dem allgemeinen Trend, dass Retrieval-Augmented Generation (RAG) in KI-basierten Anwendungen immer verbreiteter wird, wurde bestätigt, dass mehr Kontext bei der Unit-Test-Generierung zu qualitativ besseren Tests und höheren Erfolgsraten führt.
- Um den Testgenerierungsprozess zu verbessern, gibt es für Nutzer, die zusätzliche Bibliotheken oder textbasierte Designdokumente manuell als Kontext für das LLM hinzufügen möchten, die Option
--included-files.
- Komplexer Code, der mehrere Iterationen erfordert, stellt für LLMs eine weitere Herausforderung dar.
- Während fehlgeschlagene Tests (oder solche ohne Mehrwert) erzeugt wurden, zeigte sich in späteren Iterationen ein Muster, bei dem dieselben nicht akzeptierten Tests wiederholt vorgeschlagen wurden.
- Um das zu lösen, wurde dem Prompt ein Abschnitt „fehlgeschlagene Tests“ hinzugefügt, damit dieses Feedback an das LLM weitergegeben wird und es eindeutige Tests erzeugt sowie Tests, die als unbrauchbar eingestuft wurden (also kaputt sind oder die Coverage nicht ausreichend erhöhen), niemals wiederholt.
- Ein weiteres Problem, das sich im gesamten Prozess zeigte, ist, dass beim Erweitern bestehender Test-Suites keine zusätzlichen Library-Imports hinzugefügt werden können.
- Entwickler können im Testgenerierungsprozess mitunter kurzsichtig sein und sich nur auf einen einzigen Ansatz für ein Testing-Framework konzentrieren.
- Neben vielen verschiedenen Mocking-Frameworks können auch andere Bibliotheken dabei helfen, Testabdeckung zu erreichen.
- Da das TestGen-LLM-Paper (und Cover-Agent) darauf abzielt, bestehende Test-Suites zu erweitern, liegt eine vollständige Umstrukturierung ganzer Testklassen außerhalb des Umfangs.
- Das ist eine Grenze der Testerweiterung im Unterschied zur Testgenerierung und soll in künftigen Iterationen angegangen werden.
- Wichtig ist die Unterscheidung, dass im Ansatz von TestGen-LLM für jeden einzelnen Test eine manuelle Entwicklerprüfung erforderlich ist, bevor der nächste Test vorgeschlagen wird.
- Bei Cover-Agent hingegen werden so viele Tests wie möglich erzeugt, validiert und vorgeschlagen, ohne manuelle Eingriffe während des Prozesses, bis die Coverage-Anforderungen erfüllt sind (oder bei der maximalen Iterationszahl gestoppt wird).
- So entsteht ein ungestörter Ansatz für automatische Testgenerierung, der im Hintergrund mit KI läuft, sodass Entwickler nach Abschluss des Prozesses die gesamte Test-Suite auf einmal prüfen können.
Fazit und weitere Pläne
- Viele Menschen (mich selbst eingeschlossen) haben große Erwartungen an das TestGen-LLM-Paper und das Tool, aber in diesem Beitrag ging es um dessen Grenzen.
- Ich glaube, wir befinden uns noch immer im Zeitalter von KI-Assistenten und nicht von KI-Teamkollegen, die vollständig automatisierte Workflows ausführen.
- Gleichzeitig können gut gestaltete Abläufe Entwicklern helfen, automatisch Testkandidaten zu erzeugen und die Codeabdeckung in deutlich kürzerer Zeit zu erhöhen; genau das soll in Cover-Agent weiterentwickelt und geteilt werden.
- Es ist geplant, weiterhin moderne Verfahren aus dem Bereich der Testgenerierung zu entwickeln und in das Open-Source-Repository von Cover-Agent zu integrieren.
- Alle, die sich für generative KI im Testing interessieren, sind eingeladen, mitzuarbeiten und die Fähigkeiten von Cover-Agent zu erweitern; zugleich soll dieses Open-Source-Tool Forschende dazu inspirieren, neue Techniken zur Testgenerierung zu erforschen.
- Im Open-Source-Repository von Cover-Agent auf GitHub wurde eine Entwicklungs-Roadmap ergänzt, und es wäre wünschenswert, Beiträge zum Repository auf Basis dieser Roadmap oder eigener Ideen zu sehen.
- Die Vision von Cover-Agent ist, künftig automatisch bei allen pre/post-Pull-Requests zu laufen und automatisch Verbesserungen für Regressionstests vorzuschlagen, die verifiziert funktionieren und die Codeabdeckung erhöhen.
- Vorgestellt wird ein Cover-Agent, der Codebasen automatisch scannt und PRs mit Test-Suites öffnet.
- Lasst uns mit KI die Aufgaben, die wir nicht mögen, effizienter erledigen!
Noch keine Kommentare.