Wie skalieren Sie Ihre Integrationstests?

21

Suche ich Techniken und Strategien für unsere wachsende Zahl von Integrationstests auf unserem aktuellen Produkt Skalierung, so dass sie können (menschlich) Teil unserer Entwicklung bleiben und CI - Prozess.

Bei mehr als 200 Integrationstests erreichen wir bereits die 1-Stunden-Marke, um einen vollständigen Testlauf (auf einem Desktop-Entwicklungscomputer) abzuschließen. Dies beeinträchtigt die Fähigkeit eines Entwicklers, die Ausführung der gesamten Suite als Teil der Routine-Push-Prozesse zu tolerieren. Das wirkt sich auf die Motivation aus, diszipliniert zu sein, um sie gut zu schaffen. Wir testen nur Schlüsselszenarien von vorne nach hinten und verwenden eine Umgebung, die die Produktion widerspiegelt und bei jedem Testlauf von Grund auf neu erstellt wird.

Aufgrund der Zeit, die für die Ausführung benötigt wird, kommt es zu einer schrecklichen Rückkopplungsschleife und vielen verschwendeten Zyklen, die darauf warten, dass die Maschinen die Testläufe abschließen, unabhängig davon, wie konzentriert die Testläufe sind. Vergiss die teureren negativen Auswirkungen auf Fluss und Fortschritt, Gesundheit und Nachhaltigkeit.

Wir gehen davon aus, dass wir zehnmal mehr Integrationstests durchführen werden, bevor sich dieses Produkt verlangsamt (keine Ahnung, aber es scheint, als würden wir noch nicht einmal mit den Funktionen beginnen). Wir müssen damit rechnen, dass wir in den paar hundert oder ein paar tausend Integrationstests sein werden, rechne ich irgendwann.

Um klar zu sein, um zu verhindern, dass dies zu einer Diskussion über Unit-Tests und Integrationstests wird (die niemals gehandelt werden sollten). Wir führen in diesem Produkt sowohl Unit-Tests mit TDD als auch Integrationstests durch. In der Tat führen wir Integrationstests auf den verschiedenen Ebenen der Servicearchitektur durch, die für uns sinnvoll sind, da wir überprüfen müssen, wo wir wichtige Änderungen einführen, wenn wir die Muster in unserer Architektur auf die anderen Bereiche der Architektur übertragen System. 

Ein bisschen über unseren Tech Stack. Wir testen derzeit in einer (CPU- und speicherintensiven) Emulationsumgebung, um unsere Tests von Ende zu Ende durchzuführen. Dieser besteht aus Azure REST-Webdiensten, die ein NoSql-Backend (ATS) bereitstellen. Wir simulieren unsere Produktionsumgebung, indem wir den Azure-Desktop-Emulator + IISExpress ausführen. Wir sind auf einen Emulator und ein lokales Backend-Repository pro Dev-Rechner beschränkt.

Wir haben auch ein Cloud-basiertes CI, das denselben Test in derselben emulierten Umgebung ausführt, und die Testläufe in der Cloud dauern mit unserem aktuellen CI-Anbieter doppelt so lange (2 Stunden +). In Bezug auf die Hardwareleistung sind wir an die Grenzen der SLA des Cloud-CI-Anbieters gestoßen und haben deren zulässige Testlaufzeit überschritten. Um fair zu sein, ihre technischen Daten sind nicht schlecht, aber deutlich halb so gut wie die einer hauseigenen grunzigen Desktop-Maschine.

Wir verwenden eine Teststrategie, bei der der Datenspeicher für jede logische Testgruppe neu erstellt und die Testdaten vorab geladen werden. Dadurch wird die Datenintegrität umfassend sichergestellt, und die Auswirkungen auf jeden Test werden um 5 bis 15% erhöht. Wir glauben, dass es an diesem Punkt der Produktentwicklung nicht viel zu gewinnen gibt, um diese Teststrategie zu optimieren. 

Das Entscheidende ist, dass wir zwar den Durchsatz jedes Tests optimieren können (auch wenn er um jeweils 30% bis 50% steigt), aber in naher Zukunft mit mehreren hundert Tests immer noch nicht effektiv skalieren können. 1 Std. Ist sogar immer noch weit über dem vom Menschen tolerierbaren Wert, wir müssen den Gesamtprozess um eine Größenordnung verbessern, um ihn nachhaltig zu gestalten.

