Wie lassen wir Unit-Tests schnell laufen?

40

Wir haben den Punkt in unserem Projekt erreicht, an dem wir fast tausend Tests haben und die Leute haben aufgehört, sie auszuführen, bevor sie einchecken, weil es so lange dauert. Bestenfalls führen sie die Tests durch, die für den Code relevant sind, den sie geändert haben, und im schlimmsten Fall checken sie ihn einfach ein, ohne zu testen.

Ich glaube, dass dieses Problem auf die Tatsache zurückzuführen ist, dass die Lösung auf 120 Projekte angewachsen ist (wir machen normalerweise viel kleinere Projekte und dies ist nur das zweite Mal, dass wir TDD richtig durchführen) und die Build + -Testzeit auf ungefähr zwei bis drei Minuten angewachsen ist auf den kleineren Maschinen.

Wie verkürzen wir die Laufzeit der Tests? Gibt es Techniken? Mehr vortäuschen? Weniger vortäuschen? Vielleicht sollten die größeren Integrationstests nicht automatisch ausgeführt werden, wenn alle Tests ausgeführt werden?

Bearbeiten: Als Antwort auf einige der Antworten verwenden wir bereits CI und einen Build-Server. Daher weiß ich, dass die Tests fehlschlagen. Das Problem (eigentlich ein Symptom) ist, dass wir ständig Nachrichten über fehlgeschlagene Builds erhalten. Teilprüfungen durchzuführen, ist etwas, was die meisten Leute tun, aber nicht alle. und in Bezug auf die Tests sind sie eigentlich ziemlich gut gemacht, sie verwenden Fälschungen für alles und es gibt überhaupt keine IO.

Ziv
quelle
8
Bessere Hardware bekommen? Hardware ist billig im Vergleich zur Programmierzeit.
Bryan Oakley
18
Sie haben die Lösung bereits in Ihrer Frage impliziert: Führen Sie nur die Tests aus, die für den Code relevant sind, der geändert wurde. Führen Sie die gesamte Testsuite regelmäßig als Teil des QA / Release-Zyklus aus. Das heißt, 2 bis 3 Minuten klingen nicht nach viel Zeit. Es ist also möglich, dass Ihr Entwicklerteam die Dinge zu häufig eincheckt.
Robert Harvey
3
Erster Benchmark, um herauszufinden, woher die Leistungskosten stammen. Gibt es ein paar teure Tests oder ist es die bloße Menge an Tests? Sind bestimmte Setups teuer?
CodesInChaos
13
Verdammt, ich wünschte unsere Tests wären nur 2-3 Minuten. Die Durchführung aller Unit-Tests dauert 25 Minuten - und es liegen noch keine Integrationstests vor.
Izkata
4
2 bis 3 Minuten? Herrgott. Unsere können Stunden laufen ...
Roddy of the Frozen Peas

Antworten:

51

Eine mögliche Lösung wäre, den Testabschnitt von den Entwicklungsmaschinen auf ein kontinuierliches Integrationssetup ( z. B. Jenkins ) zu verschieben, indem Versionskontrollsoftware einer bestimmten Art ( git , svn usw.) verwendet wird.

Wenn neuer Code geschrieben werden muss, erstellt der jeweilige Entwickler eine Verzweigung für alle Aktivitäten im Repository. Alle Arbeiten werden in diesem Zweig ausgeführt und sie können ihre Änderungen jederzeit in den Zweig übertragen, ohne die Hauptcodezeile zu verfälschen.

Wenn die gegebene Funktion, die Fehlerbehebung oder was auch immer sie gerade bearbeiten, abgeschlossen ist, kann dieser Zweig wieder in den Trunk eingefügt werden (oder wie auch immer Sie es vorziehen), in dem alle Komponententests ausgeführt werden. Wenn ein Test fehlschlägt, wird die Zusammenführung abgelehnt und der Entwickler benachrichtigt, damit er die Fehler beheben kann.

Sie können Ihren CI-Server auch die Komponententests für jeden Feature-Zweig ausführen lassen, wenn Commits durchgeführt werden. Auf diese Weise kann der Entwickler einige Änderungen vornehmen, den Code festschreiben und den Server die Tests im Hintergrund ausführen lassen, während er weitere Änderungen oder andere Projekte bearbeitet.

