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]