Warum Continuous Integration wichtig ist

0

Automatisierte Tests und ein automatisiertes Deployment sind sehr wichtig für eine zuverlässige Software in der auch Innovationen möglich sind. Es wird mit Continuous Integration sehr viel Zeit gespart und doch ist es immer wieder eine große Hürde diese tolle Technik einzuführen. Veränderungen sind immer ein schwieriger Prozess und Continuous Integration erfordert bei seiner Einführung viel mehr als nur guten Willen. Deshalb möchte ich mich in diesem Blog-Post an Entscheider und Entwickler wenden. Jeder wird schon einmal versucht haben den eigenen Code-Kosmos oder den in einer Firma zu verändern und nachhaltig zu verbessern und effektiver zu machen. Aber das funktioniert nur, wenn alle das auf einmal gemeinsam tun und sich zielstrebig in die Richtung bewegen. Es kostet sehr viel Energie. Hier müssen sich vor allem die Entwickler-Teams, die bekanntlich immer an ihrer Belastungsgrenze arbeiten, viel Zeit für nehmen und ihre Arbeitsweise auch noch umstellen. Das ist nicht leicht. Schlüssel sind hier u.a. Teamwork und ein stetiger Know-How Transfer.

Denn wenn im Chaos nur einer aufräumt und alle anderen sich nicht kümmern wird es scheitern. Sehr schnell – Roland Golla

Daher dreht sich dieser Artikel nicht um die tatsächliche Implementierung, sondern einfach um Argumente für diese Entscheidung und vor allem gegen den aktuellen Ist-Zustand. Am Ende muß sie von oben gefällt, durchgesetzt und kontrolliert werden. Denn der innere Schweinehund ist auch beim Thema Software-Qualität schwer zu überwinden. Der Gewinn liegt auf der Hand. Software-Qualität bringt Lebensqualität und schlechte Software-Qualität macht bekanntlich krank.

Continuous Integration ist nachhaltig und effizient

Ist-Zustand ohne Continuous Integration

Continuous Integration ist nachhaltig und effizient

Continuous Integration ist nachhaltig und effizient

Software-Entwicklung und das daraus resultierende Produkt ist ein elementarer Bestandteil der Geschäftsmodelle, die im Internet Geld verdienen. Von daher wundert es immer wieder, wie schlecht und ineffektiv hier auch bei professionellen Web-Applikationen gearbeitet wird. Hier arbeiten sehr viele unterschiedliche Stellen und Abteilungen an der Weiterentwicklung und einige wenige bis gar keine auch an der Instandhaltung. Neben dem eigentlichen Webdevelopern sind hier auch Manager, Projektleiter, Product-Owner, das Marketing und natürlich je nach Struktur noch viel mehr Personalien involviert. In kleineren Strukturen belegen vielleicht einzelne Personen mehrere Rollen. Sie alle haben dabei eines gemeinsam. Ein sehr großes Interesse an zuverlässiger und hoher Software-Qualität. Aber tun sie auch etwas dafür und wie versuchen sie diesen Zustand zu ändern?

“Trust is the essential reason we need continuous integration.” via @settermjd

Robert C. Martin alias Uncle Bob hat es schon vor langer Zeit auf den Punkt gebracht. Eines der größten Probleme in der Software-Entwicklung ist das fehlende Vertrauen in die Entwickler von allen anderen Beteiligten. Es ist hier allerdings auch ein schwarzer Peter unterwegs, der natürlich bei dem abgelegt wird, der sich am wenigsten wehrt. Den Webdevelopern. Dabei fängt am Anfang alles so schön ein. Ein spannendes neues Feature soll von einem Entwickler Team umgesetzt werden. Vorstellungen von den Details werden ausgetauscht und ein Termin für die Übergabe wird vereinbart.

Das ganze endet dann in 2 möglichen Szenarien. Der Launch-Termin verstreicht und das Feature ist noch nicht fertig. Oder es ist fertig verursacht aber Bugs und hat dazu noch selber welche. In der tatsächlichen Realität trifft meistens sogar beides zu. Das wird auch gerne einmal mit dem Begriff Kinderkrankheiten klein geredet.

Das Spielchen hat schon jeder so oft gesehen, daß Webdevelopment einen ganz schlechten Ruf bekommt und vielen Leuten Kopfzerbrechen und -schmerzen macht. Nicht umsonst habe ich mit Never Code Alone eine Initiative für Software-Qualität in Deutschland gegründet.

