Ruby ist seit vielen Jahren eine sehr etablierte Programmiersprache, die durchaus auch Anfängern empfohlen werden kann. Ruby folgt dem objektorientierten Paradigma und enthält sehr viele Konzepte, um OOP gut zu unterstützen. Außerdem lassen sich dank des Frameworks Ruby on Rails unkompliziert komplexe Webanwendungen entwickeln.
Die schwierigste Hürde beim Einstieg in Ruby, die es zu meistern gilt, ist die Installation der gesamten Entwicklungsumgebung. Angesichts dessen habe ich dieses kurze Tutorial zum Einstieg mit Ruby verfasst. Beginnen wir daher auch gleich mit der Installation.
Mein Betriebssystem ist ein Debian 12 Linux und Ruby lässt sich sehr einfach mit der Anweisung sudo apt-get install ruby-full installieren. Dieses Vorgehen kann auf alle Debian basierte Linux Distributionen wie z. B. Ubuntu übertragen werden. Anschließend kann mit ruby -v der Erfolg in der Bash überprüft werden.
Wenn wir nun dem Tutorial auf der Ruby on Rails Homepage folgen und das Rails Framework über gem rails installieren wollen, stoßen wir bereits auf das erste Problem. Wegen fehlender Berechtigungen lassen sich keine Bibliotheken für Ruby installieren. Nun konnten wir auf die Idee kommen, die Bibliotheken, als Superuser mit sudo zu installieren. Dies Losung ist leider nur temporär und verhindert, dass später in der Entwicklungsumgebung die Bibliotheken korrekt gefunden werden. Besser ist es, einen Ordner für die GEMs im home Verzeichnis des Nutzers anzulegen und dies über eine Systemvariable bereitzustellen.
Die oben stehende Zeile ist an das Ende der Datei .bashrc einzutragen, damit die Änderungen auch persistent bleiben. Wichtig ist, dass <user> gegen den richtigen Nutzernamen ausgetauscht wird. Den Erfolg dieser Aktion lasst sich über gem environment überprüfen und sollte eine ähnliche Ausgabe wie nachstehend ergeben.
Mit dieser Einstellung lassen sich nun ohne Schwierigkeiten Ruby GEMs installieren. Das probieren wir auch gleich aus und installieren, das Ruby on Rails Framework, was uns bei der Entwickelung von Webapplikationen unterstützt: gem install rails. Dies sollte indessen ohne Fehlermeldungen durchlaufen und mit dem Kommando rails -v sehen wir, ob wir erfolgreich waren.
Im nächsten Schritt können wir nun ein neues Rails Projekt anlegen. Hier bediene ich mich dem Beispiel aus der Ruby on Rails Dokumentation und schreibe in die Bash: rails new blog. Dies erzeugt ein entsprechendes Verzeichnis namens blog mit den Projektdateien. Nachdem wir in das Verzeichnis gewechselt sind müssen wir noch alle Abhängigkeiten installieren. Das geschieht über: bundle install.
Hier stoßen wir nun auf ein weiteres Problem. Die Installation kann nicht beendet werden, weil es anscheinend ein Problem mit der Bibliothek psych gibt. Das tatsächliche Problem ist allerdings, dass auf der Betriebssystemebene die Unterstützung für YAML-Dateien fehlt. Das lässt sich rasch beheben, indem das YAML-Paket nachinstalliert wird.
sudo apt-get install libyaml-dev
Das Problem mit psych bei Ruby on Rails besteht schon eine Weile und ist mit der YAML Installation behoben, so, dass nun auch die Anweisung bundle install erfolgreich durchläuft. Jetzt sind wir auch in der Lage, den Server für die Rails Anwendung zu starten: bin/rails server.
ed@:~/blog$bin/railsserver=> BootingPuma=> Rails7.1.3.3applicationstartingindevelopment=> Run`bin/rails server --help`for more startup optionsPumastartinginsinglemode...* Puma version: 6.4.2 (ruby3.1.2-p20)("The Eagle of Durango")* Min threads: 5* Max threads: 5* Environment: development* PID: 12316* Listening on http://127.0.0.1:3000* Listening on http://[::1]:3000UseCtrl-Ctostop
Rufen wir nun im Webbrowser die URL http://127.0.0.1:3000 auf, sehen wir unsere Rails Webanwendung.
Mit diesen Schritten haben wir nun eine funktionierende Ruby Umgebung auf unserem System erstellt. Nun ist es an der Zeit, sich für eine geeignete Entwicklungsumgebung zu entscheiden. Wer nur gelegentlich ein paar Scripte anpasst, dem genügen VIM und Sublime Text als Editoren. Für komplexe Softwareprojekte sollte wiederum auf eine vollständige IDE zurückgegriffen werden, da dies die Arbeit erheblich vereinfacht. Die beste Empfehlung ist die kostenpflichtige IDE RubyMine von JetBrains. Wer Ruby Open Source Projekte als Entwickler unterstützt, kann eine kostenfreie Lizenz beantragen.
Eine frei verfügbare Ruby IDE ist VSCode von Microsoft. Hier müssen aber zunächst ein paar Plug-ins eingebunden werden, und für meinen Geschmack ist VSCode auch nicht sehr intuitiv. Ruby Integration für die klassischen Java IDEs Eclipse und NetBeans sind recht veraltet und nur mit sehr viel Mühe zum Laufen zu bekommen.
Damit haben wir auch schon alle wichtigen Punkte, die notwendig sind, eine funktionierende Ruby-Umgebung auf dem eigenen System einzurichten, besprochen. Ich hoffe, mit diesem kleinen Workshop die Einstiegshürde zum Erlernen von Ruby erheblich gesenkt zu haben. Wenn Ihr diesen Artikel mögt, freue ich mich über ein Like und die Weiterempfehlung an eure Freunde.
In der Softwarebranche ist es üblich, dass die Codebasis eine ausreichende Testautomatisierung aufweist. Denn dies ist für einen stabilen DevOps-Prozess und sicheres Refactoring notwendig. Aber die Realität sieht oft ganz anders aus. Fast jedes Projekt, an dem ich während meiner Karriere teilgenommen habe, hatte keine Zeile Testcode. Wenn wir darüber nachdenken, dass seit über 40 Jahren immer noch 80% aller kommerziellen Softwareprojekte scheitern, sollte uns das nicht überraschen. Aber das muss nicht so sein. In diesem Vortrag zeige ich, wie einfach es ist, auch in großen Projekten einen testgetriebenen Ansatz einzuführen. Das technische Setup ist ein Standard-Java-Projekt mit Apache Maven und JUnit 5.
Die meisten DevOps-Teams sind überzeugt, dass die Automatisierung selbst und die Automatisierung selbst eine große Herausforderung darstellt. Es scheint dringend notwendig zu sein, alles zu automatisieren – sogar die Automatisierung selbst. Dies ist für die meisten DevOps-Teams ein allgemeines Verständnis und somit Motivation. Werfen wir einen Blick auf typische, kontinuierliche Dummheiten bei der Transformation vom reinen Konfigurationsmanagement zum DevOps-Engineer.
Die meisten DevOps-Teams sind davon überzeugt, dass die Automatisierung selbst und die Automatisierung selbst eine große Herausforderung darstellt. Es scheint dringend notwendig zu sein, alles zu automatisieren – sogar die Automatisierung selbst. Dies ist für die meisten DevOps-Teams ein allgemeines Verständnis und somit Motivation. Werfen wir einen Blick auf typische, kontinuierliche Dummheiten bei der Transformation vom reinen Konfigurationsmanagement zum DevOps-Engineer.
Build-Logik kann eine fehlerhafte Architektur nicht reparieren. Zahlreiche SCM-Zusammenführungskonflikte entstehen durch die fehlende Kapselung der Geschäftslogik. Bei Funktionen, die über viele Module oder Dienste verteilt sind, ist die Wahrscheinlichkeit hoch, dass eine Datei von mehreren Entwicklern bearbeitet wird.
Die Notwendigkeit orchestrierter Builds deutet auf Architekturprobleme hin. Transitive Abhängigkeiten, fehlende Kapselung und eine umfangreiche Abhängigkeitskette sind typische Gründe für das Henne-Ei-Problem. Entwerfen Sie Ihre Artefakte so unabhängig wie möglich.
Build-Logik wird von Entwicklern und nicht von Administratoren entwickelt. Personen mit Fokus auf den Betrieb haben andere Konzepte zur Pflege von Artefakt-Builds als Softwareentwickler. Ein gutes Beispiel für eine Anti-Pattern-Build-Struktur sind webMethods der Software AG. webMethods bietet keinen Repository-Server wie Sonatype Nexus zum Teilen von Abhängigkeiten. Der Build verweist immer auf die Abhängigkeiten innerhalb einer webMethods-Installation. Diese Vorgehensweise verstößt gegen die Grundidee der Build-Automatisierung, die im Buch „Praktiken eines agilen Entwicklers“ von 2006 beschrieben wird.
Nicht alles auf einmal. Teilen Sie die Build-Jobs in konkrete Ziele auf, wie z. B. Artefakt erstellen, Abnahmetests durchführen, API-Dokumentation erstellen und Berichte generieren. Wenn einer der letzten Schritte fehlschlägt, müssen Sie nicht alles wiederholen. Die Ausführungszeit des Builds wird drastisch reduziert, und die Build-Infrastruktur lässt sich leichter warten.
Geben Sie Ihrer Build-Infrastruktur nicht zu viel Flexibilität. Dieser Punkt hängt eng mit dem ersten Thema zusammen, das ich erläutert habe. Ein undisziplinierter Build-Manager erstellt extrem komplexe Skripte, die niemand versteht. Der JavaScript-Task-Runner Grunt ist ein Beispiel dafür, wie eine Build-Logik unübersichtlich und unleserlich werden kann. Dies ist einer der Gründe, warum ich mich für Maven als Build-Tool für Java-Projekte entscheide, da es die Steuerung verständlicher Builds ermöglicht.
Es besteht keine Notwendigkeit, die Automatisierung zu automatisieren. Komplexe Automatisierungsstufen verursachen per Definition höhere Kosten als einfache Aufgaben. Überlegen Sie sich immer vorher, welchen Nutzen Ihre Automatisierungsaktivitäten bringen, um zu prüfen, ob es sich lohnt, Zeit und Geld dafür aufzuwenden.
Wir tun, was wir können, aber können wir auch, was wir tun? Oder mit den Worten von Gardy Bloch: „A fool with a tool is still a fool.“ Verstehen Sie die Anforderungen Ihres Projekts und entscheiden Sie auf dieser Grundlage, welches Tool Sie wählen. Wenn Ihnen die Ressourcen fehlen, kann Sie selbst die professionellste Lösung nicht unterstützen. Wenn Sie Ihr Problem verstanden haben, können Sie neue, professionelle und fortgeschrittene Prozesse erlernen.
Die Build-Logik wurde zunächst in der lokalen Entwicklungsumgebung ausgeführt. Wenn Ihr Build nicht auf Ihrem lokalen Entwicklungsrechner läuft, nennen Sie es nicht Build-Logik. Es ist nur ein Hack. Die Build-Logik muss plattform- und IDE-unabhängig sein.
Vermischen Sie Quellcode-Repositories nicht. mit anderen Dateien Die Organisation der Quellen in mehreren Ordnern innerhalb eines riesigen Verzeichnisses führt zu einem komplexen Build ohne jegliche Flexibilität. Quellen sollten nach Technologie oder separaten, unabhängigen Modulen strukturiert sein.
Viele der genannten Punkte lassen sich anhand der aktuellen Situation in fast jedem Projekt nachvollziehen. Die Lösung für eine erfolgreiche Problembehebung ist meist nicht allzu kompliziert. Sie erfordert lediglich ein wenig Aufmerksamkeit und gute Planung. Mein wichtigster Ratschlag ist das KISS-Prinzip (Keep it simple, stupid). Das bedeutet, den Standardprozess so weit wie möglich unverändert zu übernehmen. Man muss das Rad nicht neu erfinden. Es gibt Gründe, warum ein Standard zum Standard wird. Hier ist ein kurzer Plan, dem Sie folgen können:
Erstens: Verstehen Sie das Problem.
Zweitens: Suchen Sie nach einer Standardlösung für den Prozess.
Drittens: Entwickeln Sie einen Plan zur Integration der Lösung in die bestehende Prozesslandschaft. Dies bedeutet, Tools zu entfernen, die Standardprozesse nicht unterstützen.
Wenn Sie Ihren eigenen Weg Schritt für Schritt gehen, ohne zu weit zu springen, können Sie schnell positive Ergebnisse erzielen.
Übrigens: Wenn Sie Unterstützung für einen erfolgreichen DevOps-Prozess benötigen, kontaktieren Sie mich gerne. Ich biete praktische Beratung und Schulungen zum Aufbau eines leistungsstarken DevOps-Teams an.
Auch wenn es früher Konfigurationsmanagement hieß, bedeutet das nicht, dass die alten Probleme mit dem schönen neuen Namen DevOps beseitigt wurden. Durch die zunehmende Komplexität der Projekte und die Unkenntnis der Tools erreichen die heutigen Strategien und Arbeitsabläufe, die von den Entwicklungsteams erwartet werden, erst eine neue Qualität.
Viele DevOps-Teams verfolgen den Ansatz, alle möglichen Arbeitsschritte zu automatisieren. Das geht sogar so weit, dass sie versuchen, die Automatisierung selbst zu automatisieren. Daran wäre prinzipiell nichts auszusetzen, wenn die Lösung dann auch den Entwicklungsteams helfen würde, ihre täglichen Aufgaben effizient abzuarbeiten. Leider sind viele der Lösungen, die ich in den letzten Jahren in meinem Berufsleben kennen gelernt habe, weit davon entfernt. Vielmehr schaffen sie Entwicklungsumgebungen, die die tägliche Arbeit erschweren, anstatt sie zu vereinfachen. Schauen wir uns also gemeinsam an, welche gravierenden Auswirkungen unbedacht getroffene Entscheidungen auf den späteren Erfolg eines Projekts haben. Natürlich werden wir auch das eine oder andere Highlight aus der Entwicklung finden, das dem Unternehmen mehr als nur ein wenig Kopfzerbrechen bereitet.
Moderne Softwareentwicklung besteht aus viel mehr als nur aus Code und Kaffee. Ohne passende Deployment-Strategien und eine saubere Release-Verwaltung laufen selbst kleine Projekte schnell aus dem Ruder und werden unbeherrschbar.
Dieses Praxisbuch zeigt Ihnen, wie Sie mit Jenkins, Git und Nexus eine CI-Pipeline aufbauen. Erfahren Sie direkt aus der Praxis, was für erfolgreiche Software-Projekte essenziell ist: Source Control Management, flächendeckende Softwaretests mit einer sinnvollen Qualitätskontrolle und ein gut organisiertes Deployment. Marco Schulz gibt Ihnen seine Erfahrung aus zahlreichen internationalen IT-Projekten weiter und hält eine Menge Tipps und Überlegungen zu gutem Software Engineering für Sie parat.
Marco Schulz, 2021, 400 Seiten, Rheinwerk Computing, ISBN 978-3-8362-7834-8
The Big Picture DevOps, Continuous Deployment, Build Jobs, Pipelines … ist all das wirklich nötig, wenn es nur um ein paar Zeilen Java-Code geht? Marco Schulz zeigt Ihnen, welche Vorteile moderne Entwicklungsparadigmen bieten, wie Sie Open-Source-Werkzeuge zu einer effektiven Toolchain zusammenfügen und damit Ihre Software professionell und zeitgemäß verwalten.
Professionelle Code-Verwaltung Programmieren wäre viel einfacher, wenn Sie sich um den bestehenden Code keine Gedanken machen müssten. Da die Integration neuer Funktionen aber eine Standardaufgabe in der Software-Entwicklung ist, dreht sich hier alles um Merging-Konflikte, die Vergabe von sinnvollen Release-Nummern und das Schreiben von Unit- und Integrationstests. So behalten Sie den Überblick und arbeiten effektiv und agil im Team.
Toolchains für moderne Software-Projekte Jenkins ist das wichtigste Werkzeug, wenn es um komfortable CI-Pipelines und automatisierte Builds geht. In diesem Praxisbuch finden Sie aber noch viel mehr: Git, Maven, Nexus, SonarQube und viele andere Tools helfen Ihnen bei der Verwaltung Ihrer Codebasis.
Errata: Auch wenn die Erstellung des Buches mit viel Sorgfalt durchgeführt wurde, kommt es durchaus vor, das sich Fehler einschleichen. Dank hilfreicher Hinweise von aufmerksamen Lesern finden Sie an dieser Stelle Korrekturen.
Seite 32: Literaturliste
[2.1] Gene Kim, The Unicorn Project, 2019, IT Revolution Press, ISBN: 978-1942788768
[2.2] Gene Kim, The Phoenix Project, 2013, IT Revolution Press, ISBN: 978-0-9882625-7-7
Linux entwickelt sich mehr und mehr zu einem beliebten Betriebssystem für IT-Profis. Einer der Gründe für diese Entwicklung sind die Serverlösungen. Stabilität und geringer Ressourcenverbrauch sind einige der wichtigsten Eigenschaften für diese Wahl. Wer schon einmal mit einem Microsoft Server herumgespielt hat, wird den grafischen Desktop bei einem Linux Server vermissen. Nach dem Einloggen in einen Linux Server siht man nur die Kommandozeile, die auf Eingaben wartet.
In diesem kurzen Artikel stelle ich einige hilfreiche Linux-Programme zur Umgang mit Text Dateien auf der Kommandozeile vor. Auf diese Weise lassen sich leicht Informationen sammeln, zum Beispiel aus Protokolldateien (Logfiles). Bevor ich beginne, möchte ich noch einen einfachen und leistungsfähigen Editor namens joe empfehlen.
Strg + C – Abbrechen der aktuellen Bearbeitung einer Datei ohne Speichern der Änderungen Strg + KX – Beenden der aktuellen Bearbeitung und Speichern der Datei Strg + KF – Text in der aktuellen Datei suchen Strg + V – Einfügen der Zwischenablage in das Dokument (CMD + V für Mac) Strg + Y – Aktuelle Zeile an der Cursorposition löschen
Um joe auf einer Debian-basierten Linux-Distribution zu installieren, müssen Sie nur folgendes eingeben:
1. Wenn Sie Inhalte in einer großen Textdatei finden müssen, ist GREP Ihr bester Freund. Mit GREP können Sie nach Textmustern (Pattern) in Dateien suchen.
Als ich vor über 10 Jahren begonnen habe testgetrieben zu programmieren, waren mir sehr viele verschiedene Konzepte theoretisch bekannt. Aber diese Sichtweise erst Testfälle zu schrieben und dann die Implementierung umzusetzen war irgendwie nicht der Weg mit dem ich gut zurecht gekommen bin. Wenn ich ehrlich bin ist das bis heute der Fall. So das ich eine für mich funktionierende Adaption des TDD Paradigma von Kent Beck gefunden habe. Aber langsam der Reihe nach. Vielleicht ist mein Ansatz ja für den einen oder anderen ebenfalls recht hilfreich.
Ich komme ursprünglich aus einem Umfeld für hoch skalierbarer Webanwendungen auf die sich all die tollen Theorien aus dem universitären Umfeld in der Praxis nicht ohne weiteres umsetzen lassen. Der Grund liegt vor allem in der hohen Komplexität solcher Anwendungen. Zum einen sind verschiedene Zusatzsysteme wie In Memory Cache, Datenbank und Identität und Zugriffs Management (IAM) ein Teil des Gesamtsystems. Zum Anderen verstecken viele moderne Frameworks wie OR Mapper Komplexität hinter verschiedene Zugriffsschichten. All diese Dinge müssen wir als Entwickler heutzutage beherrschen. Deshalb gibt es robuste, praxiserprobte Lösungen die gut bekannt sind aber wenig Verwendung finden. Kent Beck mit ist eine der wichtigsten Stimmen für den praktischen Einsatz automatisierter Softwaretest.
Wenn wir uns auf das Konzept TDD einlassen wollen ist es wichtig nicht jedes Wort zu sehr auf die Goldwaage zu legen. Es ist nicht alles in Stein gemeißelt. Wichtig ist das Ergebnis am Ende des Tages. Aus diesem Grund ist es unabdinglich sich die Zielvorgabe aller Bemühungen vor Augen zu führen um dann einen persönlichen Mehrwert zu erzielen. Also schauen wir uns zu erst einmal an was wir überhaupt bezwecken wollen.
Der Erfolg gibt uns Recht
Als ich meine ersten Gehversuche als Entwickler unternommen hatte benötigte ich stetiges Feedback ob das was ich da gerade zusammen bauen auch wirklich funktioniert. Diese Feedback habe ich meist dadurch erzeugt, in dem ich meine Implementierung einerseits mit unzähligen Konsolenausgaben gespickt habe und andererseits habe ich immer versucht alles in eine Benutzeroberfläche einzubinden um mich dann ‚manuell durchzuklicken‘. Im Grunde ein sehr umständliches Test Setup, das dann auch am Schuß wieder zu entfernen ist. Wenn dann noch spätere Bugfixes vorgenommen werden mussten ging das ganze Prozedere wieder von Neuem los. Alles irgendwie unbefriedigend und weit entfernt von einer produktiven Arbeitsweise. Irgendwie musste das verbessert werden ohne das man sich jedes Mal neu erfindet.
Schließlich hat mein ursprünglicher Ansatz genau zwei markante Schwachstellen. Die offensichtlichste ist das ein und auskommentieren von Debug Informationen über die Konsole.
Viel schwerwiegender ist aber der zweite Punkt. Denn all das erworbene Wissen zu dieser speziellen Implementierung ist nicht konserviert. Es droht also über die Zeit zu verblassen und schlußendlich auch verloren zu gehen. Ein solches Spezialwissen ist für viele nachfolgende Prozessschritte in der Softwareentwicklung aber äußerst wertvoll. Damit meine ich explizit das Thema Qualität. Refactoring, Code Reviews, BugFixes und Change Requests sind nur einige der möglichen Beispiele wo tiefgreifendes Detailwissen gefragt ist.
Für mich persönlich kommt auch hinzu, das mich monoton wiederholbare Arbeiten schnell ermüden und ich diese dann sehr gern vermeiden möchte. Sich immer wieder aufs neue mit der selben Testprozedur durch eine Anwendung zu klicken ist weit davon entfernt was für mich einen erfüllten Arbeitstag ausmacht. Ich möchte neue Dinge entdecken. Das kann ich aber nur wenn ich nicht in der Vergangenheit gefangen gehalten werde.
Die trauen sich aber was
Bevor ich aber darauf eingehe wie ich meinen Entwicklungsalltag durch TDD aufgepeppt habe muss ich noch ein paar Worte über Verantwortung und Mut loswerden. Immer wieder wird mir in Gesprächen erklärt das ich ja recht habe aber man können das alles ja nicht selber umsetzen, weil der Projektleiter oder irgend ein anderer Vorgesetzter kein grünes Licht gibt.
Eine solche Einstellung ist in meinen Augen äußerst unprofessionell. Ich frage doch auch nicht den Marketingleiter welcher Algorithmus am besten terminiert. Er hat schlichtweg keine Ahnung, denn es ist auch nicht sein Aufgabengebiet. Ein Projektleiter der sich gegen das testgetriebene Arbeiten im Entwicklungsteam ausspricht hat aber auch seinen Beruf verfehlt. In der heutigen Zeit sind Testframeworks so gut in die Build Umgebung integriert, das die Vorbereitung für TDD sich selbst für unerfahrene Personen in wenigen Augenblicken umsetzen lässt. Es ist also nicht notwendig das Vorhaben an die große Glocke zu hängen. Denn ich kann versprechen das selbst bei den ersten Gehversuchen nicht mehr Zeit benötigt wird als mit der ursprünglichen Vorgehensweise. Ganz im Gegenteil sehr schnell wird sich eine merkliche Erhöhung der Produktivität einstellen.
Die erste Stufe der Evolution
Wie bereits erwähnt ist Logging für mich ein zentrale Teil der testgetriebene Entwicklung. Wann immer es sinnvoll erscheint versuche ich den Zustand von Objekten oder Variablen auf der Konsole auszugeben. Wenn wir hierfür die aus der verwendeten Programmiersprache zur Verfügung gestellten Mittel nutzen, bedeute dies das wir diese Systemausgaben nach getaner Arbeit mindestens auskommentieren müssen und bei späterer Fehlersuche wieder einkommentieren. Ein redundantes und fehleranfälliges Vorgehen.
Nutzen wir hingegen von beginn an ein Logging Framework so können wir die Debug Informationen getrost im Code stehen lassen und deaktivieren diese später im Produktivbetrieb über den eingestellten Log Level.
Ich nutze Logging aber auch als Tracer. Das heißt jeder Konstruktor einer Klasse schreibt während er aufgerufen wird einen entsprechenden Log Eintrag im Log Level Info. Damit kann man sehen in welcher Reihenfolge Objekte instanziiert werden. Hin und wieder bin ich so auch auf die übermäßig oft vorkommende Instanziierung eines einzelnen Objektes aufmerksam geworden. Dies ist hilfreich für Maßnahmen zur Performance und Speicheroptimierung.
Fehler die bei der Ausnahmebehandlung geworfen werden logge ich je nach Kontext als Error oder Warning. Das ist später im Betrieb ein sehr hilfreiches Mittel um Fehlern auf die Spur zu kommen.
Wenn ich also eine Datenbankzugriff habe, schreibe ich also eine Logausgabe im Log Level Debug wie das zugehörige SQL zusammen gebaut wurde. Führt dieses SQL zu einer Exception, weil ein Fehler enthalten ist so wird diese Exception mit dem Log Level Error geschrieben. Findet wiederum eine einfache Suchanfrage mit korrekter SQL Syntax statt und die Ergebnismenge ist leer wird dieses Ereignis je nach Bedarf entweder als Debug oder Warning klassifiziert. Handelt es sich beispielsweise um eine Loginanfrage mit falschem Benutzernamen oder Passwort neige ich dazu mich für den Log Level Warning zu entscheiden, da dies im Betrieb eventuell sicherheitstechnische Aspekte enthält.
Im gesamten Kontext konfiguriere ich das Logging für die Testfallausführung eher sehr geschwätzig und beschränke mich auf eine reine Konsolenausgabe. Im Betrieb wiederum werden die Logging Informationen in eine Logfile geschrieben.
Die Henne oder das Ei
Wenn wir mit dem Logging die Voraussetzung für eine zusätzliche Feedbackschleife gelegt haben stellt sich im nächsten Schritt die Frage wie geht es weiter. Wie bereits erwähnt tue ich mich sehr schwer erst einen Testfall zu schreiben um dann eine entsprechende Implementierung dafür zu finden. Vor diesem Problem stehen auch viele andere Entwickler die mit TDD beginnen.
Eine Sache die ich bereits voraus nehmen kann ist das Problem, das man bei einer Implementierung darauf achten muss diese auch testbar zu halten. Habe ich erst den Testfall so merke ich umgehend ob das was ich gerade erstelle auch wirklich testbar ist. Erfahrene TDD Entwickler haben recht schnell in Fleisch und Blut übernommen wie testbarer Code auszusehen hat. Der wichtigste Punkt hierbei ist das Methoden stets einen Rückgabewert haben sollten, der möglichst nicht null ist. So etwas erreicht man beispielsweise wenn man anstatt null eine leere Liste zurück gibt.
Die Vorgabe einen Rückgabewert zu haben liegt an der Art und Weise wie Unit Test Frameworks arbeiten. Ein Testfall vergleicht den Rückgabewert einer Methode mit einem Erwartungswert. Die Testzusicherung (engl. Assertation) kennt verschiedene Ausprägungen und kann entsprechend: gleich, ungleich, wahr oder falsch sein. Natürlich gibt es hier auch verschieden Variationen. So kann es unter Verwendung von Exceptions möglich sein Methoden die keinen Rückgabewert haben zu testen. Alle diese Details erschließen sich bei der Anwendung in sehr kurzer Zeit. So das jeder ohne langwierige Vorbereitungen umgehend loslegen kann.
Bei der Lektüre des Buches Test Driven Development by Example von Kent Beck finden wir auch schnell eine Erklärung warum die Testfälle zu erst geschrieben werden sollten. Es handelt sich um einen psychologischen Faktor. Es soll uns dabei helfen den üblichen Stress der im Projekt entsteht besser zu bewältigen. Es erzeugt in uns einen mentalen Zustand über den Zustand und Fortschritt der aktuellen Arbeit. Es leitet uns in eine iterativen Prozess die vorhandene Lösung schrittweise über die verschiedenen Testfälle weiter auszubauen und zu verbessern.
Für alle die wie ich aber zu beginn einer Implementierung noch keine konkrete Vorstellung über das fertige Ergebnis haben ist dieser Ansatz schwer umzusetzen. Der bezweckte Effekt der Entspannung kehrt sich ins negative um. Da wir Menschen alle unterschiedlich sind müssen wir also herausfinden wie wir ticken um das bestmögliche Ergebnis zu erzielen. Ganz so wie es mit Lernstrategien ist. Manche Menschen verarbeiten Informationen besser visuell andere eher haptisch und wieder andere extrahieren alles wichtige aus gesprochenem. Versuchen wir uns also nicht wider unserer Natur zu verbiegen um mittelmäßige oder schlechte Ergebnis zu produzieren.
Den ersten Strich zeichnen
Mir erschließt sich ein Thema eben erst während ich damit arbeite. Also Versuche ich mich solange an einer Implementierung bis ich ein erstes Feedback benötige. Genau dann schreibe ich den ersten Test. Es ergebenen sich bei diesem Vorgehen automatisch Fragen bei der jede einzelne einen eigenen Testfall wert ist. Finde ich alle vorhanden Ergebnisse? Was passiert wenn die Ergebnismenge leer ist. Wie lässt sich die Ergebnismenge eingrenzen? Alles Punkte die sich auf einem Zettel notieren und Schritt für Schritt abhaken lassen. Die Idee eine Aufgabenliste auf einem Zettel zu notieren hatte ich schon sehr lange bevor ich das bereits erwähnte Buch von Kent Beck gelesen habe. Es hilft mir schnelle Gedanke zu konservieren ohne mich von meinem aktuellen Tun ablenken zu lassen. Außerdem vermittelt es am Ende des Tages ein Gefühl etwas geschafft zu haben.
Da ich nicht warte bis ich alles Umgesetzt habe, um den ersten Test zu schreiben ergibt sich auch bei diesem Vorgehen ein iterativer Ansatz. Ich merke auch sehr schnell wenn mein Entwurf nur unzureichend testbar ist, da ich sofort eine Rückmeldung erhalte. Daraus ergibt sich meine eigene Interpretation für TDD die sich durch den permanenten Wechsel zwischen Implementieren und Test schreiben auszeichnet.
Als Ergebnis meiner frühen TDD Versuche habe ich bereits in der ersten Woche eine Beschleunigung meiner Arbeitsweise bemerkt. Ich bin auch sicherer geworden. Aber auch die Art und Weise wie ich Programmiere hat sich schon sehr zeitig zu verändern begonnen. Mir ist aufgefallen das mein Code kompakter und robuster geworden ist. Dinge die sich erst mit der Zeit aufgezeigt hatten ergaben sich bei Tätigkeiten wie Refactoring und Erweiterungen. Fehlgeschlagene Testfälle haben mich vor bösen Überraschungen bewahrt.
Ohne Übereifer beginnen
Wenn wir uns in einem bestehenden Projekt dazu entschließen TDD einzusetzen ist es eine schlechte Idee loszulegen und für bestehende Funktionalität Testfälle zu schreiben. Abgesehen von der Zeit die hierfür eingeplant werden muss wird das Ergebnis die hohen Erwartungen nicht erfüllen.
Eines der Probleme ist das man sich nun in jede Funktionalität neu einarbeiten muss und das ist sehr Zeitaufwendig. Die Qualität der so entstandene Testfälle ist auch unzureichend. Das Problem ergibt sich auch aus der Erfahrung. Wird die Erfahrung erst aufgebaut so ist die Qualität der Testfälle auch noch nicht ganz optimal und möglicherweise muss auch Code umgeschrieben werden, damit dieser Testbar wird. Es entstehen also eine Menge Risiken die für das tägliche Projektgeschäft problematisch sind.
Ein bewährtes Vorgehen TDD einzuführen ist es einfach für die aktuelle Implementierung an der man gerade arbeitet einzusetzen. Es wird also der ist Zustand des aktuellen Problems durch automatisierte Tests dokumentiert. Da man sich bereits auf vertrautem Terrain befindet muss man sich nicht erst in eine neue Thematik einarbeiten, so das man sich voll auf das formulieren von aussagekräftigen Tests konzentrieren kann. Abgesehen davon, das man ungefragt Verantwortung über fremde Arbeiten übernimmt wenn man für diese Testfälle umgesetzt.
Bestehende Funktionalität wird nur bei Fehlerkorrekturen entsprechend um Testfälle ergänzt. Für die Korrektur muss man sich eh mit den Implementierungsdetails auseinander setzen, so das hier genügend Wissen vorhanden ist wie eine Funktionalität sich verhalten sollte. Die so entstandene Tests dokumentieren zusätzlich auch die Korrektur und stellen für die Zukunft sicher das sich das Verhalten bei Optimierungsarbeiten nicht verändert.
Folgt man dieser Vorgehensweise diszipliniert verliert man sich nicht in sogenannter hektischer Betriebsamkeit, die wiederum das Gegenteil von Produktivität ist. Zudem erwirbt man so recht schnell fundiertes Wissen wie effektive und aussagekräftige Tests umgesetzt werden können. Erst wenn ausreichend Erfahrung gesammelt wurde und möglicherweise umfangreiche Refactorings geplant werden, dann kann man überlegen wie für das gesamte Projekt die Testabdeckung schrittweise verbessert werden kann.
Qualitätsstufe
Nur weil Testfälle vorhanden sind bedeutet dies nicht das diese auch eine Aussagekraft haben. Genausowenig beweist eine hohe Testabdeckung das ein Programm fehlerfrei ist. Eine hohe Testabdeckung stellt nur sicher das sich ein Programm im Rahmen der Tests verhält.
Wir kann man also sicherstellen das die vorhandene Tests auch wirklich eine Bereicherung sind und eine gute Aussagekraft haben? Der erste und meines Erachtens wichtigste Punkt ist Testfälle möglichst kurz zu halten. Das heißt im Konkreten, das ein Test nur eine explizite Fragestellung beantwortet, z. B. Was passiert wenn die Ergebnismenge leer ist? Entsprechend der Fragestellung ergibt sich dann auch die Benennung der Testmethode. Den Mehrwert dieser Vorgehensweise ergibt sich in dem Moment wenn der Testfall fehlschlägt. Ist der Test sehr kurzgefasst lässt sich oft schon an der Testmethode ablesen worin das Problem besteht, ohne sich erst langwierig in einen Testfall einzuarbeiten zu müssen.
Ein anderer wichtiger Punkt im TDD Vorgehen ist für meine umgesetzte Funktionalität sowohl die Testabdeckung für Codezeilen als auch für Verzweigungen zu überprüfen. Kann ich zum Beispiel in einer IF-Abfrage das Eintreten einer einzelnen Bedingung nicht simulieren, so kann diese Bedingung bedenkenlos gestrichen werden.
Natürlich hat man im eigenen Projekt auch genügend Abhängigkeiten zu fremden Bibliotheken. Nun kann es vorkommen das eine Methode aus dieser Bibliothek eine Ausnahme wirft, die durch keinen Testfall simuliert werden kann. Das ist genau der Grund wieso man zwar eine hohe Testabdeckung anstreben sollte aber nicht verzweifeln muss wenn 100% nicht erreicht werden können. Gerade bei der Einführung von TDD ist ein gutes Maß für die Testabdeckung größer als 85% üblich. Mit wachsender Erfahrung des Entwicklungsteams kann dieser Wert bis zu 95% angehoben werden.
Abschließend ist aber noch anzumerken, das man sich nicht zu sehr in den Eifer begibt. Denn es kann auch schnell übertrieben werden und dann sind die ganzen gewonnene Vorteile schnell wieder dahin. Und zwar geht es um den Punkt das man keine Tests schreibt die wiederum Tests testen. Hier beißt sich die Katze in den Schwanz. Das gilt auch für Bibliotheken von Fremdanbietern. Für diese werden ebenfalls keine Test geschrieben. Kent Beck äußert sich hierzu sehr klar: Selbst wenn es gute Gründe gibt dem Code anderer zu misstrauen, teste ihn nicht. Externer Code erfordert mehr eigene Implementierungslogik.
Lessons Learned
Gerade die Erkenntnisse die sich bei dem Versuch eine möglichst hohe Testabdeckung zu erzielen sind die, welche sich beim künftigen Programmieren auswirken. Der Code wird kompakter und robuster.
Die Produktivität steigt einfach durch die Tatsache, das fehleranfällige und monotone Arbeiten durch Automatisierung vermieden werden. Es entstehen keine zusätzlichen Arbeitsschritte denn alte Gewohnheiten werden durch neue, bessere ersetzt.
Ein Effekt den ich immer wieder beobachten konnten, wenn sich einzelne Personen aus dem Team für TDD entschieden haben, wurden deren Erfolge schnell beachtet. Innerhalb weniger Wochen hat dann das gesamte Team TDD entwickelt. Jeder einzelne nach seinen eigene Fähigkeiten. Manche mit Test First andere wiederum so wie ich es gerade beschrieben habe. Zum Schluß zählt das Ergebnis und das war einheitlich hervorragend. Wenn die Arbeit leichter fällt und am Ende des Tages jeder einzelne auch noch das Gefühl hat auch etwas geleistet zu haben bewirkt dies im Team einen enormen Motivationsschub, der dem Projekt und dem Arbeitsklima eine gewaltigen Auftrieb verschafft. Also worauf warten Śie noch? Probieren Sie es am besten gleich selber aus.
Die im Oktober 2023 veröffentlichten neuen AGB für Microsoft-Dienste lösten in der IT-Welt einen Aufschrei aus. Der Grund war ein Absatz, in dem es hieß, dass mittlerweile alle Microsoft-Dienste auf künstlicher Intelligenz basieren. Diese K.I. soll dazu dienen, Urheberrechtsverletzungen zu erkennen. Dazu gehören Dinge wie Musik, Filme, Grafiken, E-Books und natürlich auch Software. Falls diese K. I. Urheberrechtsverletzungen auf dem System erkennt, sollten diese Dateien automatisch vom „System“ gelöscht werden. Derzeit ist nicht klar, ob diese Regel für die eigene lokale Festplatte oder nur für die Dateien in der Microsoft Cloud gilt. Microsoft hat außerdem erklärt, dass Benutzer, die gegen die Urheberrechtsbestimmungen verstoßen, künftig von allen Microsoft-Diensten ausgeschlossen werden sollen.
Dieser Ausschluss hat verschiedene ‘Geschmäckle’. Die ersten Fragen, die mir in den Sinn kommen, sind: Was passiert mit kostenpflichtigen Abonnements wie Skype? Werde ich gesperrt und anschließend wird mein ungenutztes Guthaben zurückerstattet? Ein noch schlimmeres Szenario wäre, dass ich möglicherweise auch all mein Guthaben und digitale Käufe wie den Zugang zu Spielen und anderen Dingen verliere. Oder sind kostenpflichtige Abonnements davon nicht betroffen? Bisher ist dieser Teil nicht klar.
Wer ein Apple Nutzer ist und denkt, dass dies keine Auswirkungen auf Applegeräte hat, sollte sicherstellen, dass keine Microsoft-Dienste verwendet werden. Möglicherweise wissen sie nicht, dass dieser zu Microsoft gehört. Nicht jedes Produkt enthält den Firmennamen. Denken Sie darüber nach, denn wer weiß, ob diese Produkte Ihr System ausspionieren. Einige Anwendungen wie Skype, Teams, Edge Browser und Visual Studio Code sind auch für andere Plattformen wie Apple und Linux verfügbar.
Microsoft besitzt außerdem die Quellcode-Hosting-Plattform GitHub und ein soziales Netzwerk für Spezialisten namens LinkedIn. Mit Office 360 können Sie die gesamte Microsoft Office Suite per Webbrowser als Cloud-Lösung nutzen und alle Ihre Dokumente werden in der Microsoft Cloud gespeichert. Dieselbe Cloud, in der US-Regierungsinstitutionen wie die CIA, die NSA und viele andere ihre Dateien aufbewahren. Nun, es scheint wohl ein sicherer Ort für alle Ihre Gedanken zu sein, die in ein Office Dokument niedergeschrieben wurden.
Dieses kleine Detail zu Office-Dokumenten führt uns zu einer weiteren Randbemerkung in den neuen Geschäftsbedingungen von Microsoft. Der Kampf gegen Hassrede. Was auch immer das heißt. Öffentliche Beleidigungen und Verleumdungen werden seit jeher vom Gesetzgeber strikt als Straftat behandelt. Es ist kein Kavaliersdelikt, der mit einem kleinen Bußgeld geahndet wird. Daher ist mir nicht klar, was dieses ganze Gerede über Hassreden bedeutet. Vielleicht ist es ein Versuch, eine öffentliche Zensur der Meinungsfreiheit einzuführen.
Aber zurück zum Randhinweis der Microsoft-Nutzungsbedingungen zu Hassreden. Microsoft hat so etwas geschrieben wie: Wenn Hassreden festgestellt werden, wird der Benutzer verwarnt und wenn die Verstöße mehrmals auftreten, wird das Microsoft-Konto des Benutzers deaktiviert.
Wenn Sie vielleicht denken, dass dies nur etwas ist, was jetzt bei Microsoft passiert, seine sie sich im klaren, dass viele andere Unternehmen ebenfalls daran arbeiten, solche Bestimmungen für ihre Produkte einzuführen. Die Kommunikationsplattform Zoom beispielsweise beinhaltete auch K. I. Techniken, um die Benutzerkommunikation zu ‘Trainingszwecken’ zu beobachten.
Bei all diesen Neuigkeiten stellt sich eine große Frage, die beantwortet werden muss: Was kann ich selbst tun? Die Lösung ist einfach. Verlassen Sie das digitale Universum und gehen Sie zurück in die reale Welt. Schalten Sie das Gehirn wieder ein. Benutzen Sie Stift und Papier, zahlen Sie bar, lassen Sie Ihr Smartphone zu Hause und dort niemals auf dem Nachttisch. Wenn Sie es nicht verwenden, schalten Sie es aus! Treffen Sie Ihre Freunde, wann immer es möglich ist physisch und bringen Sie dazu nicht Ihr Smartphone mit. Es wird keine Regierung, keinen Präsidenten und keinen Messias geben, die eine Veränderung herbeiführen wird. Es ist an uns, dies zu tun.
Zu argumentieren, dass Privatsphäre für dich nicht wichtig ist, weil du nicht zu verbergen hast, ist das Gleiche wie zu sagen, das Meinungsfreiheit unwichtig ist, weil man nicht zu sagen hat.
README Dateien haben in Softwareprojekten eine lange Tradition. Diese ursprünglich reinen Textdateien enthielten Lizenzinformationen und Anweisungen wie aus dem Quellcode das entsprechende Artefakt kompiliert werden konnte oder aber wichtige Hinweise zu Installation des Programms. Es gibt keinen wirklichen Standard, wie man eine solche README Datei aufbauen sollte.
Seit dem GitHub (2018 von Microsoft übernommen) als kostenfreie Code Hosting Plattform für Open Source Projekte seinen Siegeszug angetreten ist, gab es schon recht früh die Funktion, dass die README Datei als Startseite des Repositories anzuzeigen. Dazu muss lediglich eine einfache Textdatei mit der Bezeichnung README.md im Hauptverzeichnis des Repository erstellt werden.
Um die README Dateien übersichtlicher strukturieren zu können, wurde eine Möglichkeit für eine einfache Formatierung gesucht. Schnell hatte man sich für die markdown Notation entschieden, da diese einfach zu nutzen ist und auch recht performant gerendert werden kann. Somit sind die Übersichtsseiten besser für Menschen zu lesen und können als Projektdokumentation genutzt werden.
Es ist möglich, mehrere solcher markdown Dateien als Projektdokumentation miteinander zu verknüpfen. Somit erhält man eine Art Mini WIKI das im Projekt enthalten ist und außerdem auch über Git versioniert wird.
Das Ganze wurde so erfolgreich, das Selfhosting-Lösungen wie GitLab oder das kommerzielle BitBucket diese Funktion ebenfalls übernommen haben.
Nun stellt sich aber die Frage welche Inhalte man am besten in solch eine README Datei schreibt, damit diese für Außenstehende auch einen wirklichen Mehrwert darstellen. Dabei haben sich im Laufe der Zeit folgende Punkte etabliert:
Kurzbeschreibung des Projekts
Bedingungen, unter denen der Quellcode verwendet werden darf (Lizenz)
Wie ist das Projekt zu verwenden (z.B. Anweisungen zum Compilieren oder wie wird die Bibliothek in eigene Projekte eingebunden)
Wer sind die Autoren des Projekts und wie kann man sie erreichen
Was ist zu tun wenn man das Projekt unterstützen möchte
Mittlerweile sind sogenannte Badges (Sticker) sehr populär. Diese referenzieren oft auf externe Dienste, wie beispielsweise der freie Continuous Integration Server TravisCI. Diese helfen Ausstehenden, die Qualität des Projekts zu beurteilen.
Auf GitHub gibt es auch diverse Vorlagen für README Dateien. Man muss allerdings auch ein wenig auf die tatsächlichen Gegebenheiten des eigenen Projekts schauen und beurteilen, welche Informationen für Nutzer bzw. Anwender wirklich relevant sind. Solche Vorlagen helfen aber sehr dabei, herauszufinden, ob man möglicherweise einen Punkt übersehen hat.
Da mittlerweile ziemlich jeder Hersteller von Source Control Management Serverlösungen die Funktion die README.md Datei als Projektstartseite für das Code Repository anzuzeigen integriert hat, bedeutet das eine README.me auch für kommerzielle Projekte eine sinnvolle Sache sind.
Auch wenn die Syntax für markdown leicht zu erlernen ist, kann es bei umfangreichen Editierungen solcher Dateien durchaus komfortabler sein, direkt einen MARKDOWN Editor zu nutzen. Dabei sollte man darauf achten, dass die Vorschau auch korrekt dargestellt wird und nicht nur ein einfaches Syntaxhighligting angeboten wird.
Auf alle Fälle lohnt sich ein Blick auf die GitHub Seite https://www.readme-templates.com zu werfen. Weitere Ressourcen zum Thema finden sich hier:
[EN] We use cookies to improve your experience on our site. By using our site, you consent to cookies.
[DE] Wir verwenden Cookies, um Ihre Erfahrungen auf unserer Website zu verbessern. Durch die Nutzung unserer Website stimmen Sie Cookies zu.
This website uses cookies
Websites store cookies to enhance functionality and personalise your experience. You can manage your preferences, but blocking some cookies may impact site performance and services.
Essential cookies enable basic functions and are necessary for the proper function of the website.
Name
Description
Duration
Cookie Preferences
This cookie is used to store the user's cookie consent preferences.
30 days
These cookies are needed for adding comments on this website.
Name
Description
Duration
comment_author
Used to track the user across multiple sessions.
Session
comment_author_email
Used to track the user across multiple sessions.
Session
comment_author_url
Used to track the user across multiple sessions.
Session
These cookies are used for managing login functionality on this website.
Name
Description
Duration
wordpress_logged_in
Used to store logged-in users.
Persistent
wordpress_sec
Used to track the user across multiple sessions.
15 days
wordpress_test_cookie
Used to determine if cookies are enabled.
Session
Statistics cookies collect information anonymously. This information helps us understand how visitors use our website.
Matomo is an open-source web analytics platform that provides detailed insights into website traffic and user behavior.