Eine gute Anleitung für eine Möglichkeit, ein solches Setup durchzuführen, finden Sie hier (git-spezifisch, sollte aber für andere Versionskontrollsysteme funktionieren): http://nvie.com/posts/a-successful-git-branching-model/

Mike
quelle
15
Diese. Wenn die Entwickler "sich vor dem Einchecken nicht mehr darum
gekümmert haben
+1: Eine weitere Verbesserung wäre die Modularisierung der Tests. Wenn sich ein bestimmtes Modul / eine bestimmte Datei seit der letzten Ausführung nicht geändert hat, gibt es keinen Grund, die Tests, die für das Testen verantwortlich sind, erneut auszuführen. Eine Art Makefile, das nicht alles neu kompiliert, nur weil sich eine Datei geändert hat. Dies kann einige Arbeit erfordern, wird aber wahrscheinlich auch sauberere Tests ergeben.
Leo
Funktioniert die Verzweigungsmethode mit TFS? Wir schreiben C # mit TFS und das Verzweigen in TFS ist weniger benutzerfreundlich als in Git. Ich glaube, diese Idee wird sogar abgelehnt, da wir nie verzweigen.
Ziv
Ich habe keine persönlichen Erfahrungen mit TFS; Ich konnte jedoch auf dieses Handbuch von Microsoft stoßen, das anscheinend eine ähnliche Verzweigungsstrategie aufweist wie das in dem Beitrag: msdn.microsoft.com/en-us/magazine/gg598921.aspx
Mike
33

Die meisten Unit-Tests sollten jeweils weniger als 10 Millisekunden dauern. Fast tausend Tests zu haben, ist nichts und sollte vielleicht ein paar Sekunden dauern .

Wenn dies nicht der Fall ist, sollten Sie aufhören, hochgradig gekoppelte Integrationstests zu schreiben (es sei denn, der Code benötigt dies) und gute Komponententests schreiben (beginnend mit gut entkoppeltem Code und der richtigen Verwendung von Fakes / Mocks / Stubs / usw.). Diese Kopplung wirkt sich auf die Testqualität und die Zeit aus, die erforderlich ist, um sie zu schreiben - es geht also nicht nur darum, die Testlaufzeit zu verkürzen.

Telastyn
quelle
30
Nun, Sie sollten wahrscheinlich nicht aufhören, Integrationstests und andere nicht-einheitliche automatisierte Tests zu schreiben, da diese für sich genommen nützlich sind. Sie sollten sie nur nicht mit Unit-Tests verwechseln und getrennt halten, auch weil sie langsamer sind.
2
Sie korrigieren, dass dies Integrationstests zu sein scheinen.
Tom Squires
9
Diese Antwort ist nicht produktiv. Erstens setzt es eine unangemessene Erwartung. Es gibt Overheads im Unit-Testing-Framework selbst; Dass jeder Test weniger als eine Millisekunde dauert, bedeutet nicht, dass tausend Tests weniger als ein paar Sekunden dauern müssen. Dass die gesamte Testsuite des OP in 2-3 Minuten fertig ist, ist in den meisten Fällen ein sehr gutes Zeichen.
Rwong
6
@rwong - Entschuldigung, ich nenne Bullshit. Die Metrik, die ich erhielt, stammte aus der Ausführung der zwei verschiedenen professionellen Projekte, die mir zur Verfügung standen: eines mit ~ 300 Tests, eines mit ~ 30000 Tests und Blick auf die Testlaufzeiten. Eine Testsuite, die 2-3 Minuten für <1000 Tests benötigt, ist grausam und ein Zeichen dafür, dass die Tests nicht ausreichend isoliert sind.
Telastyn
2
@rwong In der gleichen Weise wie Telastyn, hier ist ein Datenpunkt von mir: Selbst mit einigen nicht ganz idealen Tests, dem Test-Framework ( py.test) , das jede Menge Magie im Hintergrund ausführt, und alles reinem Python-Code ("100x langsamer als C ") dauert die Ausführung der ca. 500 Tests in einem meiner Projekte auf einem mehrere Jahre alten, langsamen Netbook weniger als 6 Sekunden. Diese Zahl ist in der Anzahl der Tests ungefähr linear; Während ein gewisser Startaufwand anfällt, wird dieser über alle Tests amortisiert, und der Aufwand pro Test beträgt O (1).
16

