
Henry Ford hat einmal gesagt: "Das beste Auto ist ein neues Auto." Deshalb denken wir in der Tinkoff-Unternehmensgruppe über Software-Releases nach. Die Trägheit bei der Bereitstellung von Funktionen und dringenden Korrekturen führt früher oder später zu einer hohen technischen Verschuldung des Kunden und endet meistens mit einer Stagnation des gesamten Projekts.
Es ist keine leichte Aufgabe , einen Indikator für eine hohe Markteinführungszeit bei gleichbleibender Qualität zu gewährleisten. Aus meiner Sicht können Sie nicht sofort Schienen bauen, auf denen Änderungen viele Monate nach dem Start schnell und bequem geliefert werden können. Das Wachstum eines Projekts geht normalerweise mit einer Zunahme der Anzahl der Personen einher, die daran arbeiten. Dies bedeutet, dass es in Ihren Veröffentlichungen zu einer potenziellen Chaosquelle kommt.
Unsere Erfahrung ist kaum als Anleitung für den Erfolg zu betrachten, aber eine Reihe von Ideen schien mir interessant genug, um sie mit Ihnen zu teilen. Fangen wir an.
Der Ausgangspunkt unserer Geschichte ist technisch wie folgt. Das System besteht aus mehreren Diensten, deren Codebasis von etwa 30 Personen durchsucht wird - mehreren Teams, die nach Geschäftsbereichen unterteilt sind, z. B. zur Betreuung von Einzelpersonen und juristischen Personen. Ich werde versuchen, die technischen und architektonischen Details des Projekts zu ignorieren, um mich auf den Veröffentlichungsprozess selbst zu konzentrieren.
Wir arbeiten an Gitflow , daher wird der Artikel in erster Linie für diejenigen interessant sein, die sich für diese bestimmte Versandmethode entschieden haben.
Die Probleme
Das erste Problem, auf das wir gestoßen sind, hängt mit einer unzureichenden Automatisierung von Prozessen zusammen . Die Implementierung aller Release-Aktivitäten in unserem Team ist an die Rolle des Release Managers (RM) gebunden.
Hier sind einige davon:
- Release-Zweige verlassen und Tags erstellen.
- Mit dem Meister verschmelzen und Zweige entwickeln.
- Erstellen und Bereitstellen von Artefakten, die in der Version enthalten sind.
- Kommunikation mit am Prozess beteiligten Spezialisten - zum Beispiel mit QS oder Administratoren.
Diese Routineaufgaben erfordern mit der Erweiterung des Projekts immer mehr Ressourcen (in unserem Fall eine Erhöhung der Anzahl der Services). Der erste Schritt besteht also darin, alles zu automatisieren, was automatisiert werden kann. Wir integrieren uns in das CI / CD-Tool, um Release-Zweige zuzuweisen und zusammenzuführen, Testbuilds zu starten und Artefakte bereitzustellen. Mit dem Task-Tracking-Tool und dem Corporate Messenger können Sie den für den nächsten Schritt verantwortlichen Teilnehmer rechtzeitig benachrichtigen. Ändern Sie beispielsweise den Status der Aufgabe und konfigurieren Sie den Hook zum Senden einer Benachrichtigung.
Gitflow-Automatisierungsjobs Ein Beispiel für eine Benachrichtigung in einem Messenger Der Release-Manager muss potenzielle Konflikte, die sich aus dem Zusammenführen von Zweigen ergeben, weiterhin manuell lösen. Schnelle und häufige Releases sollten jedoch deren Anzahl auf Null reduzieren.
Das nächste Problem ist das Testen .
Eines der Build-Kriterien für uns ist die erfolgreiche Durchführung der Tests. Es ist üblich, Tests in mindestens zwei Typen zu unterteilen: Einheit und Integration.
Mit Unit-Tests können Sie die Richtigkeit der einzelnen Module des Quellcodes des Programms überprüfen. In der Praxis kommt es meistens darauf an, eine oder mehrere Methoden zu überprüfen, die eine offensichtliche logische Verbindung haben.
Integrationstests überprüfen normalerweise die Funktionsfähigkeit einer ganzen Kaskade solcher Module, dh die Funktionsweise eines gesamten Features auf der Clientseite. Wenn beispielsweise eine Restschnittstelle in einer Aufgabe implementiert wurde, überprüfen wir die Funktionsfähigkeit der Autorisierung, die Deserialisierung der Anforderung selbst, die Gültigkeit der übertragenen Felder, die Integration mit anderen Diensten und Datenbanken sowie die Geschäftslogik selbst. Auf den ersten Blick scheinen solche Tests sehr autark zu sein und alle potenziellen Problembereiche abzudecken. Es ist nicht erforderlich zu verstehen, wie jeder einzelne Baustein funktioniert, und die aufgerufene Schnittstelle kapselt die gesamte Logik, um eine einfache Antwort auf die Ausgabe zu erhalten: ob sie funktioniert oder nicht.
Tatsächlich verursachen sie eine Reihe von verzögerten Problemen, hier einige davon:
- Die Teilnahme einer großen Anzahl getesteter Komponenten wirkt sich proportional auf die Montagezeit und die Durchführung solcher Tests aus.
- Das Einkapseln der Testlogik führt häufig dazu, dass es schwierig ist, die Richtigkeit des Testergebnisses zu gewährleisten. Oft passen wir den Test an das Ergebnis an, und noch häufiger entspricht das Ergebnis aufgrund zufälliger Nebenwirkungen den Erwartungen.
- Die Relevanz von Testdaten geht verloren.
- Integrationen mit Systemen von Drittanbietern, insbesondere in Testumgebungen, fallen häufig aus. Dies negiert die Zeit, die für das Laufen aufgewendet wird, da dies nicht immer offensichtlich ist: Dies ist ein vorübergehender Ausfall oder Ausfall, der durch unsere Änderungen verursacht wird.
Für die meisten Probleme wurde bereits eine Lösung gefunden. Wie üblich kommen Lösungen jedoch nicht ohne zusätzliche Einschränkungen oder neue Probleme.
Die richtigen Tests für Sie auszuwählen und richtig umzusetzen, ist eine sehr schwierige Aufgabe. Darüber hinaus ist es wichtig, ein Gleichgewicht zwischen Coverage-Qualität und Build-Geschwindigkeit herzustellen, um Ihre Releases zu optimieren.
In unserem Fall haben wir uns für einen Hybrid entschieden. Wir erhöhen weiterhin alle erforderlichen Komponenten für einen vollständigen Funktionstest und waschen gleichzeitig alle möglichen Integrationen. Um die API-Verträge zu speichern, verwenden wir Pact und überprüfen die Integration in die Datenbank - Testcontainer .
Ein solcher Ansatz zum Schreiben von Tests führte zu einer Lösung des dritten Problems - einer langen Zeit für das manuelle Testen einer Aufgabe . Die Stabilität von Hybridtests hat zu der Idee geführt, einen QS-Ingenieur in der Phase der Festlegung der Aufgabe für die Erstellung von Testfällen zu gewinnen. Dadurch können sie in der Phase der manuellen Tests übersprungen werden. Die Integration mit nützlichen Produkten wie TestRail und Allure ist zu einer Art Brücke zwischen Entwickler und Tester geworden. Es wird ein Vertrag erstellt, dessen Ausführung Schritt für Schritt in dem während der Testmontage erstellten Bericht wiedergegeben wird.
TestRail. Test Build Details TestRail. Vom Entwickler implementierte Testfälle Allure Auto Test Build Report Allure Informationen zu jedem laufenden Test und schrittweise Detaillierung der Ausführung Es bleibt übrig, Berichte mit Ihrem Aufgabenverfolgungstool zu verbinden, um eine transparente Aufgabenverfolgung zu gewährleisten. Eine klare Geschichte reduziert auch die Zeit, die zum Kompilieren und Implementieren von Tests für zukünftige Aufgaben benötigt wird.
Jira. Testfälle, die automatisch an die Aufgabe angehängt werden Auf diese Weise sparen QS-Ingenieure genug Zeit, um sich auf das Testen von Ausnahmefällen und die Integration in andere Systeme zu konzentrieren.
Das letzte Problem hängt damit zusammen. Beim manuellen Testen werden alle Aufgaben aus den Feature-Zweigen zusammengeführt, um eine Bereitstellung auf dem Prüfstand zu entwickeln und zu starten.
Erstens können Sie bei diesem Ansatz nicht über das reine Testen der Funktion sprechen, da parallel dazu die damit verbundenen Änderungen anderer Entwickler in die Entwicklung fallen können.
Zweitens kann sich beim Freigeben des Release-Zweigs herausstellen, dass die Qualitätssicherung keine Zeit hatte, einige der Aufgaben zu testen. Sie haben die Wahl: Setzen Sie die von diesen Aufgaben betroffenen Änderungen zurück oder verlangsamen Sie die Freigabe bis zum Ende des Tests.
Sie müssen die ganze Zeit eine solche Wahl treffen, es sei denn, Sie isolieren Ihre Testumgebung . Es ist wichtig, dass an der zu testenden Komponente keine anderen als die von der Aufgabe vorgenommenen Änderungen vorgenommen werden. In unserem Fall müssen wir in der Lage sein, einen oder mehrere Dienste aufzunehmen, deren Zweige Änderungen erfahren haben, und das Routing innerhalb des Clusters zu verwalten, indem nur die von der Qualitätssicherung benötigten Anforderungen an diese Instanzen gesendet werden. Die Aufgabe ist kompliziert, wenn im Cluster bereits Ausgleichsmechanismen verwendet werden, die ebenfalls berücksichtigt werden müssen.
Nachdem wir diese Gelegenheit erkannt hatten, begannen wir, manuelle Tests direkt in separaten Feature-Zweigen durchzuführen: Stellen Sie den erforderlichen Service für die Dauer des Tests bereit und integrieren Sie ihn isoliert in die Gesamtumgebung. Durch das Zusammenführen nur vorgefertigter Aufgaben in den Entwicklungszweig und das Entfernen von Sperren haben wir selbst festgelegt, welche Änderungen in die Version aufgenommen werden sollen und welche nicht.
Es ist erwähnenswert, dass eine solche Lösung für Teams, die Änderungen an fast denselben Dateien vornehmen, wahrscheinlich nicht zu einer Silberkugel wird. In diesem Fall ist die Speicherung von Features umgekehrt proportional zur Anzahl der Konflikte, die während der Fusion auftreten. In der Praxis kommt dies bei relativ häufigen Veröffentlichungen in einem Team mit fünfzig Entwicklern äußerst selten vor.
Anstelle von Ausgabe
Zusammenfassend können wir die wichtigsten Ansätze identifizieren, die bei der Beschleunigung von Releases helfen können:
- Automatisierung von Routineoperationen.
- Transparenz der Prozesse für alle Beteiligten.
- Das notwendige Gleichgewicht zwischen Geschwindigkeit und Qualität beim Schreiben automatisierter Tests.
- Reduzierte Zeit für manuelle Tests.
- Isolierung der Umgebung zum Testen.
Es ist wichtig zu verstehen, dass es sich bei der Auswahl verschiedener Ansätze, Prinzipien und Strategien immer lohnt, vom Kontext Ihres Problems auszugehen. Es gibt viele ebenso zuverlässige und ausgefeiltere Möglichkeiten, um die Lieferung Ihrer Software an den Kunden zu beschleunigen. Der Versuch, auf neu auftretende Schwierigkeiten zu reagieren, hat zu den oben beschriebenen Schlussfolgerungen geführt. Für uns waren sie der erste Schritt in Richtung eines mutigeren Ansatzes zur Veröffentlichung von Veröffentlichungen .