Wie kann man den Kofferraum stabil halten, wenn die Tests lange dauern?

9

Wir haben drei Testsuiten:

  • Eine "kleine" Suite, deren Betrieb nur ein paar Stunden dauert
  • Eine "mittlere" Suite, die mehrere Stunden dauert und normalerweise jede Nacht (jede Nacht) ausgeführt wird.
  • Eine "große" Suite, deren Ausführung eine Woche + dauert

Wir haben auch einige kürzere Testsuiten, aber ich konzentriere mich hier nicht darauf.

Die aktuelle Methode besteht darin, die kleine Suite vor jedem Commit für den Trunk auszuführen. Dann wird die mittlere Suite jede Nacht ausgeführt, und wenn sich am Morgen herausstellte, dass sie fehlgeschlagen ist, versuchen wir zu isolieren, welche der gestrigen Commits schuld waren, diese Commits zurückzusetzen und die Tests erneut zu versuchen. Ein ähnlicher Vorgang wird für die große Suite nur wöchentlich statt nachts durchgeführt.

Leider fällt die Medium Suite ziemlich häufig aus. Das bedeutet, dass der Kofferraum oft instabil ist, was äußerst ärgerlich ist, wenn Sie Änderungen vornehmen und testen möchten. Es ist ärgerlich, denn wenn ich aus dem Kofferraum auschecke, kann ich nicht sicher wissen, ob es stabil ist, und wenn ein Test fehlschlägt, kann ich nicht sicher wissen, ob es meine Schuld ist oder nicht.

Meine Frage ist, gibt es eine bekannte Methode, um mit solchen Situationen so umzugehen, dass der Kofferraum immer in Topform bleibt? zB "Commit in einen speziellen Precommit-Zweig, der dann den Trunk jedes Mal regelmäßig aktualisiert, wenn die Nacht vergeht".

Und spielt es eine Rolle, ob es sich um ein zentrales Versionsverwaltungssystem wie SVN oder ein verteiltes wie git handelt?

Übrigens bin ich ein Junior-Entwickler mit einer eingeschränkten Fähigkeit, Dinge zu ändern. Ich versuche nur zu verstehen, ob es einen Weg gibt, mit diesen Schmerzen umzugehen, die ich erlebe.

Eiche
quelle
6
Ich habe keine Ahnung, an welcher Software Sie arbeiten, aber eine kleine Testsuite, deren Ausführung Stunden dauert, ist eine WTF. Wenn sie schneller laufen würden, wäre dies einfacher, keine Möglichkeit, Ihre Tests zu rationalisieren?
Benjamin Bannier
2
Was ist so "extrem nervig" daran, dass der Kofferraum instabil ist? Ich weiß nicht, ob Sie es wissen, aber eine der beliebtesten Verzweigungsstrategien heißt sogar instabiler Stamm
Mücke
1
Es gibt viele Möglichkeiten, eine Testsuite zu optimieren (wie bei jeder anderen Software). Ich habe keine Ahnung, warum Ihre so lange dauert, aber Sie können möglicherweise einen Teil der Testumgebung wiederverwenden oder beim Ausführen einfach bessere Algorithmen / Datenstrukturen verwenden (Profiling hilft). Es kann auch sein, dass sich niemand die Zeit genommen hat, repräsentative Proben zu identifizieren , und Sie einfach jede mögliche Eingabe / Ausgabe anhand einer Referenz testen. Möglicherweise können Sie mit Ihrem Buildsystem Codetest-Abhängigkeiten codieren, sodass Sie nicht den gesamten Satz ausführen müssen. Und ich weiß, das war nicht deine Frage, deshalb habe ich es zu einem Kommentar gemacht, nicht zu einer Antwort.
Benjamin Bannier
1
... hmm, Ihre bessere Option verbessert wahrscheinlich die Tests und die Anwendungsprotokollierung, sodass Sie den Fehlergrund leichter finden können. Auf diese Weise müsste man die Ursache des Fehlers finden und beheben, anstatt Anstrengungen für "Detektivuntersuchungen" zu verschwenden, um herauszufinden, wer, wann und warum eine bestimmte Codezeile geändert wurde ...
Mücke
1
@honk Einige Tests dauern nur lange. Ich arbeite für ein Unternehmen, das Datenerfassungsgeräte herstellt, und unser "teilweiser" Testlauf dauert ungefähr eine Stunde. Die Tests müssen verschiedene Arten von Messungen durchführen, und das braucht nur Zeit.
Velociraptors