Es gibt verschiedene Ansätze, mit denen ich ähnliche Probleme gelöst habe:

  1. Überprüfen Sie die Ausführungszeit und ermitteln Sie die langsamsten Tests. Analysieren Sie anschließend, warum die Ausführung so lange dauert .
  2. Sie haben 100 Projekte. Müssen Sie diese möglicherweise nicht jedes Mal erstellen und testen? Könntest du alle unittest nur nachts bauen? Erstellen Sie mehrere "schnelle" Build-Konfigurationen für den täglichen Gebrauch . Der CI-Server führt nur eine begrenzte Anzahl von Unittests-Projekten aus, die sich auf "heiße" Teile Ihres aktuellen Entwicklungsprozesses beziehen .
  3. Verspotten und isolieren Sie alles, was Sie könnten , und vermeiden Sie Festplatten- / Netzwerk-E / A, wann immer dies möglich ist
  4. Wenn es nicht möglich ist, solche Vorgänge zu isolieren, haben Sie möglicherweise Integrationstests? Könnten Sie Integrationstests nur für Nacht-Builds planen ?
  5. Überprüfen Sie alle gelegentlichen Singletons, die Verweise auf Instanzen / Ressourcen enthalten und Speicher belegen. Dies kann zu Leistungseinbußen führen, während alle Tests ausgeführt werden.

Darüber hinaus können Sie die folgenden Tools verwenden, um sowohl Ihr Leben zu vereinfachen als auch um Tests zu beschleunigen

  1. Gated Commit Einige CI-Server können für das Erstellen und Testen konfiguriert werden, bevor Code in das Quell-Repository übertragen wird. Wenn jemand Code schreibt, ohne zuvor alle Tests ausgeführt zu haben, der auch fehlgeschlagene Tests enthält, wird er abgelehnt und an den Autor zurückgesandt.
  2. Konfigurieren Sie den CI-Server so , dass Tests parallel ausgeführt werden : mit mehreren Computern oder Prozessen. Beispiele sind pnunitund CI-Konfiguration mit mehreren Knoten.
  3. Continuous Testing Plug-In für Entwickler, das alle Tests beim Schreiben von Code automatisch ausführt.
Akim
quelle
12

0. Hören Sie auf Ihre Programmierer.

Wenn sie die Tests nicht ausführen, bedeutet dies, dass sie die Kosten (Warten auf die Ausführung der Tests, Behandlung falscher Fehler) als höher als den Wert (sofortiges Erkennen von Fehlern) einschätzen. Reduzieren Sie die Kosten, erhöhen Sie den Wert und die Mitarbeiter führen die Tests die ganze Zeit durch.

1. Machen Sie Ihre Tests 100% zuverlässig.

Wenn Sie jemals Tests haben, die mit falschen Negativen scheitern, sollten Sie sich sofort darum kümmern. Reparieren Sie sie, ändern Sie sie, beseitigen Sie sie, was auch immer nötig ist, um 100% ige Zuverlässigkeit zu gewährleisten. (Es ist in Ordnung, eine Reihe von unzuverlässigen, aber dennoch nützlichen Tests zu haben, die Sie separat ausführen können. Der Hauptteil der Tests muss jedoch zuverlässig sein.)

2. Ändern Sie Ihre Systeme, um sicherzustellen, dass alle Tests die ganze Zeit bestehen.

Verwenden Sie kontinuierliche Integrationssysteme, um sicherzustellen, dass nur vorübergehende Commits in der Haupt- / Beamten- / Veröffentlichungs- / beliebigen Zweigstelle zusammengefasst werden.

3. Ändern Sie Ihre Kultur so, dass 100% der Tests bestanden werden.