Daher untersuche ich, mit welchen Techniken und Strategien wir die Testzeit drastisch reduzieren können.

  • Weniger Tests zu schreiben ist keine Option. Lassen Sie uns das bitte nicht in diesem Thread diskutieren.
  • Die Verwendung schnellerer Hardware ist auf jeden Fall eine Option, wenn auch sehr teuer.
  • Das parallele Ausführen von Gruppen von Tests / Szenarien auf separater Hardware ist ebenfalls auf jeden Fall eine bevorzugte Option.
  • Das Erstellen einer Gruppierung von Tests um in der Entwicklung befindliche Features und Szenarien ist plausibel, jedoch letztendlich nicht zuverlässig, um die vollständige Abdeckung oder das Vertrauen zu beweisen, dass das System von einer Änderung nicht betroffen ist. 
  • Die Ausführung in einer Cloud-skalierten Staging-Umgebung anstelle des Desktop-Emulators ist technisch möglich, obwohl wir anfangen, Testläufen Bereitstellungszeiten hinzuzufügen (jeweils ~ 20 Minuten zu Beginn des Testlaufs, um das Zeug bereitzustellen).
  • Die Aufteilung der Komponenten des Systems in unabhängige logische Teile ist bis zu einem gewissen Grad plausibel, wir erwarten jedoch eine begrenzte Laufleistung, da die Wechselwirkungen zwischen den Komponenten mit der Zeit zunehmen dürften. (dh eine Änderung wirkt sich wahrscheinlich auf unerwartete Weise auf andere aus, wie dies häufig der Fall ist, wenn ein System schrittweise entwickelt wird.)

Ich wollte sehen, welche Strategien (und Werkzeuge) andere in diesem Bereich verwenden.

(Ich muss glauben, dass andere diese Art von Schwierigkeiten mit bestimmten Technologie-Sets sehen können.)