Antworten:

1

Die einzige Möglichkeit, die Grundursache für die Instabilität zu beheben, besteht darin, den Code zu entkoppeln, damit Änderungen isolierter sind, wie andere Antworten vorgeschlagen haben.

Wenn Sie als einzelner Entwickler jedoch einen stabileren Build für Ihre persönliche Arbeit wünschen, ist dies relativ einfach zu lösen. Anstatt an der Spitze zu arbeiten, ziehen Sie nur den letzten Build, der die Testsuite über Nacht bestanden hat, in Ihren Arbeitsbaum. Wenn Sie für jede Änderung Feature-Zweige erstellen können, verzweigen Sie vom letzten stabilen Build.

Ja, Ihr Baum wird ein paar Tage zurückliegen, aber die meiste Zeit spielt das keine Rolle. Führen Sie Ihre Arbeit gegen den stabilen Build durch, damit Sie wissen, dass Ihre Änderungen alle Tests abgebrochen haben. Aktualisieren Sie dann vor dem Einchecken auf den neuesten Stand und führen Sie Ihre normale Integration durch. Nachdem Sie eingecheckt haben, kehren Sie zum letzten stabilen Build zurück.

Sie müssen immer noch die unordentliche Integrationsarbeit erledigen, aber was mir an dieser Methode gefällt, ist, dass sie die Integrationsarbeit auf eine für mich günstigere Zeit isoliert und mir eine stabile Codebasis für die Entwicklung bietet, wenn sie nicht bequem ist. Ich habe eine viel bessere Idee, wenn es meine Änderungen sind, die wahrscheinlich den Build im Vergleich zu denen anderer gebrochen haben.

Karl Bielefeldt
quelle
1
-1 Arbeiten in Filialen ist eine praktikable Option, aber die Empfehlung ohne Testvorschlag kann mehr schaden als nützen. Nur Tests können zeigen, ob es für ein bestimmtes Projekt machbar ist oder nicht. Zum Beispiel in einem Projekt, das ich vor ungefähr 2 Jahren durchgeführt habe, hat ein solcher Test gezeigt, dass das Arbeiten in Zweigen ~ 7x mal mehr Aufwand erfordert als im instabilen Stamm
Mücke
Danke Karl! Ich hatte zwar nicht gehofft, dies zu lernen, aber dies ist ein sehr praktischer Ansatz, der mir helfen könnte, das vorliegende Problem zu lösen. Und ich stimme zu, dass ein paar Tage hinter dem Kofferraum nur selten Integrationsprobleme verursachen.
Eiche
12

Ich weiß, dass Sie versuchen, dies zu vermeiden, aber die wirkliche Erkenntnis besteht darin, dass etwas ernsthaft mit Ihrer Codebasis nicht stimmt: Sie müssen eine vollständige Testsuite ausführen, die eine Woche dauert, um sicherzugehen, dass Ihr Code stabil ist!

Der vorteilhafteste Weg, um dieses Problem zu beheben, besteht darin, Ihre Codebasis und Tests in (unabhängige) Untereinheiten aufzuteilen.
Dies hat enorme Vorteile:

  • Die Tests für jede dieser Einheiten laufen schneller (es gibt einfach weniger) und sie brechen nicht, wenn in einer der unabhängigen oder nachgeschalteten Einheiten etwas schief geht.
  • Ein fehlgeschlagener Test wird auf eine bestimmte Einheit festgelegt, wodurch es viel einfacher wird, die Ursache des Problems zu finden.
  • Sie können die VCS-Positionen der verschiedenen Einheiten trennen, sodass Ihr "stabiler" Zweig eine Auswahl der neuesten erfolgreich getesteten Builds jeder Einheit sein kann, sodass ein oder zwei defekte Einheiten Ihre "stabile" Version nicht destabilisieren .

Auf der anderen Seite wird die Verwaltung Ihrer VCS-Struktur komplizierter, aber nach einer vollen Woche für Ihren vollständigen Test können Sie den Schmerz ertragen!