Unterrichten Sie die Lektion, dass eine Aufgabe erst "erledigt" ist, nachdem 100% der Tests bestanden wurden und sie in den Zweig main / official / release / whatever integriert wurde.

4. Machen Sie die Tests schnell.

Ich habe an Projekten gearbeitet, bei denen Tests eine Sekunde dauern, und an Projekten, bei denen sie den ganzen Tag dauern. Es besteht eine starke Korrelation zwischen der Zeit, die für die Durchführung von Tests benötigt wird, und meiner Produktivität.

Je länger die Tests dauern, desto seltener werden sie ausgeführt. Das bedeutet, dass Sie länger brauchen, ohne Feedback zu den vorgenommenen Änderungen zu erhalten. Dies bedeutet auch, dass Sie zwischen den Commits länger brauchen. Häufigeres Festschreiben bedeutet kleinere Schritte, die einfacher zusammenzuführen sind. Commit-Historie ist leichter zu verfolgen; Es ist einfacher, einen Fehler in der Historie zu finden. Auch das Zurückrollen ist einfacher.

Stellen Sie sich Tests vor, die so schnell ablaufen, dass es Ihnen nichts ausmacht, sie bei jeder Kompilierung automatisch auszuführen.

Schnelle Tests können schwierig sein (das hat das OP gefragt, richtig!). Entkopplung ist der Schlüssel. Mocks / Fakes sind in Ordnung, aber ich denke, Sie können es besser machen, indem Sie überarbeiten, um Mocks / Fakes überflüssig zu machen. Siehe Arlo Belshees Blog, beginnend mit http://arlobelshee.com/post/the-no-mocks-book .

5. Machen Sie Tests nützlich.

Wenn die Tests nicht scheitern, wenn Sie es vermasseln, was ist dann der Sinn? Bringen Sie sich bei, Tests zu schreiben, die die Fehler auffangen, die Sie wahrscheinlich verursachen. Dies ist eine Fähigkeit für sich und wird viel Aufmerksamkeit erfordern.

Jay Bazuzi
quelle
2
Stimmen Sie ENDLICH zu, insbesondere Punkt 3 und 1. Wenn Entwickler keine Tests ausführen, sind die Tests fehlerhaft, die Umgebung ist fehlerhaft oder beides. Punkt 1 ist das Minimum. Falsche Fehler sind schlimmer als fehlende Tests. Weil die Menschen lernen zu akzeptieren, scheitert. Sobald ein Misserfolg toleriert wird, breitet er sich aus, und es ist eine gewaltige Anstrengung erforderlich, um wieder 100% zu bestehen und 100% zu ERWARTEN. Starten Sie diese Fixierung heute .
Bill IV
Und wie kann man evtl. mit # 5 nicht einverstanden sein?!? zusätzlich zu 1 & 3 oder heck, 2 & 4 auch! Wie auch immer, tolle Antwort rundum.
22.08.18 Uhr
4

Ein paar Minuten ist OK für Unit-Tests. Beachten Sie jedoch, dass es drei Haupttypen von Tests gibt:

  1. Unit-Tests - Testen Sie jede "Unit" (Klasse oder Methode) unabhängig vom Rest des Projekts
  2. Integrationstests - Testen Sie das Projekt als Ganzes, indem Sie in der Regel das Programm aufrufen. Einige Projekte, die ich gesehen habe, kombinieren dies mit Regressionstests. Hier wird deutlich weniger verspottet als bei Unit-Tests
  3. Regressionstests - Testen Sie das abgeschlossene Projekt als Ganzes, da die Testsuite ein Endbenutzer ist. Wenn Sie über eine Konsolenanwendung verfügen, können Sie das Programm über die Konsole ausführen und testen. Sie setzen Interna niemals diesen Tests aus, und jeder Endbenutzer Ihres Programms sollte (theoretisch) in der Lage sein, Ihre Regressionstestsuite auszuführen (auch wenn dies niemals der Fall ist).

Diese sind in der Reihenfolge der Geschwindigkeit aufgelistet. Unit-Tests sollten schnell gehen. Sie werden nicht jeden Fehler erkennen, aber sie stellen fest, dass das Programm vernünftig ist. Unit-Tests sollten in maximal 3 Minuten oder mit angemessener Hardware durchgeführt werden. Sie sagen, Sie haben nur 1000 Unit-Tests, und sie dauern 2-3 Minuten? Nun, das ist wahrscheinlich in Ordnung.