Wie ist die Welt ohne Continuous Integration?

Der Vater der agilen Software-Entwicklung hat einmal gesagt

Continuous Integration is a software development practice where members of a team integrate their work frequently; usually, each person integrates at least daily… Each integration is verified by an automated build… to detect integration errors as quickly as possible. – Martin Fowler

Das ist eine sehr treffende Aussage. Allerdings wie genau sieht denn eigentlich die Realität aus. Hier unterscheidet sich die Continuous Integration im Ansatz von der üblichen Entwicklungsweise. Denn die sieht leider in den meisten Fällen so aus

  • Ein Ticket mit dem Arbeitsauftrag wird von einer Person aus einem nicht technischen Arbeitsbereich erstellt
  • Das Feature oder der Bug wird implementiert bzw- gefixt – in der Regel sind es eher viele Bugs die reported und gefixt werden
  • Das ganze wird manuell und lokal vom einem Entwickler flüchtig für den positiven Fall getestet
  • Das Ticket wird abgeschlossen und sich mit dem Code nicht mehr beschäftigt
  • Irgendwann werden dann auf Staging Umgebungen wieder von Nicht-Technikern einfache Klick-Tests durchgeführt, die in der Regel auch nur exakt den Fall abdecken

In dieser Arbeits- und Denkweise liegen schon mehrere fundamentale Fehler. Kannst du sie erkennen? Und diese Probleme sind leider sehr verbreitet. Die manuellen Tests beziehen sich ausschließlich auf den rein funktionalen Aspekt im Ticket-Kontext. Dabei werden nicht einmal besonders viele Fälle abgedeckt oder sich kreativ daran gemacht Fehler zu finden die Software-Qualität dadurch zu erhöhen und zu verbessern.

Es wird mit minimalem Aufwand jeweils nur das entwickelt, was gebraucht wird, um die jeweiligen Hypothesen zu testen (s.o. Lean Startup Cycle). agil-werden.de

Und wer kennt die folgenden Punkte nicht auch aus dem Entwickler-Alltag.

  • Webdeveloper macht eine Änderung
  • Webdeveloper öffnet den bevorzugten Browser und schaut sich nur den Teil seiner Änderung kurz an
  • Webdeveloper sieht das alles so läuft wie er möchte
  • Er setzt einen neuen Ticket-Status und geht zum nächsten Task

Was ist so kompliziert an Software-Entwicklung?

Große Probleme sind hier zu wenig Kommunikation und auch zu wenig Sorgfalt. Beides kostet sehr viel Zeit und genau deshalb ist hier eine Automatisierung mit Continuous Integration so wichtig. Natürlich implementieren wir die Anforderungen, die an uns gestellt werden. Jeden Tag und auch Freitags. Wir geben nicht auf. Deshalb sind wir Coder. Danach setzen wir ein Testszenario auf und klicken das durch. Aber das kommunizieren wir dann wieder nicht. Warum geben wir dem Tester das Wissen nicht mit und wo das kniffelige ist einfach mit in das Ticket? Wenn alles – in dem Ticket-Kontext – passt, dann ist der Prozess abgeschlossen und wir gehen zum nächsten Task. Betrachten wir an dieser Stelle einmal folgende Fragen.

  • Was passiert, wenn ein weiterer Entwickler eine Änderung in dem System macht, die eine Abhängigkeit zu dem Task hat?
  • Kann sich die eigene Änderung auch auf Abhängigkeiten im System auswirken?
  • Haben beide Entwickler ernsthaft über alle Eventualitäten nachgedacht?
  • Werden bei weiteren Änderungen die bestehenden Tests berücksichtigt?
  • Werden bei jeder Änderung alle nötigen Test-Szenarien für alle Usecases der Code Änderung durchgeführt?
  • Wie lange dauert eine vollständige Test-Iteration?
  • Welcher unter Druck stehende Mensch kann immer gleichbleibende Tests manuell ausführen?

