Sind Scrum und eine stabile Entwicklung ein Widerspruch?

11

Ich bin Teil einer Entwicklungsgruppe mit 5 Teams, insgesamt etwa 40 Entwicklern. Wir folgen der Scrum-Methode mit 3-wöchigen Sprints. Wir haben ein kontinuierliches Integrations-Setup (Jenkins), bei dem eine Build-Pipeline mehrere Stunden dauert (aufgrund umfangreicher automatisierter Tests). Grundsätzlich funktioniert der Entwicklungsprozess gut.

Wir stellen jedoch fest, dass unser Build nach einigen Tagen in einem neuen Sprint oft instabil wird und bis zum Ende des Sprint-Endes "Commit Stop" wackelig bleibt. Dies hat den nachteiligen Effekt, dass Build-Schritte weit unten in der Pipeline, insbesondere UI- / Webtests, mehrere Tage lang nicht ausgeführt werden (da sie nur bei einem "grünen" Build ausgelöst werden). Folglich werden neu eingeführte Fehler oft erst sehr spät im Sprint erkannt.

  • Jedes Commit wird anhand einer Reihe grundlegender Tests überprüft. Nach der Überprüfung wird die Änderung nach einer Codeüberprüfung (Gerrit) an den Master weitergeleitet.
  • Grundlegende Unit-Tests werden alle 30 Minuten mit einer Dauer von weniger als 10 Minuten ausgeführt
  • Integrationstests werden alle 2 Stunden und eine Dauer von 1 Stunde ausgeführt
  • UI- / Webtests werden bei erfolgreichen Integrationstests ausgeführt und dauern mehrere Stunden

Abhängig davon, wer während des Sprints für die Build-Stabilität verantwortlich ist (diese Verantwortung wird pro Sprint weitergegeben), kann es zu Zwischen-Ad-hoc-Commit-Stopps kommen, um den Build wieder stabil zu machen.

Also wollen wir:

  1. Unsere Entwicklerteams entwickeln und übernehmen Änderungen während eines Sprints ungehindert
  2. Unser Erstellungsprozess wird abgebrochen, wenn ein Erstellungsschritt fehlschlägt, da nachfolgende Erstellungsergebnisse wenig Bedeutung haben
  3. Unser Erstellungsprozess, um den Entwicklern rechtzeitig Qualitätsfeedback zu geben

Angesichts von (2) scheinen sich die Punkte (1) und (3) zu widersprechen. Hat jemand eine gute Praxis, um damit umzugehen?

( Wir lockern derzeit Punkt (2) und erlauben die Fortsetzung des Builds auch bei fehlgeschlagenen Build-Schritten. Ich habe noch kein Feedback, wie sich dies auf unsere Qualität auswirkt. )

Danke, Simon

Simon
quelle
3
Ich würde sagen, wenn ein Build benötigt wird several hours, ist das das eigentliche Problem. Dies bedeutet, dass die kombinierte Lösung zu groß und zu breit ist. Sie sollten versuchen, die Lösung zu komponieren und dann kleine Codestücke als Pakete haben (auf die eine oder andere Weise in allen wichtigen Sprachen auf allen Plattformen verfügbar). Änderungen würden sich also nur auf die Komponenten auswirken und werden viel schneller erkannt. Der vollständige Build fügt im Wesentlichen bereits kombinierte Komponenten zusammen und ist auch schneller. Sie würden dann möglicherweise nur einige Tests ausführen, um sicherzustellen, dass die richtigen Komponenten aufgelöst wurden.
Zaitsman
Ist Ihre Build-Umgebung lokal oder cloudbasiert?
Lauri Laanti
@LauriLaanti, unsere Build-Umgebung ist vor Ort, 1 Jenkins-Instanz mit 3 Slaves.
Simon

Antworten:

7

Zunächst einige Grundprinzipien: - Wichtige Änderungen sollten immer an einem Feature-Zweig in Ihrem VCS vorgenommen werden. - Feature-Zweige sollten alle Tests bestehen, bevor sie in den Trunk integriert werden. Hinzugefügt - Commits sollten immer bauen - Ein gebrochener Build erfordert sofortige Aktion aus der Committer & / oder dem Rest des Teams. - Ein fehlgeschlagener Test sollte die verbleibenden Tests nur abbrechen, wenn es sich um einen kritischen Test handelt.