Dinge zu überprüfen:

  • Stellen Sie jedoch sicher, dass Ihre Komponententests und Integrationstests getrennt sind. Integrationstests sind immer langsamer.

  • Stellen Sie sicher, dass Ihre Komponententests parallel ausgeführt werden. Es gibt keinen Grund, dies nicht zu tun, wenn es sich um echte Komponententests handelt

  • Stellen Sie sicher, dass Ihre Komponententests "frei von Abhängigkeiten" sind. Sie sollten niemals auf eine Datenbank oder das Dateisystem zugreifen

Davon abgesehen klingen Ihre Tests im Moment nicht schlecht. Als Referenz hat jedoch einer meiner Freunde in einem Microsoft-Team 4.000 Komponententests, die auf anständiger Hardware in weniger als 2 Minuten ausgeführt werden (und es ist ein kompliziertes Projekt). Schnelle Unit-Tests sind möglich. Das Eliminieren von Abhängigkeiten (und Verspotten nur so oft wie nötig) ist die Hauptsache, um Geschwindigkeit zu erreichen.

Earlz
quelle
3

Trainieren Sie Ihre Entwickler in PSP (Personal Software Process), damit sie ihre Leistung durch mehr Disziplin verstehen und verbessern können. Das Schreiben von Code hat nichts damit zu tun, dass Sie mit den Fingern auf eine Tastatur schlagen und anschließend einen Compile- und Check-in-Button drücken.

PSP war in der Vergangenheit sehr beliebt, als das Kompilieren von Code viel Zeit in Anspruch nahm (Stunden / Tage auf einem Mainframe, sodass jeder den Compiler mitbenutzen musste). Aber als persönliche Workstations leistungsfähiger wurden, akzeptierten wir alle den Prozess:

  1. Geben Sie Code ein, ohne nachzudenken
  2. drücke build / compile
  3. Korrigieren Sie Ihre Syntax, damit sie kompiliert wird
  4. Führen Sie Tests durch, um festzustellen, ob das, was Sie geschrieben haben, tatsächlich Sinn ergibt

Wenn Sie überlegen, bevor Sie tippen, und dann nach dem Tippen überprüfen, was Sie geschrieben haben, können Sie die Anzahl der Fehler reduzieren, bevor Sie eine Build- und Testsuite ausführen. Lernen Sie, Build nicht 50-mal am Tag zu drucken, sondern ein- oder zweimal. Dann ist es weniger wichtig, dass Ihre Build- und Testzeit einige Minuten länger dauert.

Bart Koopman
quelle
2
Ich stimme Ihrer Liste zutiefst zu, aber absolut nicht mit "Nur zweimal am Tag zu bauen ist besser als 50 Mal".
Doc Brown
3

Ein möglicher Weg: Teilen Sie Ihre Lösung. Wenn eine Lösung 100 Projekte umfasst, ist sie nicht mehr zu handhaben. Nur weil zwei Projekte (z. B. A und B) einen gemeinsamen Code aus einem anderen Projekt (z. B. Lib) verwenden, müssen sie sich nicht in derselben Lösung befinden.

Stattdessen können Sie Lösung A mit Projekten A und Lib sowie Lösung B mit Projekten B und Lib erstellen.

svick
quelle
2

Ich bin in einer ähnlichen Situation. Ich habe Unit-Tests, die die Kommunikation mit dem Server testen. Sie testen das Verhalten mit Zeitüberschreitungen, brechen Verbindungen usw. ab. Die gesamte Testreihe dauert 7 Minuten.

7 Minuten sind eine relativ kurze Zeit, aber nicht vor jedem Commit.

Wir haben auch eine Reihe von automatisierten UI-Tests, deren Laufzeit 2 Stunden beträgt. Es ist nicht etwas, das Sie jeden Tag auf Ihrem Computer ausführen möchten.