Ich empfehle weiterhin, in irgendeiner Form eine Strategie für "stabile" und "Entwicklungs" -Zweige zu verwenden, aber es gibt viele Möglichkeiten, dies zu tun, und Sie können diejenige auswählen, die für Ihr Unternehmen am besten geeignet ist (Meta-Repositorys mit festen Revisionen, auf die verwiesen wird) separate Repositorys für jede Einheit, ein stabiler Zweig und ein Entwicklungszweig, Feature-Zweige ....)

Joris Timmermans
quelle
1
Ich habe nie gesagt, dass der große Test ein Atomtest ist, es ist eine Testsuite . Wenn ein einzelner Entwickler eine Änderung an Element X vornimmt, führt er die für X relevanten Tests aus - unabhängig davon, aus welcher Testsuite er stammt. Dies ist zusätzlich zu dem wöchentlichen Test, der durchgeführt wird, um sicherzustellen, dass eine Änderung an einem Ort nicht unerwartet Auswirkungen auf einen anderen Ort hat. Sie machen jedoch einen interessanten Punkt geltend, dass zumindest die Trennung der Dinge auf diese Weise dazu beiträgt, die Tests für bestimmte Module zu beschleunigen und gleichzeitig das Risiko in etwa auf dem gleichen Niveau zu halten.
Eiche
2
@oak - In gewisser Weise ist die Suite atomar, wenn sie nur ausgeführt wird. Nur so können Sie sicher sein, dass der Code stabil ist, aber Sie machen einen guten Punkt, also habe ich meine Antwort bearbeitet.
Joris Timmermans
4
Wir haben riesige Testsuiten für unsere Compiler, von denen einige mehrere Tage dauern, und ich denke nicht, dass dies für Software so komplex ist wie ein C ++ - Compiler. Es ist nicht so, dass die Suite definiert, was als "stabil" anzusehen ist, sondern dass es Millionen verschiedener Eckpunkte der Codegenerierung gibt, die nicht jeden Tag getestet werden können.
JesperE
1
@JesperE - das ist verständlich, wenn die riesige Testsuite nicht "stabil" definiert, sondern ein gigantischer Vernunfttest ist. Ich würde nicht erwarten, dass die vollständige Suite (oder sogar die mittlere Suite) sehr oft ausfällt.
Joris Timmermans
1

Für SVN weiß ich nichts über so etwas wie "Pre-Commit". Ich denke, es ist wahrscheinlich, dass Commits und Rollbacks erzeugt werden, wenn der Test fehlschlägt. Wie doc-brown sagt, besteht die einzige Möglichkeit darin, einen temporären Zweig festzuschreiben und ihn später mit dem Trunk zusammenzuführen.

Mit einem verteilten wie git oder mercurial denke ich, dass es möglich wäre. Verwenden eines "Test" -Repositorys und eines "stabilen" Repositorys. Sie drücken auf den Testvertreter, testen ihn jeden Abend und wenn alles gut läuft, drücken Sie vom Test in den Stall. Andernfalls setzen Sie den Testmitarbeiter zurück. Ich bin mir ein bisschen unsicher, wie der Versionsverlauf aussehen würde, wenn Sie vom Testen zum Stall wechseln, aber ich denke, es ist möglich, das kaputte Rollback-Zeug dabei auszuschließen. Ein bisschen experimentieren wäre am sichersten.

Eine Alternative wäre auch, jeden Abend den lokalen Kofferraum jeder Person zu testen. Dann dürfen die Personen mit bestandenen Tests es am Morgen auf den zentralen Server übertragen.

dagnelies
quelle
1

IMHO hat dies nichts mit dem von Ihnen verwendeten VCS zu tun. Die Verwendung eines "zu testenden" Zweigs kann eine Lösung sein, die auch mit zentralisiertem oder verteiltem VCS realisiert werden kann. Aber ehrlich gesagt denke ich, dass das Beste in Ihrer Situation darin besteht, die mittlere Testsuite so zu optimieren (anscheinend enthält sie die wichtigsten Tests), dass sie viel schneller ausgeführt wird, sodass Sie sie für das Pre-Commit-to-Trunk verwenden können Tests, so wie Sie es jetzt mit Ihrer "kleinen Suite" tun.