Kann man erkennen worauf ich hinaus will? Damit kann langfristig nicht erfolgreich gearbeitet werden. Es ist unmöglich zu skalieren und es ist kein eindeutiges und wiederholbares Test-Szenario und -ergebnis. Am Ende kann in solchen Arbeitsumgebungen keiner genau sagen was und wie getestet wurde. Und auch nicht genau, warum es überhaupt funktioniert. Wer trägt hier die Verantwortung und würdet ihr in einem Auto fahren, daß so getestet wird oder einen Bungee-Sprung bei dem Hersteller machen, der so arbeitet? Es funktioniert für einen kleinen lokalen ersten funktionalen Test, oder bei der Entwicklung selbst. Vielleicht wird noch einmal auf einer Staging Umgebung irgendetwas anderes getestet. Oft ist es ja schon schwierig genug einen Bug zu rekonstruieren. Und wenn man als Tester nur auf Staging kommt und vermutet, daß es jetzt funktioniert und gar keinen Vergleich hat, kann man ungefährt die Dimension von Chaos hier erahnen. Aber in Wahrheit erscheint für jedes Ticket potentiell ein neuer Bug, weil die Testabdeckung so gering ist und man einfach nicht fehlerfrei arbeiten kann. Aber gibt es hier nicht doch eine Lösung?

Wir brauchen zuverlässige automatisierte Prozesse

Software-Qualität

Software-Qualität

Auch Webdeveloper sind Menschen und sind natürlich auch außerhalb ihrer Arbeit einer Vielzahl von Belastungen ausgesetzt. Finanzen, Emotionen, Zeit, Gesundheit, Familie, Beziehungen und natürlich auch das Wetter und die jeweilige Tagesform spielen in der täglichen Arbeit eine Rolle. In dem Zusammenhang sind auch Arbeitsweg und Arbeitsumstände beispielsweise in Großraum Büros ein Einflussfaktor. Wirken sich diese ganzen Faktoren auf unsere maximale Top-Leistungsfähigkeit aus? Natürlich. Und wer will schon jeden Tag auf 100% Genauigkeit laufen?

Betrachten wir aber auch moderne Webapplikationen. Denken wir einen Moment lang darüber nach, wie komplex und anspruchsvoll sie geworden sind. Wieviele Abhängigkeiten und miteinander verbundene Systeme gibt es? Abgesehen davon, daß es nachweislich Legacy Code Anwendungen gibt in denen niemand den Gesamtüberblick hat und alles ein Spiel mit sehr hohem Risiko und Einsatz stattfindet.

Kann ein Webdeveloper, egal wie kompetent und erfahren er auch immer sein mag, hier immer für Zuverlässigkeit garantieren. Welchen Druck muß er dabei wohl standhalten und wie hoch ist seine psychische und physische Belastung bei dem ganzen Spiel. Das ist unmöglich und auch nicht förderlich für Innovationen.

Bungee auf dem Live-System

Bungee auf dem Live-System

Es kommt also eine Entwicklung zustande,  die wie ein Blindflug läuft. Es gibt viel zu viele Unbekannte, so viele offene Fragen und Faktoren, die man einfach nicht mehr kontrollieren und überblicken kann. Die Wahrscheinlichkeit hier in Zukunft einen längeren Ausfall zu haben ist extrem hoch. Es entstehen sehr hohe Kosten für die niemand aufkommen möchte und die auch keiner irgendwo geplant hat. Die stehe auch in keinen Verhältnis und wachsen nur noch weiter. Es bringt nichts Symptome zu bekämpfen man muß an die Ursachen gehen.  Aber ich kann dir verraten, wer das freitags abends alles in seiner Freizeit wieder rausholen darf. Der Frust steigt und das Betriebsklima fällt. Hier werden neben der Applikation auch alle damit in Verbindung stehenden Unternehmen und Mitarbeiter in Mitleidenschaft gezogen. Aber der Schuldige wird gefunden, der der es gemacht hat also du.

Das Ziel von Continuous Integration