Also, was ist zu tun?

  1. Das Ändern der Tests ist normalerweise nicht sehr effektiv.
  2. Führen Sie vor dem Festschreiben nur die relevanten Tests aus.
  3. Führen Sie alle Ihre Tests täglich (oder mehrmals täglich) auf einem Buildserver aus. Auf diese Weise haben Sie auch die Möglichkeit, Berichte zur Codeabdeckung und Codeanalyse zu erstellen.

Das Wichtigste ist: Alle Ihre Tests sollten häufig ausgeführt werden, da es wichtig ist, die Fehler zu finden. Es ist jedoch nicht unbedingt erforderlich, sie vor dem Festschreiben zu finden.

Sulthan
quelle
1
Tests, die mit Servern kommunizieren: Wenn es sich um einen Server handelt, handelt es sich nicht wirklich um einen Komponententest, sondern um etwas Höheres. Wenn ich Sie wäre, würde ich die Unit-Tests (die schnell ausgeführt werden sollten) aufteilen und diese zumindest vor jedem Commit ausführen. Auf diese Weise werden Sie zumindest die schnellen Dinge (Dinge, die nicht mit dem Server kommunizieren müssen) aus dem Weg räumen, bevor der Code festgeschrieben wird.
Michael Kohne
@MichaelKohne Ich wusste, dass jemand es erkennen würde. Ich weiß, dass es sich nicht um Unit-Tests handelt, aber sie dienen demselben Zweck. Es geht nur darum, wie Sie sie benennen.
Sulthan
1
Meistens geht es darum, wie Sie sie benennen, aber es ist gut, den Unterschied im Hinterkopf zu behalten (welcher Name auch immer Sie verwenden). Wenn Sie nicht differenzieren, neigen die Entwickler (meiner Erfahrung nach) dazu, nur Tests auf höherer Ebene zu schreiben. An diesem Punkt erhalten Sie keine Tests, die Sie dazu zwingen, in Ihren Abstraktionen und Kopplungen vernünftig zu sein.
Michael Kohne
1

Obwohl Ihre Beschreibung des Problems keinen gründlichen Einblick in die Codebasis gibt, kann ich mit Sicherheit sagen, dass es sich um ein zweifaches Problem handelt.

Lerne die richtigen Tests zu schreiben.

Sie sagen, Sie haben fast tausend Tests und Sie haben 120 Projekte. Angenommen, höchstens die Hälfte dieser Projekte sind Testprojekte, haben Sie 1000 Tests für 60 Produktionscode-Projekte. Das gibt Ihnen etwa 16-17 Tests pro. Projekt!!!

Das ist wahrscheinlich die Menge an Tests, die ich in einem Produktionssystem für 1-2 Klassen durchführen müsste. Wenn Sie also nicht nur 1-2 Klassen in jedem Projekt haben (in diesem Fall ist Ihre Projektstruktur zu feinkörnig), sind Ihre Tests zu groß, sie decken zu viel Boden ab. Sie sagen, dies ist das erste Projekt, bei dem Sie TDD ordnungsgemäß durchführen. Angenommen, die von Ihnen angegebenen Zahlen weisen darauf hin, dass dies nicht der Fall ist und Sie keine TDD-Eigenschaft ausführen.

Sie müssen lernen, die richtigen Tests zu schreiben. Dies bedeutet wahrscheinlich, dass Sie zunächst lernen müssen, wie Sie den Code testbar machen. Wenn Sie innerhalb des Teams keine Erfahrung dafür finden, würde ich vorschlagen, Hilfe von außen anzustellen, z. B. in Form von einem oder zwei Beratern, die Ihrem Team über einen Zeitraum von zwei bis drei Monaten dabei helfen, testbaren Code zu schreiben minimale Unit-Tests.

Zum Vergleich: In dem .NET-Projekt, an dem ich gerade arbeite, können wir ungefähr 500 Unit-Tests in weniger als 10 Sekunden durchführen (und das wurde nicht einmal auf einem High-Spec-Computer gemessen). Wenn das Ihre Zahlen wären, hätten Sie keine Angst davor, diese von Zeit zu Zeit vor Ort zu betreiben.

Erfahren Sie, wie Sie die Projektstruktur verwalten.