Wenn Sie als Team diese Praktiken befolgen und durchsetzen, z. B.: "Name & Schande", wenn der Build beschädigt ist, sollten Sie bereit sein, da sich alle Commits, die den Build beschädigen könnten, in einem Feature-Zweig befinden. Andere Commits, die den Build unterbrechen, müssen sofort behoben werden, und dann erhalten Sie Ihre nachgelagerten Testergebnisse.

Sie können auch einen automatischen Test des neuesten "erfolgreichen" Builds (nicht unbedingt einen, der die Integrationstests besteht) für die UI / Web-Tests als nächtlichen Bericht hinzufügen .

Steve Barnes
quelle
3
Eine gute Praxis, die hier hinzugefügt werden sollte, ist, dass Feature-Zweige alle Tests bestehen sollten, bevor sie zur Hauptlinie zusammengeführt werden
Bart van Ingen Schenau
@BartvanIngenSchenau - guter Punkt hinzugefügt!
Steve Barnes
@SteveBarnes, danke für die Eingabe. Ein Commit in Gerrit befindet sich immer in einem Zweig und wird nur bei Erfolg zusammengeführt (mein erster Punkt im Erstellungsprozess). Danach beginnt das Problem. Da 30 Entwickler mehrmals pro Tag Änderungen vornehmen, müssen wir frühzeitig zusammenführen und dann überprüfen. Es ist ein sofortiges Eingreifen nach einem gebrochen zu bauen, aber als die Zeit zwischen begehen und Build - Feedback ist 2 Stunden, gibt es mehrere andere Commits in der Zwischenzeit sein wird. Möglicherweise den nächsten Build brechen.
Simon
@ Simon Der Sinn des "Namens & der Schande" ist es, Ihre Entwickler dazu zu bringen, keinen kaputten Code mehr zu begehen! Auf den meisten Systemen ist es möglich, einen Testbuild in kurzer Zeit mit Tools wie ant, make, scons usw. durchzuführen. Wenn Ihr Projekt gut strukturiert ist, erlauben die meisten Sprachen teilweise Neuerstellungen, um zu testen, ob Dinge erstellt werden (vollständig / sauber) Builds müssen natürlich noch gemacht werden).
Steve Barnes
8

Hat nichts mit Scrum zu tun. Ihr Build sollte unabhängig davon kontinuierlich stabil sein.

Niemand sollte etwas einchecken, es sei denn, er hat einen lokalen Build durchgeführt und die Komponententests lokal ausgeführt (und beide haben natürlich bestanden). Ihr lokaler Erstellungs- und Testprozess sollte empfindlich auf Änderungen reagieren und kann Tests für Code überspringen, der sich nicht geändert hat.

Jeder, der etwas einführt, das dazu führt, dass der Build fehlschlägt oder ein Komponententest fehlschlägt, sollte öffentlich beschämt werden . Wenn der Build kaputt ist, muss er sofort repariert werden.

