Um Ihnen einen kleinen Hintergrund zu geben: Ich arbeite für ein Unternehmen mit ungefähr zwölf Ruby on Rails-Entwicklern (+/- Praktikanten). Fernarbeit ist weit verbreitet. Unser Produkt besteht aus zwei Teilen: einem ziemlich dicken Kern und einem dünnen bis zu großen Kundenprojekten, die darauf aufbauen. Kundenprojekte erweitern in der Regel den Kern. Das Überschreiben der wichtigsten Funktionen findet nicht statt. Ich könnte hinzufügen, dass der Kern einige ziemlich schlechte Teile hat, die dringend überarbeitet werden müssen. Es gibt Spezifikationen, aber hauptsächlich für Kundenprojekte. Der schlechteste Teil des Kerns ist ungetestet (nicht so, wie es sein sollte ...).
Die Entwickler sind in zwei Teams aufgeteilt, die für jeden Sprint mit einer oder zwei PO arbeiten. Normalerweise ist ein Kundenprojekt streng mit einem der Teams und POs verbunden.
Jetzt unser Problem: Ziemlich oft brechen wir uns gegenseitig auf. Jemand von Team A erweitert oder überarbeitet das Kernfeature Y, was zu unerwarteten Fehlern bei einem der Kundenprojekte von Team B führt. Meistens werden die Änderungen nicht über die Teams bekannt gegeben, so dass die Bugs fast immer unerwartet auftauchen. Team B, einschließlich der PO, hielt Feature Y für stabil und testete es nicht, bevor es freigegeben wurde, da die Änderungen nicht bekannt waren.
Wie diese Probleme loswerden? Welche Art von Ansagetechnik können Sie mir empfehlen?
Antworten:
Ich würde empfehlen, das Buch Working Effectively with Legacy Code von Michael C. Feathers zu lesen . Es wird erklärt, dass Sie wirklich automatisierte Tests benötigen, wie Sie sie einfach hinzufügen können, wenn Sie sie noch nicht haben und welcher "Code" auf welche Weise umgestaltet werden soll.
Abgesehen davon scheint ein weiteres Kernproblem in Ihrer Situation ein Mangel an Kommunikation zwischen den beiden Teams zu sein. Wie groß sind diese Teams? Arbeiten sie an unterschiedlichen Rückständen?
Es ist fast immer eine schlechte Praxis, Teams entsprechend Ihrer Architektur aufzuteilen. ZB ein Kernteam und ein Nicht-Kernteam. Stattdessen würde ich Teams auf funktionaler Ebene erstellen, jedoch komponentenübergreifend.
quelle
Das ist das Problem. Effizientes Refactoring hängt stark von einer Reihe automatisierter Tests ab. Wenn Sie diese nicht haben, treten die beschriebenen Probleme auf. Dies ist besonders wichtig, wenn Sie eine dynamische Sprache wie Ruby verwenden, bei der es keinen Compiler gibt, der grundlegende Fehler im Zusammenhang mit der Übergabe von Parametern an Methoden abfängt.
quelle
Die vorherigen Antworten, die auf bessere Komponententests hindeuten, sind gut, aber ich bin der Meinung, dass es grundlegendere Probleme geben könnte, die behandelt werden müssen. Sie benötigen klare Schnittstellen für den Zugriff auf den Kerncode aus dem Code für die Kundenprojekte. Auf diese Weise wird der Code des anderen Teams nicht beschädigt, wenn Sie den Kerncode umgestalten, ohne das über die Schnittstellen beobachtete Verhalten zu ändern . Dadurch wird es viel einfacher zu wissen, was "sicher" überarbeitet werden kann und was möglicherweise überarbeitet werden muss.
quelle
Andere Antworten haben wichtige Punkte hervorgehoben (mehr Unit-Tests, Feature-Teams, saubere Schnittstellen zu den Kernkomponenten), aber ich finde, dass ein Punkt fehlt, nämlich die Versionierung.
Wenn Sie das Verhalten Ihres Cores durch Ausführen von Release 1 einfrieren und dieses Release in ein privates Artefaktverwaltungssystem 2 einfügen, kann jedes Kundenprojekt seine Abhängigkeit von Core-Version X deklarieren , und es wird mit dem nächsten Release X nicht beschädigt + 1 .
Die "Ankündigungsrichtlinie" beschränkt sich dann darauf, zu jeder Veröffentlichung eine CHANGES-Datei oder eine Teambesprechung zu haben, um alle Funktionen jeder neuen Kernveröffentlichung anzukündigen.
Außerdem denke ich, dass Sie besser definieren müssen, was "Kern" ist und welche Teilmenge davon "Schlüssel" ist. Sie scheinen (richtig) zu vermeiden, viele Änderungen an "Schlüsselkomponenten" vorzunehmen, aber Sie erlauben häufige Änderungen an "Kern". Um sich auf etwas verlassen zu können, muss man es stabil halten. Wenn etwas nicht stabil ist, nennen Sie es nicht core. Vielleicht könnte ich vorschlagen, es "Hilfskomponenten" zu nennen?
BEARBEITEN : Wenn Sie die Konventionen im Semantic Versioning-System befolgen , muss jede inkompatible Änderung in der Core-API durch eine größere Versionsänderung gekennzeichnet sein . Das heißt, wenn Sie das Verhalten des zuvor vorhandenen Kerns ändern oder etwas entfernen und nicht nur etwas Neues hinzufügen. Mit dieser Konvention wissen Entwickler, dass ein Update von Version 1.1 auf 1.2 sicher ist, aber ein Wechsel von 1.X auf 2.0 ist riskant und muss sorgfältig überprüft werden.
1: Ich denke, dies wird in der Welt von Ruby ein Juwel genannt.
2: Das Äquivalent zu Nexus in Java oder PyPI in Python
quelle
Wie andere Leute bereits sagten, wird eine gute Suite von Komponententests Ihr Problem nicht lösen: Sie werden Probleme beim Zusammenführen von Änderungen haben, selbst wenn jede Team-Testsuite erfolgreich ist.
Gleiches gilt für TDD. Ich sehe nicht, wie es das lösen kann.
Ihre Lösung ist nicht technisch. Sie müssen die "Kern" -Grenzen klar definieren und jemandem eine "Wachhund" -Rolle zuweisen, sei es dem leitenden Entwickler oder dem Architekten. Änderungen am Core müssen diesen Watchdog durchlaufen. Er ist dafür verantwortlich, dass jede Ausgabe aller Teams ohne zu große Kollateralschäden zusammengeführt wird.
quelle
Als langfristige Lösung benötigen Sie auch eine bessere und zeitnahere Kommunikation zwischen den Teams. Jedes der Teams, die jemals beispielsweise das Kernfeature Y verwenden werden, muss an der Erstellung der geplanten Testfälle für das Feature beteiligt sein. Diese Planung wird für sich genommen die verschiedenen Anwendungsfälle hervorheben, die Merkmal Y zwischen den beiden Teams innewohnt. Sobald festgelegt ist, wie das Feature funktionieren soll, und die Testfälle implementiert und vereinbart wurden, muss das Implementierungsschema zusätzlich geändert werden. Das Team, das die Funktion freigibt, muss den Testfall ausführen, nicht das Team, das ihn verwenden wird. Die Aufgabe, falls vorhanden, die zu Kollisionen führen sollte, ist das Hinzufügen eines neuen Testfalls von einem der beiden Teams. Wenn ein Teammitglied an einen neuen Aspekt der Funktion denkt, der nicht getestet wurde, Es sollte ihnen freigestellt sein, einen Testfall hinzuzufügen, dessen Bestehen sie in ihrer eigenen Sandbox überprüft haben. Auf diese Weise treten nur Kollisionen auf der Ebene der Absichten auf, und sie sollten festgenagelt werden, bevor das überarbeitete Feature in die Öffentlichkeit entlassen wird.
quelle
Während jedes System effektive Testsuiten benötigt (was unter anderem Automatisierung bedeutet) und diese Tests, wenn sie effektiv verwendet werden, diese Konflikte früher als jetzt erkennen, werden die zugrunde liegenden Probleme nicht behoben.
Die Frage enthüllt mindestens zwei grundlegende Probleme: die Praxis, den „Kern“ zu modifizieren, um die Anforderungen für einzelne Kunden zu erfüllen, und das Versagen der Teams, ihre Absichten, Änderungen vorzunehmen, zu kommunizieren und zu koordinieren. Beides ist keine der Hauptursachen, und Sie müssen verstehen, warum dies getan wird, bevor Sie es beheben können.
Als Erstes muss festgestellt werden, ob sowohl die Entwickler als auch die Manager erkennen, dass hier ein Problem vorliegt. Wenn dies zumindest bei einigen der Fall ist, müssen Sie herausfinden, warum sie der Meinung sind, dass sie nichts dagegen unternehmen können, oder sich dagegen entscheiden. Für diejenigen, die dies nicht tun, können Sie versuchen, ihre Fähigkeit zu verbessern, vorauszusehen, wie ihre aktuellen Aktionen zukünftige Probleme verursachen können, oder sie durch Personen zu ersetzen, die dies können. Solange Sie nicht über Mitarbeiter verfügen, die wissen, wie die Dinge schief laufen, ist es unwahrscheinlich, dass Sie das Problem beheben können (und vielleicht auch nicht, zumindest kurzfristig).
Es kann schwierig sein, das Problem zumindest anfangs abstrakt zu analysieren. Konzentrieren Sie sich daher auf einen bestimmten Vorfall, der zu einem Problem geführt hat, und versuchen Sie herauszufinden, wie es passiert ist. Da die beteiligten Personen wahrscheinlich defensiv sind, müssen Sie auf eigennützige und post-hoc-Begründungen achten, um herauszufinden, was wirklich passiert.
Es gibt eine Möglichkeit, die ich nicht erwähne, da dies so unwahrscheinlich ist: Die Anforderungen der Kunden sind so unterschiedlich, dass es nicht genügend Gemeinsamkeiten gibt, um gemeinsam genutzten Kerncode zu rechtfertigen. Wenn dies der Fall ist, haben Sie tatsächlich mehrere separate Produkte und sollten diese als solche verwalten und keine künstliche Kopplung zwischen ihnen herstellen.
quelle
Wir alle wissen, dass Unit-Tests der richtige Weg sind. Wir wissen aber auch, dass es schwierig ist, diese realistisch nachzurüsten.
Eine bestimmte Technik, die für Sie beim Erweitern der Funktionalität nützlich sein kann, besteht darin, vorübergehend und lokal zu überprüfen, ob die vorhandene Funktionalität nicht geändert wurde. Das kann so gemacht werden:
Ursprünglicher Pseudocode:
Temporärer Testcode vor Ort:
Führen Sie diese Version durch alle vorhandenen Tests auf Systemebene. Wenn alles in Ordnung ist, wissen Sie, dass Sie nichts kaputt gemacht haben, und können dann den alten Code entfernen. Beachten Sie, dass Sie beim Überprüfen der Übereinstimmung von alten und neuen Ergebnissen möglicherweise auch Code hinzufügen, um Unterschiede zu analysieren und Fälle zu erfassen, von denen Sie wissen, dass sie aufgrund einer beabsichtigten Änderung, wie z. B. einer Fehlerbehebung, unterschiedlich sein sollten.
quelle
"Meistens werden die Änderungen nicht über die Teams bekannt gegeben, so dass die Bugs fast immer unerwartet
auftraten." Was ist mit (zusätzlich zu dem, worauf alle anderen bereits hingewiesen haben, dass Sie strenge Tests durchführen sollten), um sicherzustellen, dass es eine ordnungsgemäße Kommunikation gibt? Dass die Leute darauf aufmerksam gemacht werden, dass sich die Benutzeroberfläche, an die sie schreiben, in der nächsten Version ändern wird, und wie werden sich diese Änderungen auswirken?
Und geben Sie ihnen so schnell wie möglich Zugriff auf mindestens eine Dummy-Schnittstelle (mit leerer Implementierung), damit sie ihren eigenen Code schreiben können.
Ohne all das werden Unit-Tests nicht viel bewirken, außer dass in den letzten Phasen darauf hingewiesen wird, dass zwischen den Teilen des Systems einiges nicht stimmt. Sie wollen das wissen, aber Sie wollen es früh, sehr früh wissen und die Teams miteinander sprechen lassen, die Bemühungen koordinieren und tatsächlich häufigen Zugang zu der Arbeit haben, die das andere Team leistet verpflichten sich nach mehreren Wochen oder Monaten, 1-2 Tage vor Lieferung).
Ihr Fehler ist NICHT im Code, schon gar nicht im Code des anderen Teams, das nicht wusste, dass Sie an der Schnittstelle herumgespielt haben, gegen die sie geschrieben haben. Ihr Fehler liegt in Ihrem Entwicklungsprozess, der mangelnden Kommunikation und Zusammenarbeit zwischen Menschen. Nur weil Sie in verschiedenen Räumen sitzen, heißt das nicht, dass Sie sich von den anderen abgrenzen sollten.
quelle
In erster Linie haben Sie ein Kommunikationsproblem (wahrscheinlich auch mit einem Teambuilding- Problem verbunden). Ich denke, eine Lösung für Ihren Fall sollte sich auf ... Kommunikation statt auf Entwicklungstechniken konzentrieren.
Ich nehme an, dass es nicht möglich ist, das Kernmodul beim Starten eines Kundenprojekts einzufrieren oder zu teilen (andernfalls müssen Sie nur einige nicht kundenbezogene Projekte in Ihren Unternehmenszeitplan integrieren, die auf die Aktualisierung des Kernmoduls abzielen).
Wir müssen also versuchen, die Kommunikation zwischen den Teams zu verbessern. Dies kann auf zwei Arten angegangen werden:
Weitere Informationen zu CI als Kommunikationsprozess finden Sie hier .
Schließlich haben Sie noch ein Problem mit der fehlenden Teamarbeit auf Unternehmensebene. Ich bin kein großer Fan von Teambuilding-Events, aber dies scheint ein Fall zu sein, in dem sie nützlich wären. Haben Sie regelmäßig entwicklerweite Meetings? Können Sie Personen aus anderen Teams zu Ihren Projektrückblicke einladen? Oder vielleicht manchmal ein Freitagabendbier?
quelle