Sie haben die Lösung in 120 Projekte unterteilt. Das ist nach meinen Maßstäben eine erstaunliche Anzahl von Projekten.

Wenn es also Sinn macht, tatsächlich so viele Projekte zu haben (was meines Erachtens nicht der Fall ist - aber Ihre Frage enthält nicht genügend Informationen, um dies beurteilen zu können), müssen Sie die Projekte in kleinere Komponenten aufteilen, die kann separat erstellt, versioniert und bereitgestellt werden. Wenn ein Entwickler die Testsuite auf unit ausführt, muss er nur die Tests ausführen, die sich auf die Komponente beziehen, an der er gerade arbeitet. Der Build-Server sollte sicherstellen, dass alles korrekt integriert ist.

Die Aufteilung eines Projekts in mehrere Komponenten, die separat erstellt, versioniert und bereitgestellt werden, erfordert meiner Erfahrung nach ein sehr ausgereiftes Entwicklungsteam, ein Team, das ausgereifter ist, als ich das Gefühl habe, dass Ihr Team es ist.

In jedem Fall müssen Sie jedoch etwas an der Projektstruktur ändern. Teilen Sie die Projekte entweder in separate Komponenten auf oder beginnen Sie mit dem Zusammenführen von Projekten.

Fragen Sie sich, ob Sie wirklich 120 Projekte benötigen?

ps Vielleicht möchten Sie NCrunch ausprobieren. Es ist ein Visual Studio-Plug-In, das Ihren Test automatisch im Hintergrund ausführt.

Pete
quelle
0

JUnit-Tests sind normalerweise schnell durchzuführen, aber einige von ihnen müssen nur einige Zeit in Anspruch nehmen, um sie auszuführen.

Beispielsweise dauert der Datenbanktest in der Regel einige Zeit, bis er initialisiert und abgeschlossen ist.

Wenn Sie Hunderte von Tests haben, selbst wenn sie schnell sind, benötigen sie aufgrund ihrer Anzahl viel Zeit, um ausgeführt zu werden.

Was getan werden kann, ist:

1) Identifizieren Sie die entscheidenden Tests. Die für die wichtigsten Teile von Bibliotheken und die, die nach Änderungen am wahrscheinlichsten versagen. Nur dieser Test sollte immer beim Kompilieren ausgeführt werden. Wenn ein Code häufig beschädigt ist, sollten seine Tests obligatorisch sein, auch wenn die Ausführung lange dauert. Wenn andererseits ein Teil der Software nie ein Problem verursacht hat, können Sie Tests für jeden Build sicher überspringen.

2) Bereiten Sie den Continuous Integration Server vor, auf dem alle Tests im Hintergrund ausgeführt werden. Es liegt an Ihnen, ob Sie sich entscheiden, stündlich oder nach jedem Commit zu bauen (der zweite Schritt ist nur sinnvoll, wenn Sie automatisch erkennen möchten, wessen Commit Probleme verursacht hat).

Donau Seemann
quelle
0

Probleme, die ich gesehen habe:

a) Verwenden von IOC zum Aufbau von Testelementen. 70 Sekunden -> 7 Sekunden durch Entfernen des Behälters.

b) Nicht alle Klassen verspotten. Halten Sie Ihre Unit-Tests auf ein einzelnes Element. Ich habe Tests gesehen, die durch ein paar Klassen streifen. Dies sind keine Komponententests und es ist wahrscheinlicher, dass sie brechen.

c) Profilieren Sie sie, um herauszufinden, was passiert ist. Ich fand, dass der Konstruktor Dinge baute, die ich nicht brauchte, also lokalisierte ich sie und reduzierte die Laufzeit.

d) Profil. Vielleicht ist der Code nicht so gut und Sie können durch eine Überprüfung etwas Effizienz gewinnen.

e) Entfernen Sie Abhängigkeiten. Wenn Sie die ausführbare Datei klein halten, wird die Ladezeit verkürzt. Verwenden Sie eine Schnittstellenbibliothek und IOC-Container, um Ihre endgültige Lösung auszuführen. In Ihren Haupttestprojekten sollte jedoch nur die Schnittstellenbibliothek definiert sein. Dies stellt die Trennung sicher, erleichtert das Testen und verkleinert den Testfußabdruck.