John Wu
quelle
2
Einerseits sollte betont werden, dass die Stabilität des Aufbaus in der Verantwortung aller liegt. Auf der anderen Seite würde ich von öffentlichem Scham abraten, da (1) erfahrenere Teammitglieder eine größere Verantwortung dafür haben, Junior-Mitgliedern dabei zu helfen, Build-Stabilität zu erreichen (durch Codeüberprüfung, Paarprogrammierung oder einfache enge Zusammenarbeit vor einem Commit oder durch (2) Scham nimmt die psychologische Sicherheit des Teams .
Rwong
1
Wenn die Leute nicht beschämt werden wollen, sollten sie den Build nicht brechen. Es ist nicht so, dass dies ein unangemessen hoher Standard ist. Wenn Sie Entwickler haben, die es nicht hacken können, lassen Sie sie ihren eigenen Zweig spielen, bis sie herausfinden, wie sie die kritischen Commons des Teams nicht brechen können. (Davon abgesehen sollte jede tatsächliche Scham gut schmecken).
John Wu
In unserem Prozess ist jedes Commit verzweigt (in Gerrit) und muss vor dem Zusammenführen mit dem Master eine Reihe grundlegender Tests bestehen. Diese grundlegenden Tests können nicht eine Stunde lang ausgeführt werden, da wir die Codeüberprüfung durchführen und schnell zusammenführen möchten. Es ist nach der Zusammenführung, wo das Problem beginnt, siehe meinen Kommentar zu @SteveBarnes
Simon
6

Ihr Problem scheint zu sein, dass die Ausführung von Tests zu lange dauert. Glücklicherweise hat uns Moores Gesetz eine Lösung für dieses Problem geliefert. Heutzutage können High-End-Server-CPUs leicht über 10 Kerne (und über 10 HyperThreads) haben. In einem Computer können mehrere solcher CPUs vorhanden sein.

Wenn ich Tests hätte, die so lange dauern, würde ich das Problem mit mehr Hardware lösen. Ich würde einen High-End-Server kaufen und dann die Tests parallelisieren, damit die Tests alle CPU-Kerne voll ausnutzen. Wenn Ihre Tests heute Single-Threaded sind, werden die Tests durch die Verwendung von 10 Kernen und 10 HyperThreds wahrscheinlich 15-mal schneller ausgeführt. Dies bedeutet natürlich, dass sie auch das 15-fache des Speichers verwenden, sodass der Computer über genügend RAM verfügen muss.

Die mehreren Stunden werden also zu 10 bis 30 Minuten.

Sie haben nicht angegeben, wie viel Zeit der Build benötigt, aber Standard-Build-Tools wie make ermöglichen das Parallelisieren auch des Builds. Wenn Sie Ihre Komponententests parallelisieren und ein typischer Entwicklercomputer über 4 Kerne und 4 HyperThreads verfügt, werden die Unit-Tests in weniger als 10 Minuten zu weniger als 2 Minuten. Vielleicht könnten Sie also eine Richtlinie durchsetzen, nach der jeder die Komponententests vor dem Festschreiben ausführen sollte?

Über Testfehler Beenden weiterer Tests: Tun Sie dies nicht auf dem Build-Server! Sie möchten so viele Informationen wie möglich über den Fehler erhalten, und weitere Tests können etwas Wichtiges ergeben. Wenn der Build selbst fehlgeschlagen ist, können Sie natürlich keine Komponententests ausführen. Wenn der Entwickler Komponententests auf seinem eigenen Computer ausführt, möchten Sie möglicherweise beim ersten Fehler abbrechen.

Ich sehe keinen Zusammenhang zwischen Scrum und Ihren Problemen. Die Probleme können bei jedem Entwicklungsprozess auftreten.

juhist
quelle
Ich stimme zu, mit einem schnelleren Build wären die Dinge viel einfacher. Unser TechTeam hat Tage damit verbracht, die Geschwindigkeit unseres Erstellungsprozesses zu verbessern, sonst würden wir Tage statt Stunden warten. Diese Rückmeldungsdauer beträgt derzeit ca. 2 Stunden. Ich suche also nach einem Ansatz, der dies als "gegeben" ansieht. (Natürlich versuchen wir ständig, den Build zu beschleunigen. Aber in naher Zukunft werden es 2 Stunden sein)
Simon
Einige Tests können mit parallelem Lauf in Konflikt stehen
deFreitas
Es ist nur möglich, mehr Hardware darauf zu werfen, wenn die Tests so geschrieben sind, dass sie unabhängig voneinander ausgeführt werden können, ohne dass Nebenwirkungen auftreten. Je weiter Sie von der Hardware entfernt sind, desto schwieriger wird dies. Die meisten Entwickler tun dies nicht Wenn ich Ihnen zustimme, würde ich mich zunächst darauf konzentrieren, die Tests richtig zu strukturieren.
c_maker
2

Ist es nicht möglich, mehr Jenkins-Installationen zu haben und die Entwickler eine separate Jenkins-Instanz überprüfen zu lassen?

Ich denke, die beste Lösung besteht darin, den Code alle Tests bestehen zu lassen, bevor er in den Hauptzweig eingecheckt und von der Hauptinstanz von Jenkins kompiliert / getestet wird. Lassen Sie nicht zu, dass Leute Code einchecken, der den Build unterbricht.

Ich checke meinen Code in den Entwicklungszweig ein, prüfe, ob er die Tests besteht, und erstelle eine Pull-Anfrage. Aber Sie könnten natürlich Jenkins einen Feature-Zweig ziehen lassen und diesen testen.

xyious
quelle
1

Punkt (2) scheint der schmerzhafteste Punkt zu sein, deshalb werde ich mich darauf konzentrieren.

Möglicherweise ist es an der Zeit, das Projekt in mehrere Module aufzuteilen.

https://en.wikipedia.org/wiki/Dependency_inversion_principle

A. High-Level-Module sollten nicht von Low-Level-Modulen abhängen. Beides sollte von Abstraktionen abhängen.

B. Abstraktionen sollten nicht von Details abhängen. Details sollten von Abstraktionen abhängen.

Wenn ein Modul nicht erstellt werden kann, kann der Build für andere Module fortgesetzt werden, solange diese anderen Module von einer Schnittstelle abhängen können und der Code, aus dem diese Schnittstelle besteht, erfolgreich erstellt wurde.

Auf diese Weise erhalten Sie Feedback zu anderen Buildfehlern, sodass Sie Zeit haben, mehr als ein defektes Modul zu reparieren, bevor der nächste Build ausgeführt wird.

Im Allgemeinen sind die SOLID-Prinzipien so konzipiert, dass sie sich mit Bibliotheken befassen und Probleme erstellen. Mit anderen Worten - diese Prinzipien sind so konzipiert, dass sie genau die Probleme lösen, mit denen Sie konfrontiert sind.


Als Randnotiz (siehe Antwort von juhist) können Sie den Build nicht schneller laufen lassen (durch Parallelisierung), wenn Sie den Build nicht in separate Module aufteilen.

rwong
quelle
0

Ich denke, Ihrem Team fehlt einer der wichtigsten Grundsätze von Scrum: Fertig, funktionierende Software. Ein PBI sollte erst dann als erledigt markiert werden, wenn es die von Ihrem Team festgelegte Definition of Done erfüllt. Die Definition von "Fertig" ist für jedes Team unterschiedlich, würde aber wahrscheinlich Folgendes beinhalten:

  • Code hat Unit-Tests
  • Unit Test Pass als Teil eines automatisierten Builds
  • Code wurde in main zusammengeführt (und Konflikte wurden gelöst)
  • etc.

Im Wesentlichen passiert also, dass Ihr Team Dinge markiert, die tatsächlich nicht erledigt sind. Das ist ein Problem für sich.

Davon abgesehen läuft es auf eine ordnungsgemäße Verwaltung der Versionskontrolle hinaus. Wenn Sie Git verwenden, werden alle Arbeiten im lokalen Repository des Entwicklers ausgeführt, und es sollte nichts auf die Remote-Website übertragen werden, es sei denn, es ist "erledigt" und möglicherweise freigebbar. Unvollständige Arbeiten sollten niemals in Ihr Haupt-Repository verschoben werden. Wenn der Entwickler an einem längerlebigen Feature-Zweig arbeiten muss und auf Remote zugreifen möchte, um sicherzustellen, dass er seine Arbeit nicht verliert, sollte er an einer Gabel arbeiten, und Sie würden diese Gabel dann in main zusammenführen, wenn die Funktion ist "fertig" und möglicherweise freigebbar - nicht vorher.

Für TFVC ist es etwas komplizierter, weil alles auf "Remote" passiert. Das bedeutet, dass Entwickler immer aus Zweigen heraus arbeiten sollten, es sei denn, es handelt sich um eine schnelle Lösung. Hier gelten jedoch die gleichen Regeln wie bei Git: Unvollständige Software wird nicht festgeschrieben. Zeitraum. Bei einer ordnungsgemäß verwalteten Versionskontrolle sollte "main" immer freigebbar sein. Wenn ein Commit gemacht wurde, das "main" ist, dann machen Sie es nicht richtig.

Chris Pratt
quelle