Ich habe an einem ziemlich großen Python-Projekt mit einer Reihe von Tests gearbeitet.
Einige spezielle Teile der Anwendung erfordern einige CPU-intensive Tests, und unser Ansatz, alles zu testen, bevor das Commit aufhört, macht Sinn.
Wir haben seither einen Tag-basierten selektiven Testansatz übernommen. Das Problem ist, dass mit der wachsenden Codebasis die Pflege dieses Tagging-Schemas etwas umständlich wird, und ich würde gerne anfangen zu lernen, ob wir etwas Klügeres bauen könnten.
In einem früheren Job war das Testsystem so, dass es nur Code testete, der von den Änderungen beim Commit betroffen war.
Es scheint, als ob Mighty Moose einen ähnlichen Ansatz für CLR
languages verwendet. Wenn ich diese als Inspiration verwende, ist meine Frage, welche Alternativen (wenn überhaupt) für intelligentes selektives Testen in Python
-Projekten vorhanden sind?
Falls es keine gibt, was wären die ersten Ansätze, um so etwas aufzubauen?
Die Idee, das selektive Testen von Teilen Ihrer Anwendung zu automatisieren, klingt definitiv interessant. Es fühlt sich jedoch so an, als ob dies mit einer statisch getippten Sprache viel einfacher zu erreichen wäre, aber angesichts der Dynamik von Python wäre es wahrscheinlich eine große Zeit, etwas zu bekommen, das zuverlässig alle von einem Commit betroffenen Tests erkennt .
Wenn Sie Ihr Problem lesen und die Idee des selektiven Testens beiseite legen, sollten Sie in der Lage sein, Tests zu gruppieren, so dass Sie Testsuiten isoliert ausführen können, was eine Reihe nützlicher automatisierter Testausführungsstrategien ermöglicht verkürze die Rückkopplungsschleife wie:
Daher denke ich, dass Ihr Ansatz, Tags zu verwenden, um Tests in verschiedene "Gruppen" zu partitionieren, ein kluger Ansatz ist, obwohl Sie sagen, dass das Management dieser mit einer großen Testsuite schwierig wird. In Anbetracht dessen könnte es sich lohnen, Zeit in die Entwicklung von Tools zu investieren, um die Verwaltung Ihrer Testsuite zu unterstützen, insbesondere die Verwaltung Ihrer Tags. Ein solches System könnte aufgebaut werden, indem Informationen gesammelt werden von:
Viel Glück, es ist definitiv ein interessantes Problem, das Sie versuchen zu lösen, und hoffen, dass einige dieser Ideen Ihnen helfen.
Wenn Sie unittest.TestCase
verwenden, können Sie angeben, welche Dateien mit dem% co_de ausgeführt werden sollen % Parameter Dann können Sie Tests basierend auf dem geänderten Code ausführen. Auch wenn Sie pattern
nicht verwenden, sollten Sie Ihre Tests nach Funktionsbereichen / Modulen ordnen, damit Sie einen ähnlichen Ansatz verwenden können.
Optional, keine elegante Lösung für Ihr Problem, aber wenn jeder Entwickler- / Gruppen- oder Funktionscodebereich an einen separaten Zweig übergeben wurde, könnte er in Ihrer Continuous Testing-Umgebung ausgeführt werden. Sobald dies abgeschlossen ist (und bestanden wurde), können Sie sie in Ihren Hauptstamm / Hauptzweig zusammenführen.
Eine Kombination von nächtlichen Jobs aller Tests und pro-Branch-Tests alle 15-30 Minuten (wenn es neue Commits gibt) sollte ausreichen.
Einige zufällige Gedanken zu diesem Thema, basierend auf der Arbeit, die ich zuvor an einer Perl-Codebase mit ähnlichen "full build is tall long" -Problemen gemacht habe:
Das Wissen um Ihre Abhängigkeiten ist der Schlüssel dafür, dass dies funktioniert. Wenn das Modul A von B und C abhängig ist, müssen Sie A testen, wenn eines der beiden dann geändert wird. Es sieht aus wie Snakefood ist ein guter Weg zu bekommen ein Wörterbuch, das die Abhängigkeiten in Ihrem Code umreißt; Wenn Sie das übernehmen und in ein Makefile übersetzen, dann können Sie beim Einchecken einfach "test" machen und alle Abhängigkeiten (und nur die benötigten) werden neu erstellt und getestet.
Sobald Sie ein Makefile haben, arbeiten Sie an machen es parallel >; Wenn Sie ein halbes Dutzend Tests parallel ausführen können, verringern Sie die Laufzeit erheblich.
Wenn Sie die Testergebnisse in eine Datei schreiben, können Sie make oder eine ähnliche Alternative verwenden, um zu bestimmen, wann die Tests neu erstellt werden müssen. Wenn Sie Ergebnisse in die Datei schreiben, kann make den Datumsstempel der Tests mit den abhängigen Python-Dateien vergleichen.
Leider kann Python nicht genau bestimmen, worauf es ankommt, da Module dynamisch importiert werden können, sodass Sie Importe nicht zuverlässig betrachten können, um betroffene Module zu bestimmen.
Ich würde eine Namenskonvention verwenden, damit make das generisch lösen kann. Ein naives Beispiel wäre:
%Vor%Definiert eine neue implizite Regel für die Konvertierung zwischen _test.py und Testergebnissen. Dann können Sie Ihre zusätzlichen Abhängigkeiten für Ihre Tests festlegen, etwa so:
%Vor% Stellen Sie sich die Frage um: Welche Tests müssen ausgeschlossen werden, damit der Rest tolerierbar wird? Die CPython-Testsuite in Lib / test schließt ressourcenintensive Tests aus, bis sie speziell angefordert werden (wie sie auf einem Buildbot sein können). Einige der optionalen Ressourcen sind "CPU" (Zeit), "Largefile" (Speicherplatz) und "Netzwerk" (Verbindungen). ( python -m test -h
(auf 3.x, test.regrtest auf 2.x) gibt die gesamte Liste an.)
Leider kann ich Sie nicht sagen, wie dies zu tun ist, wenn "skip if resource not available" eine Funktion des älteren test.regrest-Läufers ist, den die Testsuite verwendet. Es gibt ein Problem im Tracker, Ressourcen zum Komponententest hinzuzufügen.
Was in der Zwischenzeit funktioniert, ist ungefähr so: Fügen Sie eine maschinenspezifische Datei, exclusions.py, hinzu, die eine Liste von Zeichenfolgen wie die oben genannten enthält. Importieren Sie dann Ausschlüsse und überspringen Sie Tests, Fälle oder Module, wenn sich die entsprechende Zeichenfolge in der Liste befindet.
Wir sind in der Vergangenheit mehrmals auf dieses Problem gestoßen und konnten es durch Verbessern und Neu-Factoring von Tests beantworten. Sie geben weder Ihre Entwicklungspraktiken noch die Dauer Ihrer Tests an. Ich würde sagen, wenn Sie TDD tun, müssen Sie Tests nicht mehr als ein paar Sekunden ausführen. Alles, was länger als das dauert, müssen Sie auf einen Server verschieben. Wenn Ihre Tests länger als einen Tag dauern, haben Sie ein echtes Problem, und es wird Ihre Fähigkeit einschränken, Funktionalität schnell und effektiv bereitzustellen.