[Update: 16.12.2016: Wir haben letztendlich mehr in CI-Paralleltests investiert, um das Ergebnis zu diskutieren: http://www.mindkin.co.nz/blog/2015/12/16/16-jobs]

Jezz Santos
quelle
Seit ich diesen Beitrag verfasst habe, habe ich untersucht, ob nCrunch (das wir ausgiebig für unsere Unit-Tests verwenden) ein Werkzeug sein kann, das uns eine Taktik bietet. Offensichtlich ist es möglich, Tests an entfernte Maschinen zu versenden und diese parallel auszuführen. Es kann also sinnvoll sein, Gruppen von Integrationstests sowie mehrere Instanzen von hochspezifizierten Cloud-Computern zu identifizieren. nCrunch behauptet, dass dies die genaue Absicht dieser Funktion ist. Hat das noch jemand versucht?
Jezz Santos,
Sieht so aus, als würde dies zu einer Diskussion darüber führen, was ein Integrationstest ist und was kein Integrationstest ist und wie die Leute Unit-Tests und Integrationstests missverstehen, oh Mann!
Jezz Santos

Antworten:

9

Ich habe an einem Ort gearbeitet, an dem 5 Stunden (auf 30 Maschinen) für die Durchführung von Integrationstests benötigt wurden. Ich habe die Codebasis überarbeitet und stattdessen Unit-Tests für das neue Zeug durchgeführt. Die Unit-Tests dauerten 30 Sekunden (über 1 Maschine). Oh, und die Käfer sind auch runtergegangen. Und Entwicklungszeit, da wir genau wussten , was mit Granular-Tests gebrochen hat.

Lange Rede kurzer Sinn, das tust du nicht. Vollständige Integrationstests nehmen exponentiell zu, wenn Ihre Codebasis wächst (mehr Code bedeutet mehr Tests und mehr Code bedeutet, dass die Ausführung aller Tests länger dauert, da mehr "Integration" erforderlich ist). Ich würde argumentieren, dass alles im "Stundenbereich" die meisten Vorteile der kontinuierlichen Integration verliert, da die Rückkopplungsschleife nicht vorhanden ist. Selbst eine Verbesserung um eine Größenordnung reicht nicht aus, um Sie gut zu machen - und es ist nicht annähernd ausreichend, um Sie skalierbar zu machen.

Daher würde ich empfehlen, die Integrationstests auf die umfassendsten und wichtigsten Rauchprüfungen zu beschränken. Sie können dann jede Nacht oder in einem nicht kontinuierlichen Intervall ausgeführt werden, wodurch Ihr Leistungsbedarf erheblich reduziert wird. Unit-Tests, die nur linear anwachsen, wenn Sie mehr Code hinzufügen (Tests nehmen zu, Laufzeit pro Test nicht), sind der richtige Maßstab.

Telastyn
quelle
Genau. Unit-Tests sind viel skalierbarer und unterstützen eine schnellere Rückkopplungsschleife.
Brandon
8
Sie könnten diesen Punkt verpasst haben. Das OP führt bereits umfangreiche uint-Tests sowie die fraglichen Integrationstests durch. Unit-Tests sind niemals ein Ersatz für Integrationstests. Unterschiedliches Werkzeug, unterschiedliche Praktiken, unterschiedliche Zwecke, unterschiedliche Ergebnisse. Es ist nie eine Frage des einen oder anderen.
Jezz Santos,
1
Der Beitrag wurde übersichtlicher, um deutlich zu machen, dass dieses Produkt mit TDD erstellt wurde. Daher gibt es bereits Tausende von Komponententests, die von den fraglichen Integrationstests unterstützt werden. .
Jezz Santos
8

Integrationstests werden immer lange dauern, da sie einen echten Benutzer imitieren sollten. Aus diesem Grund sollten Sie nicht alle synchron ausführen!

Angesichts der Tatsache, dass Sie bereits Dinge in der Cloud ausführen, scheint es mir, als wären Sie in der besten Position, um Ihre Tests über mehrere Computer zu skalieren.

Im Extremfall starten Sie eine neue Umgebung pro Test und führen Sie alle gleichzeitig aus. Ihre Integrationstests dauern dann nur so lange wie der Test mit der längsten Laufzeit.

Ewan
quelle
Gute Idee! Betrachtet man eine Strategie wie diese, aber mit einigen Tools, die beim verteilten Testen helfen
Jezz Santos
4

Das Reduzieren / Optimieren der Tests scheint mir die beste Idee zu sein, aber für den Fall, dass dies keine Option ist, habe ich eine Alternative zum Vorschlagen (erfordert jedoch das Erstellen einiger einfacher proprietärer Tools).

Ich hatte ein ähnliches Problem, aber nicht in unseren Integrationstests (die liefen in Minuten). Stattdessen war es einfach in unseren Builds: Die Erstellung einer C-Codebasis im großen Maßstab würde Stunden dauern.

Was ich als extrem verschwenderisch sah , war die Tatsache , dass wir das waren Wiederaufbau ganze Sache von Grund auf (etwa 20.000 Quelldateien / Kompilierungseinheiten) , auch wenn nur wenige Quelldateien geändert und damit für einen Wechsel zu verbringen Stunden , die nur wenige Sekunden oder Minuten dauern sollte schlimmstenfalls.

Wir haben also versucht, inkrementelle Verknüpfungen auf unseren Build-Servern herzustellen, aber das war unzuverlässig. Es gab manchmal falsche Negative und konnte auf einigen Commits nicht aufbauen, um dann bei einem vollständigen Neuaufbau erfolgreich zu sein. Schlimmer noch, es gab manchmal Fehlalarme und meldete einen Build-Erfolg, nur dass der Entwickler ein defektes Build in den Hauptzweig einbindete. Deshalb haben wir jedes Mal, wenn ein Entwickler Änderungen aus seiner privaten Filiale herausgenommen hat, alles neu aufgebaut.

Ich hasste das so sehr. Ich ging mit der Hälfte der Entwickler in Konferenzräume, um Videospiele zu spielen, und weil es beim Warten auf Builds nur wenig anderes zu tun gab. Ich habe versucht, durch Multitasking und Starten einer neuen Verzweigung einen Produktivitätsvorteil zu erzielen, sobald ich eine Commit-Operation ausgeführt habe, damit ich während des Wartens auf die Builds am Code arbeiten kann. Wenn jedoch ein Test oder Build fehlschlug, war es zu schmerzhaft, Änderungen nach diesem Zeitpunkt in die Warteschlange zu stellen und versuchen, alles zu reparieren und alles wieder zu nähen.

Nebenprojekt Während des Wartens, später integrieren

Also habe ich stattdessen ein Grundgerüst der Anwendung erstellt - dieselbe Art von grundlegender Benutzeroberfläche und relevante Teile des SDK, gegen die ich mich als ganzes separates Projekt entwickeln konnte. Dann würde ich unabhängigen Code dagegen schreiben, während ich auf Builds außerhalb des Hauptprojekts warte. Das gab mir zumindest einige Programmierkenntnisse, damit ich einigermaßen produktiv bleiben konnte, und dann begann ich, diese Arbeit, die vollständig außerhalb des Produkts ausgeführt wurde, später in die projektseitigen Codeausschnitte zu integrieren. Das ist eine Strategie für Ihre Entwickler, wenn sie viel warten müssen.

Manuelles Analysieren von Quelldateien, um herauszufinden, was neu erstellt / erneut ausgeführt werden soll

Trotzdem hasste ich es, dass wir so viel Zeit verschwendeten, um die ganze Zeit alles wieder aufzubauen . Deshalb habe ich es über ein paar Wochenenden auf mich genommen, Code zu schreiben, der Dateien auf Änderungen überprüft und nur die relevanten Projekte neu erstellt - immer noch ein vollständiger Neuaufbau, keine inkrementelle Verknüpfung, sondern nur die Projekte, die neu erstellt werden müssen ( deren abhängige Dateien, rekursiv analysiert, geändert wurden). Das war absolut zuverlässig und nachdem wir es ausführlich demonstriert und getestet hatten, konnten wir diese Lösung verwenden. Dadurch wurde die durchschnittliche Erstellungszeit von Stunden auf einige Minuten verkürzt, da wir nur die erforderlichen Projekte neu erstellten (obwohl zentrale SDK-Änderungen noch eine Stunde dauern konnten, wir haben dies jedoch viel seltener als lokalisierte Änderungen durchgeführt).

Die gleiche Strategie sollte für Integrationstests gelten. Analysieren Sie Quelldateien einfach rekursiv, um herauszufinden, von welchen Dateien die Integrationstests abhängen (z. B .: importin Java,#includein C oder C ++) auf der Serverseite und die darin enthaltenen / importierten Dateien usw., Erstellen eines vollständigen Abhängigkeitsdatei-Diagramms für das System. Im Gegensatz zum Build-Parsing, das eine DAG bildet, sollte das Diagramm ungerichtet sein, da es an jeder geänderten Datei interessiert ist, die Code enthält, der indirekt ausgeführt werden kann *. Führen Sie den Integrationstest nur dann erneut aus, wenn sich eine der Dateien im Diagramm für den gewünschten Integrationstest geändert hat. Selbst für Millionen von Codezeilen war es einfach, dieses Parsen in weniger als einer Minute durchzuführen. Wenn Sie andere Dateien als den Quellcode haben, die sich auf einen Integrationstest auswirken können, wie Inhaltsdateien, können Sie möglicherweise Metadaten in einen Kommentar im Quellcode schreiben, der die Abhängigkeiten in den Integrationstests angibt. Sollten sich diese externen Dateien ändern, werden die Tests ebenfalls geändert wieder laufen lassen.

* Wenn test.c beispielsweise foo.h enthält, was auch in foo.c enthalten ist, sollte eine Änderung in test.c, foo.h oder foo.c den integrierten Test als einen neuen Lauf erfordernd markieren.

Das Programmieren und Testen kann einen oder zwei Tage in Anspruch nehmen, insbesondere in der formalen Umgebung, aber ich denke, es sollte auch für Integrationstests funktionieren, und es lohnt sich, wenn Sie keine andere Wahl haben, als im Stundenbereich auf Builds zu warten zu beenden (entweder aufgrund des Bau- oder Test- oder Verpackungsprozesses oder was auch immer). Das kann dazu führen, dass in nur wenigen Monaten so viele Mannstunden verloren gehen, dass die Zeit, die für die Erstellung einer solchen proprietären Lösung benötigt wird, um ein Vielfaches verkürzt wird. Außerdem wird die Energie des Teams vernichtet und der durch Konflikte verursachte Stress bei größeren Zusammenschlüssen verringert häufig als Folge der Zeitverschwendung warten. Es ist nur schlecht für das gesamte Team, wenn sie einen großen Teil ihrer Zeit damit verbringen, auf Dinge zu warten.Alles , was bei jeder kleinen Änderung neu aufgebaut / neu gestartet / neu verpackt werden muss.


quelle
3

Klingt so, als hätten Sie viel zu viele Integrationstests. Rückruf Testpyramide . Integrationstests gehören in die Mitte.

Als Beispiel ein Repository mit Verfahren übernehmen set(key,object), get(key). Dieses Repository wird in Ihrer gesamten Codebasis häufig verwendet. Alle von diesem Repository abhängigen Methoden werden mit einem gefälschten Repository getestet. Jetzt brauchen Sie nur noch zwei Integrationstests, einen für set und einen für get.

Einige dieser Integrationstests könnten wahrscheinlich in Komponententests umgewandelt werden. Beispielsweise sollten End-to-End-Tests meiner Ansicht nach nur testen, ob die Site mit der richtigen Verbindungszeichenfolge und den richtigen Domänen ordnungsgemäß konfiguriert ist.

Integrationstests sollten prüfen, ob ORM, Repositorys und Warteschlangenabstraktionen korrekt sind. Als Faustregel wird für Integrationstests kein Domänencode benötigt - nur Abstraktionen.

Fast alles andere kann mit Stubbed / Mocked / Faked / In-Mem-Implementierungen auf Abhängigkeiten getestet werden.

Esben Skov Pedersen
quelle
1
Interessante Perspektive. Unsere Integrationstests versuchen nicht, jede Permutation jedes Parameters jedes ReST-Aufrufs zu verifizieren. Das ist aus unserer Sicht kein Integrationstest. Sie führen wichtige End-to-End-Szenarien über die API aus, die wiederum verschiedene Back-End-Stores und andere Systeme betreffen. Damit soll sichergestellt werden, dass bei der Änderung der API ermittelt wird, welche Szenarien berücksichtigt werden müssen (dh nicht mehr wie erwartet funktionieren).
Jezz Santos,
1
Wir haben Integrationstests auf verschiedenen Ebenen der Architektur. In Ihrem Beispiel haben wir Komponententests für die Klassen, die auf den Datenspeicher zugreifen, damit wir wissen, dass sie die richtigen Aufrufe an unseren Datenspeicher vornehmen. Wir haben Integrationstests, um eine Kopie unserer Speicher einzurichten und zu testen, ob sie Daten korrekt lesen und schreiben mit dem Laden. Anschließend verwenden wir diese Datenklassen in einer REST-API, die wir mit Komponententests erstellen, und anschließend Integrationstests, mit denen der Webdienst gestartet und aufgerufen wird, um sicherzustellen, dass die Daten vollständig von hinten nach vorne und umgekehrt übertragen werden. Schlagen Sie vor, dass wir hier zu viele Tests haben?
Jezz Santos
Ich habe meine Antwort als Antwort auf Ihre Kommentare aktualisiert.
Esben Skov Pedersen
2

Nach meiner Erfahrung in einer agilen oder DevOps-Umgebung, in der Pipelines für die kontinuierliche Lieferung üblich sind, sollten Integrationstests durchgeführt werden, sobald jedes Modul fertiggestellt oder angepasst ist. In vielen Continuous-Delivery-Pipeline-Umgebungen ist es beispielsweise nicht ungewöhnlich, dass pro Entwickler und Tag mehrere Code-Bereitstellungen durchgeführt werden. Das Ausführen einer kurzen Reihe von Integrationstests am Ende jeder Entwicklungsphase vor der Bereitstellung sollte eine Standardpraxis in dieser Art von Umgebung sein. Weitere Informationen finden Sie in der praktischen Anleitung zum Testen in DevOps , die von Katrina Clokie verfasst wurde.

Um auf diese Weise effizient zu testen, muss die neue Komponente entweder mit vorhandenen, fertigen Modulen in einer dedizierten Testumgebung oder mit Stubs und Treibern getestet werden. Abhängig von Ihren Anforderungen ist es im Allgemeinen eine gute Idee, eine Bibliothek mit Stubs und Treibern für jedes Anwendungsmodul in einem Ordner oder einer Bibliothek zu speichern, um eine schnelle, sich wiederholende Verwendung von Integrationstests zu ermöglichen. Wenn Sie die Stubs und Treiber so organisieren, können Sie iterative Änderungen problemlos durchführen, sie auf dem neuesten Stand halten und optimale Ergebnisse erzielen, um Ihre laufenden Testanforderungen zu erfüllen.

Eine weitere in Betracht zu ziehende Option ist eine ursprünglich um 2002 entwickelte Lösung namens Service Virtualization. Auf diese Weise wird eine virtuelle Umgebung erstellt, in der die Modulinteraktion mit vorhandenen Ressourcen zu Testzwecken in einem komplexen Unternehmens-DevOps oder in der agilen Umgebung simuliert wird.

Dieser Artikel kann hilfreich sein, um zu verstehen, wie Integrationstests im Unternehmen durchgeführt werden

Dan
quelle
Dies kann zwar funktionieren (wenn das System in solche Module aufgeteilt werden kann, aber nicht in alle Produkte) - es war vor einiger Zeit die Norm, verzögert jedoch die Integration und verliert somit alle Vorteile von CI / CD. Irgendwie kontraproduktiv, meinst du nicht auch? Bei solchen Integrationstests entdeckte Probleme können nicht einfach und schnell einem bestimmten Commit zugeordnet werden. Daher sind umfassende Untersuchungen von Grund auf erforderlich, genau wie Fehler aus der Produktion (und Sie wissen, wie viel teurer diese sind, um sie zu beheben).
Dan Cornilescu
1

Haben Sie jeden Test gemessen, um zu sehen, wo die Zeit genommen wird? Und dann die Leistung der Codebasis gemessen, wenn es ein besonders langsames Bit gibt. Ist das Gesamtproblem einer der Tests oder der Bereitstellung oder beides?

In der Regel möchten Sie die Auswirkungen des Integrationstests reduzieren, damit die Ausführung bei relativ geringen Änderungen minimiert wird. Anschließend können Sie den vollständigen Test für einen "QA" -Lauf verlassen, den Sie ausführen, wenn die Verzweigung in die nächste Ebene befördert wird. Sie haben also Komponententests für Entwicklungszweige, führen beim Zusammenführen reduzierte Integrationstests durch und führen beim Zusammenführen zu einem Zweig mit Release-Kandidaten einen vollständigen Integrationstest durch.

Dies bedeutet, dass Sie nicht bei jedem Commit alles neu erstellen und neu packen und erneut bereitstellen müssen. Sie können Ihr Setup in der Entwicklungsumgebung so organisieren, dass eine möglichst kostengünstige Bereitstellung durchgeführt wird, wobei Sie darauf vertrauen, dass dies in Ordnung ist. Anstatt eine ganze VM hochzufahren und das gesamte Produkt bereitzustellen, belassen Sie die VM mit der alten Version und kopieren Sie beispielsweise neue Binärdateien (YMMV, je nachdem, was Sie tun müssen).

Für diesen insgesamt optimistischen Ansatz ist noch ein vollständiger Test erforderlich, der jedoch zu einem späteren Zeitpunkt durchgeführt werden kann, wenn der Zeitaufwand geringer ist. (zB können Sie den vollständigen Test einmal in der Nacht ausführen, wenn es Probleme gibt, die der Entwickler am Morgen lösen kann). Dies hat auch den Vorteil, dass das Produkt auf dem Integrations-Rig für die Tests am nächsten Tag aktualisiert wird - es ist möglicherweise veraltet, wenn Entwickler Änderungen vornehmen, jedoch nur bis zu einem Tag.

Wir hatten ein ähnliches Problem beim Ausführen eines sicherheitsbasierten statischen Analysetools. Vollständige Läufe würden Ewigkeiten dauern, daher haben wir es von den Entwickler-Commits zu einem Integrations-Commit verschoben (dh wir hatten ein System, auf dem Entwickler angaben, fertig zu sein, und es wurde zu einem Zweig der Stufe 2 zusammengeführt, in dem weitere Tests durchgeführt wurden, einschließlich perf Wenn dies abgeschlossen war, wurde es zu einer QA-Niederlassung für die Bereitstellung zusammengeführt. Die Idee ist, die regelmäßigen Läufe zu entfernen, die kontinuierlich bei nächtlichen Läufen auftreten würden. Entwickler würden die Ergebnisse am Morgen erhalten und ihre Entwicklung nicht beeinträchtigen Fokus bis später in ihrem Entwicklungszyklus).

gbjbaanb
quelle
1

Zu einem bestimmten Zeitpunkt kann ein vollständiger Satz von Integrationstests viele Stunden in Anspruch nehmen, selbst auf teurer Hardware. Eine der Möglichkeiten besteht darin, die meisten dieser Tests nicht bei jedem Commit, sondern jede Nacht oder im kontinuierlichen Batch-Modus (einmal pro mehrere Commits) auszuführen.

Dies führt jedoch zu einem neuen Problem: Entwickler erhalten kein sofortiges Feedback, und fehlerhafte Builds bleiben möglicherweise unbemerkt. Um dies zu beheben, ist es wichtig, dass sie jederzeit wissen, dass etwas kaputt ist. Erstellen Sie Benachrichtigungs-Tools wie Catlight oder TeamCitys Tray Notifier .

Aber es wird noch ein anderes Problem geben. Selbst wenn der Entwickler feststellt, dass der Build beschädigt ist, beeilt er sich möglicherweise nicht, ihn zu überprüfen. Schließlich überprüft es vielleicht schon jemand anderes, oder?

Aus diesem Grund verfügen diese beiden Tools über die Funktion "Build Investigation". Es wird angezeigt, ob jemand aus dem Entwicklerteam den fehlerhaften Build tatsächlich überprüft und repariert. Entwickler können sich freiwillig melden, um den Build zu überprüfen. Bis dahin wird jeder im Team durch ein rotes Symbol in der Nähe der Uhr verärgert.

Alex
quelle
0

Es hört sich so an, als würde Ihre Codebasis größer, und eine gewisse Codeverwaltung hilft. Wir verwenden Java, also entschuldige mich im Voraus, wenn ich das annehme.

  • Ein großes Projekt muss in kleinere Einzelprojekte zerlegt werden, die in Bibliotheken kompiliert werden. Java-Tools wie Nexus machen dies einfach.
  • Jede Bibliothek sollte eine Schnittstelle implementieren. Dies hilft, die Bibliothek bei Tests auf höherer Ebene auszublenden. Dies ist besonders nützlich, wenn die Bibliothek auf eine Datenbank oder einen externen Datenspeicher (z. B. einen Mainframe) zugreift. In solchen Fällen ist es wahrscheinlich langsam und möglicherweise unmöglich, die Mainframe- oder Datenbankdaten in einen wiederholbaren Zustand zu versetzen.
  • Integrationstests für jede Bibliothek können umfassend sein, müssen jedoch nur ausgeführt werden, wenn eine neue Bibliotheksquelle festgeschrieben wird.
  • Übergeordnete Integrationstests sollten nur die Bibliotheken aufrufen und davon ausgehen, dass sie perfekt sind.

Der Java-Shop, in dem ich arbeite, verwendet diesen Ansatz und wir werden selten gezögert, auf die Ausführung von Integrationstests zu warten.

Kiwiron
quelle
Vielen Dank, aber ich denke, wir haben nicht das gleiche Verständnis für den Zweck und die Anwendung von Integrationstests in diesem Zusammenhang. Sie können Integrationstests mit Komponententests kombinieren.
Jezz Santos
0

Ein anderer möglicher Ansatz in den CI - Pipeline Integrationstests zu halten (oder jede Art von Überprüfungen, baut einschließlich) mit langen Laufzeiten oder der Anforderung begrenzt und / oder teure Ressourcen von den herkömmlichen CI - Systemen wechseln ist , basierend auf post-commit Prüfungen (die anfällig für Staus ) zu einer Basis auf pre-commit Prüfungen.

Anstatt ihre Änderungen direkt in die Filiale zu übertragen, senden die Entwickler sie an ein zentrales automatisiertes Überprüfungssystem, das die Überprüfungen durchführt und:

  • Bei Erfolg werden die Änderungen automatisch in den Zweig übernommen
  • Wenn dies nicht gelingt, werden die jeweiligen Einreicher benachrichtigt, um ihre Änderungen neu zu bewerten

Ein solcher Ansatz ermöglicht das Kombinieren und Testen mehrerer übermittelter Änderungen, wodurch möglicherweise die effektive CI-Überprüfungsgeschwindigkeit um ein Vielfaches erhöht wird.

Ein Beispiel hierfür ist das von OpenStack verwendete Gerrit / Zuul-basierte Gating-System .

Ein anderes ist ApartCI ( Haftungsausschluss - ich bin der Schöpfer und der Gründer des Unternehmens, das es anbietet).

Dan Cornilescu
quelle