Doc Brown
quelle
Ich frage hier hauptsächlich nach der Methodik - dh gibt es einen gemeinsamen Weg, um mit einer solchen Situation umzugehen? Nehmen wir zumindest für diese Diskussion an, dass die Tests nicht über das hinaus optimiert werden können, was sie bereits sind.
Eiche
@ Oak: Jemand hier (Sie?) Hat meine Antwort abgelehnt - aber manchmal sind die Dinge, die Sie nicht hören möchten, die einzigen Dinge, die helfen. Wie Sie in der Diskussion unter Ihrer Frage sehen, haben andere dasselbe vorgeschlagen, sodass mein Vorschlag überhaupt nicht so schlecht zu sein scheint.
Doc Brown
+1, das ist die richtige Antwort. Die eigentliche Frage des OP lautet: "Hilfe, ich ertrinke im Mist. Mit welcher Methode kann ich mir selbst helfen?" und die Antwort ist, dass Methodik nicht das ist, worüber Sie sich Sorgen machen sollten.
MrFox
1

Die fehlgeschlagenen Medientests: Stimmt es, dass meistens dieselben Tests fehlschlagen?

Wenn es einen Fehler gibt, gibt es immer die gleichen verwandten Tests, die fehlschlagen?

Wenn dies zutrifft: Möglicherweise können Sie einige häufig fehlgeschlagene mittlere Tests (ein Test für jede Fehlerklasse) selektiv auswählen und innerhalb des kleinen Satzes ausführen.

Sind die meisten Tests Integrationstests, die eine echte Datenbank verwenden? Wenn ja, ist es möglich, sie durch eine Unittest zu ersetzen, die eine verspottete Datenbank hat?

k3b
quelle
1

Sie müssen Ihre Tests beschleunigen, es gibt keine andere Möglichkeit, diesen Kreis zu quadrieren.

Betrachten Sie das Problem: Sie möchten sicher sein, dass Sie beim Auschecken über Arbeitscode verfügen. Natürlich können Sie Commits verzögern und Verzweigungen bis vor der Veröffentlichung durchführen, aber dies verzögert nur den Beginn des Problems bis zur Integration. Müssen Sie die einwöchige Suite nach jeder Zusammenführung wie in ausführen? Methodik ist nicht die Lösung, die Lösung ist rein technisch.

Folgendes schlage ich vor:

1) Machen Sie die Tests so atmosphärisch wie möglich und maximieren Sie die Wiederverwendung in der Umgebung.

2) Holen Sie sich eine Testsuite-Farm, um sie auszuführen. Wenn Sie anstelle von 8 großen Modulen 50 haben, können Sie eine Reihe von Amazon EC2-Spotinstanzen hochfahren und die gesamte Suite parallel ausführen. Ich bin mir sicher, dass dies etwas Geld kosten wird, aber es wird enorm viel Entwicklerzeit sparen.

MrFox
quelle
0

Das Wichtigste, was Sie in Ihrer Frage für selbstverständlich halten, ist, dass alle Commits Tests bestehen müssen. Dies ist zwar eine nette Regel und scheint sinnvoll zu sein, aber manchmal ist sie nicht praktikabel. Ihr Fall ist ein Beispiel (obwohl MadKeithV einen Punkt macht), und ich kann mir vorstellen, einen VCS-Zweig so makellos zu halten, dass es schwierig sein könnte, wenn die Entwickler nicht ausreichend zusammenarbeiten.

In Wirklichkeit möchten Sie irgendwie wissen, welche Commits bestanden oder nicht bestanden wurden. Ein "Pre-Commit-Zweig", wie Sie vorgeschlagen haben, würde funktionieren, aber dies erfordert möglicherweise zusätzlichen Aufwand von Entwicklern, wenn sie Commits durchführen, die möglicherweise schwer zu verkaufen sind.

Ein ähnlicher Ansatz, der einfacher sein könnte, besteht darin, den Kofferraum zu verlassen, damit die Leute nach Belieben brechen können, und einen Zweig für Commits zu haben, die nicht kaputt sind. Ein automatisiertes Skript kann Commits durchlaufen, wenn sie an den Trunk gesendet werden, die Tests für sie ausführen und sie dem Zweig hinzufügen, wenn sie erfolgreich sind.

Oder Sie könnten absurd simpel sein und ein Skript haben, das die übergebenen Commits in einer Textdatei auflistet (die möglicherweise selbst versioniert ist oder nicht).

Oder Sie haben ein Batch-System, das Anforderungen für zu testende Zweige / Revisionen (von einer beliebigen Stelle im Baum) akzeptiert, diese testet und an den Trunk (oder einen anderen Zweig) festschreibt, wenn sie erfolgreich sind.

Michael Slade
quelle