Bei Continuous Integration ist das Ziel dieses Unbekannte nach und nach aufzudecken und vor allem durch Tests abzudecken. So wird die Entwicklung schneller und zuverlässiger. Die Software-Qualität steigt. Aber was ist das genau? Continuous Integration kann man auf folgende 11 Punkte zusammenfassen:

  1. Alles soll in ein Repository und nicht mit Sub-Repositories gearbeitet werden
  2. Build-Prozess mit Self-Testing
  3. Automatisieren des Build-Prozesses
  4. Jeder arbeitet mit hohen Software-Qualitätsansrüchen und schreibt zuverlässige Tests für seinen Teil der Applikation
  5. Jeder aktualisiert sich regelmäßig gegen das Haupt-Repository und versucht seinen Teil schnell zurück zu mergen
  6. Kommt es zu Fehlern werden diese sofort behoben und die Build-Pipeline grün gehalten
  7. Der gesamte Build-Prozess muß schnell sein und hier ebenfalls immer verbessert werden
  8. Die Entwicklung soll mit vielen Commits transparent und übersichtlich sein
  9. Staging Umgebungen sollen immer komplett neu gebaut und getestet werden. Alles andere ist nicht zuverlässig.
  10. Ein Projekt Setup soll ebenfalls schnell und automatisiert gehen. So kann es jeder Mitarbeiter immer schnell wieder herstellen und natürlich auch neue Mitarbeiter schnell in das Team integriert werden.
  11. Automatisiertes Deployment

Betrachten wir 5 dieser Punkte im Detail.

Build-Prozess mit Self-Testing

Build-Prozess
Bildquelle: tamingdata
Ein automatisiertes Testverfahren ist der Kern von Continuous Integration. Durch diese Tests wird die Software in ihrem Gesamtzustand validiert und immer alle Tests durchgeführt. In der Webentwicklung gibt es tatsächlich Zufälle, die niemand vorher sehen kann. Die können nur durch eine hohe und zuverlässige Test-Abdeckung gefunden werden. Völlig unabhängig davon ob man BDD (Behavior Driven Development), TDD (Test Driven Development) , oder eine der anderen xDD verwendet. Dabei ist eine Kombination mit Frontend-Tests und Unit-Tests schon ein sehr guter Anfang. Funktionale-Tests und API-Tests können natürlich auch zusätzlich eingesetzt werden. Alle zusammen lassen sich ja sehr gut mit dem PHP-Testing-Framework Codeception erstellen. Mit all diesen Mitteln lässt sich eine hohe Testabdeckung erreichen. Wichtig ist, daß sie jederzeit und in jedem Environment wiederholbar sind. Dazu sollten sie ebenfalls, genau wie die eigentliche Software skalierbar und erweiterbar sein. Dann werden die Tests Bugs wesentlich eher als ihr, der Kunde oder der User aufspüren. Dabei ist es nicht so wichtig, ob die Tests 10 mal oder 1000 mal ausgeführt werden. Wichtig ist das sie immer automatisiert dabei sind und auf keinen Fall vernachlässigt werden. Das gute ist hier die Zuverlässigkeit und Effektivität mit der andere Bereiche auch immer wieder getestet werden und so eine hohe Gewährleistung.

Automatisieren des Build-Prozesses

In einem Build-Prozess werden die Tests bei einem bestimmten Event automatisiert ausgeführt. Das passiert in der Regel in dem Moment in dem ein Webdeveloper einen Push auf einem bestimmten Branch, wahrscheinlich das aktuelle Release, gegen das Remote-Repository macht. Wichtig ist, daß hier immer alle Tests ausgeführt werden und sie auch in unterschiedlicher Reihenfolge funktionieren und durchgeführt werden. Dafür kann man bei Codeception eine Shuffle-Funktion nutzen. Dabei muß alles auch unabhängig von Datensätzen und anderen möglichen Faktoren immer reibungslos laufen. Hier bieten sich bei simulierten User-Eingaben unter anderem Timestamps an, die z.B. einen Usernamen erweitern. Tests-Szenarien können hier von einfachen Assertions über komplexe Funktionalen-Tests bis hin zu User-Stories in Form von Acceptance-Tests sein. Dabei sind Computer natürlich viel besser dafür geeignet solche monotonen und wiederkehrenden Arbeiten immer mit der gleichen Präzision durchzuführen. Dafür ist der Mensch einfach nicht gemacht.

Computers are designed for automation. Humans aren’t.“ via @settermjd

Die Entwicklung soll mit vielen Commits transparent und übersichtlich sein

Commit Messages sollten neben ihrer Ticket-ID auch immer eine Information dazu enthalten, was gerade gemacht wurde. Welche Datei oder Methode wurde angepasst und vor allem warum? Welches JS-File wurde bearbeitet oder vielleicht etwas an einer Konfiguration geändert. Nur so kann nachvollzogen werden was passiert ist und wo ein eventueller neuer Bug herkommen könnte. Durch diese Transparenz kann effektiver gearbeitet werden. Ein Commit sollte auch immer eine lauffähige Version der Software abbilden können und nicht zwischendurch gemacht werden.