Waratah
quelle
0

Ich fühle deinen Schmerz und bin an verschiedenen Stellen gelaufen, an denen die Build-Geschwindigkeit erheblich verbessert werden kann. Ich empfehle jedoch, die Anzahl an Details zu messen, um herauszufinden, wo Ihr Build am längsten dauert. Zum Beispiel habe ich einen Build mit ungefähr 30 Projekten, dessen Ausführung etwas mehr als eine Minute dauert. Dies ist jedoch nur ein Teil des Bildes. Ich weiß auch, welche Projekte am längsten dauern, was mir hilft, meine Bemühungen zu konzentrieren.

Dinge, die die Bauzeit verschlingen:

  • Paketdownload (Nuget für C #, Maven für Java, Gem für Ruby usw.)
  • Kopieren großer Dateienmengen in das Dateisystem (Beispiel: GDAL-Unterstützungsdateien)
  • Öffnen von Verbindungen zur Datenbank (einige benötigen pro Verbindung mehr als eine Sekunde zum Aushandeln)
  • Reflektionsbasierter Code
  • Automatisch generierter Code
  • Verwenden von Ausnahmen zur Steuerung des Programmflusses

Mock-Bibliotheken verwenden entweder Reflection oder injizieren Code mithilfe von Bytecode-Bibliotheken, um das Mock für Sie zu generieren. Es ist zwar sehr praktisch, nimmt aber die Testzeit in Anspruch. Wenn Sie in Ihrem Test in einer Schleife Verspottungen generieren, kann dies den Komponententests eine messbare Zeitspanne hinzufügen.

Es gibt verschiedene Möglichkeiten, um die Probleme zu beheben:

  • Verschieben von Tests mit einer Datenbank in die Integration (dh nur auf dem CI-Build-Server)
  • Vermeiden Sie in Ihren Tests das Erstellen von Mocks in Schleifen. Vermeiden Sie in der Tat nur Schleifen in Ihren Tests insgesamt. In diesem Fall können Sie wahrscheinlich mit einem parametrisierten Test die gleichen Ergebnisse erzielen.
  • Überlegen Sie, ob Sie Ihre massive Lösung in separate Lösungen aufteilen möchten

Wenn Ihre Lösung über 100 Projekte enthält, verfügen Sie über eine Kombination aus Bibliothekscode, Tests und Anwendungscode. Jede der Bibliotheken kann eine eigene Lösung mit den zugehörigen Tests sein. Jet Brains Team City ist ein CI-Build-Server, der auch als Nuget-Server fungiert - und ich bin sicher, dass es nicht der einzige ist. Dies gibt Ihnen die Flexibilität, Bibliotheken, die wahrscheinlich nicht oft geändert werden, in ihre eigenen Lösungen / Projekte zu verschieben und mithilfe von Nuget die Abhängigkeiten für Ihren Anwendungscode aufzulösen. Kleinere Lösungen bedeuten, dass Sie Ihre Änderungen an einer Bibliothek schnell und unkompliziert vornehmen und die Vorteile der Hauptlösung nutzen können.

Berin Loritsch
quelle
-1

Kann Ihre Testumgebung überall ausgeführt werden? Verwenden Sie, falls dies möglich ist, Cloud Computing, um die Tests auszuführen. Teilen Sie die Tests auf N virtuelle Maschinen auf. Wenn die Zeit für die Ausführung der Tests auf einem einzelnen Computer T1 Sekunden beträgt, kann sich die Zeit für die Aufteilung T2 T2 = T1 / N nähern. (Angenommen, jeder Testfall benötigt ungefähr die gleiche Zeit.) Und Sie müssen nur für die VMs bezahlen, wenn Sie sie verwenden. Sie haben also nicht rund um die Uhr einen Haufen Testmaschinen in einem Labor. (Ich würde dies gerne dort tun, wo ich arbeite, aber wir sind an bestimmte Hardware gebunden. Keine VMs für mich.)

Nani Tatiana Isobel
quelle