Generell wird die Software ja immer getestet bevor sie eingesetzt wird. Und das passiert bei automatisierten Tests immer auf die gleiche Weise jedes mal. Das hat mehrere Vorteile.

  • Die Probleme sind fast sofort sichtbar, da automatisierte Tests wesentlich schneller laufen.
  • Der Webdeveloper, der den Bug verursacht hat wird schnell gefunden. Dadurch wird viel Zeit durch unnötiges Rätselraten reduziert.
  • Die Verfügbarkeit und Zuverlässigkeit der Applikation wird erhöht.
  • Die Kosten für die Software-Entwicklung fallen, da die Entwicklung insgesamt viel effektiver wird.

Probleme werden schneller und früher entdeckt. In diesem Zusammenhang sind die Kosten eines Bugs im Zusammenhang zu seinem Alter zu betrachten. Es wird weniger Zeit benötigt Probleme zu lösen, da es weniger Kommunikation benötigt und der Entwickler noch nicht mit seinem Kopf so weit von dem aktuellen Task entfernt ist.

Staging Umgebungen sollen immer komplett neu gebaut und getestet werden. Alles andere ist nicht zuverlässig

„Lokal gehts“. Wer hat das nicht schon einmal gehört oder gesagt. Das ist eine sehr große Herausforderung, die Webanwendungen immer wieder plagt. Hier spreche ich auch gerne aus eigener Erfahrung. Webdeveloper arbeiten lokal mit Linux, OSX und Windows. Am Ende sind die Webserver auf denen gehostet wird allerdings dann wieder Linux. Von daher ist es schon sehr wichtig gemeinsam auf einer gemeinsamen Vagrant Box zu entwickeln. Allerdings machen Webdeveloper hier natürlich auch manchmal Dinge, die sie näher oder schneller an ein Ziel bringen. Das ist auch völlig ok und gut so. Solange sie diese Änderungen auch in das Produktiv-System gebracht werden. Aber das soll in diesem Abschnitt gar nicht im Detail erläutert werden. Wichtig ist das sich die Staging Umgebung nicht von der Live-Umgebung unterscheidet und hier ein vollständiges automatisiertes Rollout durchgeführt wird und danach alle Tests automatisiert durchgeführt werden. So schützt man sich vor Problemen und Bugs die keiner braucht.

Ein Projekt Setup soll ebenfalls schnell und automatisiert gehen

Warum Continuous Integration wichtig ist

Warum Continuous Integration wichtig ist

Ein Projekt muß schnell und einfach aufgesetzt werden können. Egal ob Junior- oder Senior-Webdeveloper, Projektmanager oder Student, Freelancer oder Remote-Mitarbeiter. Alle sollen in der Lage sein eine aktuelle Entwicklungsumgebung schnell und einfach aufzusetzen. Nur so ist sie im geringsten Fehleranfällig und benötigt die wenigsten Ressourcen bei denen ja schon immer von einem starken Mangel gesprochen wird. Wenn man allerdings für jedes Setup einen internen Mitarbeiter mit 5 Jahren konkreter Projekterfahrung für 3 Stunden binden muß, damit ein neuer Mitarbeiter in das Projekt starten kann hat man auf mehreren Ebenen ein Problem. Insgesamt kann man hier von einer langsamen und uneffektiven Entwicklung ausgegehen.
Die Bereitstellung einer voll funktionsfähigen Applikations-Umgebung wie Test, Staging Produktion oder für einen neuen Entwickler muß ganz einfach und automatisiert gehen. Das hat nicht nur Vorteile bei der Effektivität des Personals, sondern auch bei neuen Servern. Hierbei spielt die Architektur eine entscheidende Rolle. Bei einer guten Continuous Integration ist das schon von alleine gegeben.

Weiterführende Links Continuous Integration

Entwicklungshilfe NRW Starthilfe
Never Code Alone

About Author

PHP Kurs und Inhouse Schulungen für Webdevelopment mit Continuous Integration - Clean Coder, Blogger, Autor, Dozent und Senior Webdeveloper www.rolandgolla.de

Leave A Reply