Unterlagen zu “Ruby und Rails für .Net Entwickler” (Luzern)
Die .Net User Group Zentralschweiz gab mir Anfangs Woche die Gelegenheit meinen Ruby und Rails Vortrag für .Net Entwickler zu präsentieren. Gut 6 Monate nach der ersten Präsentation bei der .Net User Group Bern konnte ich so nochmals rund 30 .Net Entwicklern zeigen das es neben C# noch andere interessante Programmiersprachen gibt.
In den letzten Monaten gab es bei Ruby und Rails einige entscheidende Neuerungen. Ruby ist zum 20. Geburtstag in der Version 2 erschienen und Rails 4 liegt nun als Beta vor. Für mich Grund genug neben dem Vortrag auch die Beispiele anzupassen.
Unterlagen
Die Präsentation findet sich auf Speakerdeck und kann dort auch als PDF heruntergeladen werden.
Beispiele
Die grössere Beispielanwendung zu den Alltagsszenarien habe ich in Rails 4 Beta 1 neu erstellt. Die Aufgabenstellung ist noch dieselbe, die Entwicklungswerkzeuge sind aber um die hilfreichen Tools rund um die Fehlerbehandlung erweitert worden.
Vergleicht man die neue Beispielanwendung mit der für Rails 3.2 kann man so auch die Unterschiede (wie Strong Parameters) zwischen den Rails-Versionen sehen.
Weiterführende Informationen
Damit man sich die Links nicht aus den Folien zusammensuchen muss:
Webseiten & Tools
Tools für Windows
Podcasts & Videos
Bücher
- Seven Languages in Seven Weeks (Rezension)
- Programming Ruby 1.9 (Rezension)
- Practical Object-Oriented Design in Ruby (Rezension)
- Rails 4 in Action
- The Rails View (Rezension)
- Continuous Testing (Rezension)
In meinem Blog sind alle Beiträge zu Ruby & Rails mit dem Tag “Ruby“ versehen.
Danke
Als Abschluss möchte ich mich nochmals bei der .Net User Group Zentralschweiz und den Teilnehmern bedanken. Neben der grossen Teilnehmerzahl freuten mich besonders die guten Gespräche in der Pause und nach dem Vortrag. Ich finde es toll dass es auch in Luzern eine so vielfältige .Net User Group gibt.
Buch-Rezension zu “Practical Object-Oriented Design in Ruby”
Ein gutes Buch über objektorientiertes Design (OOD) zu finden ist nicht einfach. Obwohl sich viele Bücher diesem Thema widmen fehlt doch immer wieder etwas: Entweder ist das Buch so theoretisch das es keinen Bezug zur Praxis hat oder die notwendige Theorie fehlt.
“Practical Object-Oriented Design in Ruby” (kurz POODR) von Sandy Metz findet den Mittelweg zwischen Theorie und Praxis. In einer direkten Sprache wird man Schritt für Schritt an die Thematik OOD herangeführt.
Auch wenn die Beispiele in Ruby sind so ist dieses Buch auch für andere Sprachen sehr zu empfehlen – das benötigte Wissen über Ruby ist minimal und schnell erklärt.
Wozu OOD?
Sandy Metz definiert OOD als die Art und Weise wie man Code in einem Programm anordnet. OOD ist somit nicht nur etwas für Experten sondern betrifft jeden Programmierer. Denn jeder der Code schreibt beeinflusst dessen Design.
Design is more the art of preserving changeability than it is the act of achieving perfection.
Ob eine Erweiterung später einfach einzubauen ist hängt von den heute getroffenen Entscheidungen ab. Oft fehlt aber die Erfahrung und das Wissen wie sich Entscheidungen auswirken. Dieses Buch zeigt einem wie kleine Veränderungen die Erweiterbarkeit beeinflussen und was für Vor- und Nachteile die einzelnen Ansätze von OOD mitbringen. Dies ersetzt zwar nicht das Sammeln von eigenen Erfahrungen, bietet einem aber eine gute Ausgangslage um nicht alle Fehler selber machen zu müssen.
Einfache Beispiele
Nach all den Banken und Blogs kommen hier Fahrräder für die Beispiele zum Einsatz. Durch die Optimierung für E-Reader sind die Beispiele recht kurz. So lässt sich der Code übersichtlich darstellen und ist als Nebeneffekt einfach zu verstehen. Im Gegensatz zu anderen Büchern kann man sich so auf die Beispiele konzentrieren und muss nicht ständig hin und her blättern.
Das entscheidende bei den Beispielen ist der Weg zum Ziel. Daher gibt es entsprechend viele kleine Schritte die ausführlich erläutert werden. Allerdings führen nicht alle Schritte in die richtige Richtung. Umwege und falsche Ansätze werden in diesem Buch ebenfalls thematisiert und erklärt.
So kann man auf wenigen Seiten Erfahrungen sammeln die bei einem richtigen Projekt Monate an Arbeit verursachen.
Tests
Dem Thema Tests widmet sich das letzte Kapitel. Die in den vorherigen Kapiteln erarbeiteten Beispiele werden hier nun getestet. Man sieht so rasch wie die verschiedenen Ansätze von OOD sich auf die Testbarkeit von Code auswirken.
Sehr gelungen finde ich wie die Stolperfallen präsentiert werden. Der Mock für die Tests mag noch so gut sein. Wenn sich die Klasse ändert und der Mock dies nicht mitbekommt ist zwar der Test grün aber die Software läuft nicht. Die gezeigten Lösungen sind zwar auf dynamisch typisierte Programmiersprachen ausgerichtet, können aber auch bei C# beim Erkennen von Veränderungen helfen.
Was fehlt
Die gewählten Beispiele sind alle recht Kurz und meist weniger als 100 Zeilen lang. Auch wenn kurze Klassen und Methoden anzustreben sind so ist die Realität doch oft anderes. Ein längeres Beispiel bei dem man mittels OOD Ordnung hinein bringt hätte ich sehr begrüsst.
Weitere Informationen
Wer sich für OOD interessiert aber nicht gleich ein Buch dazu lesen will wird auf Confreaks fündig. Dort gibt es als Video abrufbare Präsentationen von Sani Metz die einzelne Konzepte aus dem Buch aufgegriffen.
Wer lieber Podcasts hört findet in Episode 87 von Ruby Rogues eine ausführliche Buchbesprechung mit zahlreichen Tipps rund um OOD die im Buch keinen Platz gefunden haben.
Fazit
POODR ist ein angenehm zu lesendes Buch das sehr viel Wissen vermittelt. Obwohl ich mich schon länger mit OOD beschäftige konnte ich hier ganz neue Aspekte kennen lernen. Die Beispiele sind so einfach das man davon nicht abgelenkt wird und doch komplex genug um all die verschiedenen Möglichkeiten zu erklären.
Für mich ist dieses Buch definitiv ein „Must Read“ für alle die sich mit Software-Entwicklung beschäftigen.
Zum Buch
“Practical Object-Oriented Design in Ruby” von Sandy Metz, 2012 Addison-Wesley Professional, ISBN: 978-0-3217-2133-4, 272 Seiten, Englisch
EF 5: Modelle übersichtlicher gestalten
Ob man nun “Model-First” oder “DB-First” folgt, bei Entity Framework steht man schnell einmal vor einem Problem: Das Datenmodell verliert an Übersichtlichkeit.
Die oft verwendeten Beispiele mit wenigen Tabellen und Verbindungen sehen im Designer von Visual Studio prima aus. Hat man aber ein komplexeres Modell steht man bald einmal vor so einer Ansicht:
Auch wenn man sehr viel Zeit aufwendet um die Entitäten hin und her zu ziehen, so bleibt das Modell doch unübersichtlich. Verwendet man Entity Framework 5 und Visual Studio 2012 gibt es aber 2 Hilfsmittel die einem bei der Organisation helfen können.
Farben
Mit Hilfe von Farben kann man thematisch zusammenhängende Bereiche hervorheben. Dazu klickt man im Designer die gewünschte Tabelle (oder mittels der Hilfe von CTRL mehrere) an und wählt in den Properties die entsprechende Füllfarbe (Fill Color):
Die Farben haben einzig im Designer eine Bedeutung und beeinflussen das Modell nicht. Mit wenig Aufwand sieht das Diagramm dann so aus:
Diagramme
Für grosse Modelle sind die Farben zwar ein Anfang, doch ist man damit noch nicht am Ziel. Neu kann man das Modell aber in verschiedene Diagramme aufteilen. Die entsprechende Funktion findet sich im Model Browser unter Diagramme:
Die gewünschten Entitäten können nun auf dieses neue Diagramm gezogen werden. Man muss dies aber nicht für jede Entität einzeln machen. Über das Kontextmenü auf einer Entität kann man mit “Include Related” alle verbundenen Entitäten auf einmal einfügen lassen.
Die so erzeugten Diagramme behandeln nur noch den Ausschnitt aus dem Modell den man genauer betrachten möchte:
Beim Löschen von Entitäten aus dem Diagramm muss man aufpassen. Mittels “Delete from Model” wird die Entität aus dem Modell gelöscht und ist danach über den DB-Kontext nicht mehr abrufbar. In der Regel will man stattdessen die Funktion “Remove from Diagram” nutzen. So wird nur das Diagramm angepasst und das Modell bleibt unverändert.
Fazit
Mit Hilfe von Farben und zusätzlichen Diagrammen kann man Ordnung in sein DB-Modell bekommen. So kann man auch grössere Datenbanken in Entity Framework benutzen ohne die Übersicht zu verlieren.
Die Testpyramide
Seit einigen Monaten stosse ich immer wieder auf das Konzept der Testpyramide. Ich finde dieses Bild sehr passen, da es die wesentlichen Aspekte auf den Punkt bringt. Um ein System wirklich zu testen gilt es mehrere Ebenen anzuschauen. Die Testpyramide zeigt diese auf und vermittelt auf eine leicht verständliche Weise wie sich die Anzahl der Testfälle staffeln soll:
Unit-Tests als Grundlage
Unit-Tests bilden die Basis der Testpyramide. Die kleinstmöglichen Tests sollten sicherstellen dass das System im Kern funktioniert. Eine wichtige Eigenschaft von Unit-Tests: Sie sind Schnell. In wenigen Sekunden sollte man wissen ob es überhaupt Sinn macht die länger laufenden Tests zu starten. Diese Sekunden sind wohlgemerkt nicht für einen einzigen Tests gedacht, sondern für alle Unit-Tests zusammen – womit ein Unit-Test der länger als 1/100 Sekunde dauert schon als langsam gelten muss.
Damit Tests so schnell sind dürfen sie nur wenig testen. Weder eine Verbindung zur Datenbank noch ein Zugriff aufs Dateisystem oder Aufruf eines Webservices ist erlaubt. All diese Abhängigkeiten müssen entfernt werden. Ob dies mittels Konfiguration oder mit Mocks gemacht wird spielt dabei keine Rolle.
Die Geschwindigkeit alleine kann aber nicht das einzige Kriterium für einen Unit-Test sein. Sonst besteht die Testsuite am Ende nur aus leeren Methoden. Das was man testet soll auch noch Sinn machen. Und einem in die richtige Richtung weisen wenn einmal ein Test fehlschlägt. So ist man schnell einmal bei mehreren Kriterien die von Ben Rady und Rod Coffin in “Continuous Testing” mit dieser Abkürzung zusammengefasst werden:
FIRE: Fast, Informative, Reliable and Exhaustive
Integrationstests
Zu wissen dass der eigene Code für sich alleine funktioniert ist ein Anfang. Damit weiss man aber noch nicht ob der Code auch mit anderen Teilen funktioniert. Hier kommen die Integrationstests ins Spiel.
Auf dieser Ebene werden all die Abhängigkeiten angeschaut die man bei den Unit-Tests entfernt hat. Was zuerst nach vermeidbarem Zusatzaufwand aussieht hat sehr wohl seine Berechtigung. Es genügt wenn man das Erzeugen, Speichern, Aktualisieren und Löschen eines Objekts in der Datenbank ein Mal pro Klasse testet. Dies hat die gleiche Aussagekraft (ist aber deutlich schneller) wie wenn man in allen Unit-Tests immer mit den Objekten aus der Datenbank arbeiten würde.
Da weniger Tests mit den Umsystemen nötig sind wirkt sich deren Ausführungsdauer nicht so stark auf die Länge des gesamten Testlaufs aus.
Akzeptanztests
Die Akzeptanztests bilden die Spitze der Testpyramide. Hier gilt es die Anwendung aus Sicht des Benutzers zu testen. Vom GUI durch die Geschäftslogik hin zur Datenbank und den externen Webservices soll hier alles geprüft werden.
Da man bereits weis das sowohl der Kern der Anwendung funktioniert und der auch mit den Umsystemen korrekt zusammenarbeitet benötigt man nur noch wenige Akzeptanztests. Diese dürfen noch einmal langsamer sein als die Integrationstests und sollen als letzte Stufe die Korrektheit der gesamten Anwendung belegen.
Und da es so wenige Tests sind kann man diese auch mit dem Kunden/Endbenutzer besprechen. Müssen wirklich nur die wichtigsten Tests angeschaut werden hat man gute Chancen dass dies auch wirklich gemacht wird.
Reihenfolge & Einschränkungen
Die Testpyramide gibt keine Reihenfolge für die Erstellung der Testfälle vor. Wenn es bei der Ausführung auch am meisten Sinn macht mit den Unit Tests zu beginnen so ist man beim Erstellen frei.
Hat man Glück und der Kunde will an Akzeptanztests mitarbeiten kann man einen Top-Down Ansatz wählen. Man beginnt mit einem fehlgeschlagenen Akzeptanztest und schreibt so lange Integrations- und Unit-Tests bis dieser erfüllt wird. Alternativ kann man aber auch mit den Unit-Tests beginnen und sich nach oben arbeiten.
Die Testpyramide ist aber nicht perfekt. Es gibt etliche Testarten die darin keinen Platz finden. Wo platziert man beispielsweise die Explorationstests? Oder die Performancetests? Trotz dieser Einschränkungen finde ich das Bild der Testpyramide sehr gelungen.
TDD: Denken erlaubt
Test-Driven Development (TDD) gibt auch heutzutage noch viel zu diskutieren. Was mir dabei immer wieder auffällt: Es scheint als ob vor lauter Red-Green-Refactor vergessen geht das man eigentlich Software entwickeln soll. Sobald man sich mit Tests beschäftigt vergisst man das grosse Ganze. Oder wieso schreiben gestandene Software-Entwickler einen Test nach dem anderen der ihnen nur bestätigt das 1 + 1 wirklich 2 ergibt?
Code Katas als Ursache?
Code Katas sollen einem dabei helfen sich bei einer Übung auf einen bestimmten Aspekt zu konzentrieren. Dieser Aspekt ist oft TDD, doch gibt es genügend andere Aspekte die man in den Vordergrund stellen kann (wie die Bedienung der IDE nur mit der Tastatur oder Patterns wie das Single Responsibility Principle).
Will man damit TDD erproben nimmt man in der Regel ein ganz einfaches Beispiel. Man will sich ja nicht lange mit dem Problem beschäftigen sondern TDD lernen. Entsprechend schreibt man viele Tests und denkt wenig über die Lösung nach – diese ist ja durch einfache Beispiele wie FizzBuzz gewollt. Man trainiert also ständig mit einfachen Beispielen und vielen Tests. Die Videos zu diesen Trainings zeigen entsprechend viele Tests und wenig Gedanken über die Lösung.
Kurzum: Der Feedback-Loop für den Entwickler zeigt ganz klar dass er TDD erst richtig macht wenn wer viel testet und wenig denkt. Das Problem ist nur das dies komplett falsch ist.
Software-Entwicklung vor TDD
Gehen wir einen Schritt zurück. Bevor man mit TDD Software entwickeln wollte machte man in der Regel diese Schritte:
- Problem analysieren
- Lösung erarbeiten
- Programmieren
- Testen
- Veröffentlichen
- Bugs fixen
- Veröffentlichen
Bei der iterativen Software-Entwicklung folgt man ebenfalls dieser Schrittfolge – einzig der Umfang behandelt nicht mehr das ganze System sondern nur einen Teil.
Die Idee von TDD war es ursprünglich einmal die Schritte 3 & 4 zu kombinieren. So hoffte man die teure Behebung von Bugs nach der Veröffentlichung zu minimieren. Nie war es das Ziel die Phase der Problemanalyse oder dem Erarbeiten der Lösung zu streichen.
Babysteps ins Chaos
Die Analyse der Problemstellung und das erarbeiten der Lösung ging irgendwo bei der Einarbeitung in TDD verloren. Irgendwann sollten Babysteps (wie 1+1 = 2) die Verständnislücken der Problemstellung füllen und die Lösung herausfallen. Nur wo passiert dies? Viel eher stehen all die minimalen Tests nur im Weg und erschweren die Weiterentwicklung der Software. Alleine mit Babysteps lösen wir das Problem nicht.
Schrittgrösse variieren
Wie aber geht man “richtig” vor? Kent Beck zeigt in “TDD By Example” wie man erst das Problem analysieren soll, eine Liste mit Testfällen (und noch anzugehenden Problemen) führt und vor allem wie man die Schrittgrösse variieren kann.
Das Red-Green-Refactor soll man beibehalten. Aber wenn man weiss wo hin man will und welche Lösung man verfolgt kann man grössere Schritte machen. Wie gross diese Schritte sind hängt vom konkreten Problem, der Vertrautheit mit der Technologie und dem angepeilten Lösungsweg ab.
Für den Lösungsweg greife ich oft auf Flussdiagramme zurück. So altmodisch die auch sein mögen, für eine grobe Skizzierung der Abläufe finde ich diese Art der Darstellung sehr hilfreich. Auch in der objektorientierten Programmierung gibt es unzählige Teilaufgaben die mit einem Flussdiagramm ideal abgebildet werden können.
Mit wenigen Worten pro Tätigkeit kann ich die einzelnen Kernaufgaben herausarbeiten. Ich sehe so auf einen Blick was alles zur Lösung dazu gehört und was es für Abhängigkeiten gibt. Passende Testfälle (und damit die Schrittgrösse) lassen sich so ebenfalls finden. Beim Programmieren tauchen dann immer noch genügend neue Testfälle auf. Diese können aber auch erst einmal nur auf eine Liste abgelegt und erst später priorisiert (oder gelöscht) werden.
Beispiele
Für das was ich bisher beschrieben habe gibt es zahlreiche gute Beispiele. Besonders empfehlen kann ich den Pluralsight-Kurs “Outside-In Test-Driven Development” von Mark Seemann. Darin wird erklärt wie man mit TDD bei den Akzeptanztests beginnt und schrittweise verfeinert bis der notwendige Code geschrieben ist. Beginnt man mit den Akzeptanztests verliert man das eigentliche Ziel nicht aus den Augen. Das Mantra Red-Green-Refactor bleibt gültig ohne dass man sich in den Babysteps verliert. Und sind diese kleinen Schritte doch nötig hat man ein Rahmenwerk das einem daran erinnert wann genug ist.
Wer Bücher bevorzugt findet in “Rails 4 in Action” von Ryan Bigg eine ausführliche Anleitung um testgetrieben eine Webanwendung zu erstellen. Hier wird noch mehr Wert auf die praktische Implementierung von TDD gelegt und gezeigt wie man mit unterschiedlichen Testebenen zu einer Lösung kommt.
Fazit
Nur weil man TDD macht muss man noch lange nicht aufhören selber zu denken. Eine Analyse der Lösung und ein grober Lösungsweg braucht es noch immer bevor man sich dem programmieren zuwendet. Verzichtet man auf diese grundlegenden Dinge schiebt man nur Code herum. Dies ist nicht nur ineffizient sondern auch teuer – sowohl beim erstmaligen schreiben wie auch bei all den kommenden Änderungen.
Daher unbedingt erst einmal abklären was man eigentlich machen will. Ist das “Was” klar geht es ans “Wie”. Ob man dazu ein Flussdiagramm oder eine sonstige Skizze macht spielt keine Rolle – wichtig ist das man sich überlegt wie man vorgehen will. TDD und Red-Green-Refactor können viel besser, klarer und sinnvoller angewendet werden wenn man diese Vorarbeiten macht.
Das passende Gem finden
Für Ruby und Rails gibt es unzählige Helfer. Diese als Gem bezeichneten Pakete zu finden ist eine Herausforderung. Nicht weil es zu wenig Gems gibt, sondern weil so viele verschiedene Ansätze zur Auswahl stehen. Nicht nur für Einsteiger ist es schwer sich zu entscheiden. Soll man nun das nehmen was gerade “In” ist oder ist ein älteres Paket besser? Wie steht es um die Aktualität? Und wo findet man die Dokumentation?
Vor diesen Problemen stand auch Christoph Olszowka. Seine Lösung dazu war ein Verzeichnis zu starten bei dem die einzelnen Gems gesammelt und bewertet werden. Seit Ende 2011 ist diese Sammlung auf Ruby-Toolbox.com abrufbar.

Die Gems werden nach Thema gruppiert und mit anderen Vertretern der gleichen Kategorie verglichen. Die Balkengrafik zeigt einem auf einen Blick welche Gems in der gewählten Kategorie beliebt sind. Links zur Webseite, der Dokumentation und zum Bug Tracker helfen einem sich schnell ein eigenes Bild zu machen. Und da man auch gleich sieht wie aktiv daran entwickelt wird erspart man sich böse Überraschungen.

Mir gefällt neben der Übersichtlichkeit der Seite vor allem die Erklärung wie die Werte zustande kommen. Hier gibt es keine “magische” Blackbox die die Projekte bewertet, sondern eine Formel die man selber überprüfen kann.

Ruby-Toolbox.com ist für mich die Anlaufstelle wenn ich ein Gem für eine spezielle Aufgabe suche. Darüber hinaus ist es auch ein guter Platz um zu schauen wie vielfältig das Ruby-Ökosystem ist und was es alles für fertige Lösungen gibt.
Mein Tipp: Unbedingt anschauen!
MS SQL Server: Login mittels Passwort aktivieren
Obwohl es kaum etwas Einfacheres gibt stosse ich bei der Arbeit mit dem SQL Server immer wieder auf ein Problem: Wieso kann ich nicht mit dem angegebenen Benutzernamen und Passwort auf die Datenbank zugreifen?
Die Fehlermeldung bleibt ja mit Absicht wage:
Schaut man ins Event Log findet man die Ursache:
Login failed for user 'demo'. Reason: An attempt to login using SQL authentication failed. Server is configured for Windows authentication only. [CLIENT: ]
Auch bei diesem Server ist bisher nur ein Login mittels Windows-Authentifizierung erlaubt. Dies lässt sich aber schnell ändern. Dazu genügt es das Microsoft SQL Server Management Studio als Administrator zu starten und mittels Rechtsklick auf den Servernamen die Eigenschaften aufzurufen. Unter Security kann man dem SQL Server erlauben die Benutzer selber zu authentifizieren:
Nach einem Neustart des SQL Server funktioniert der Login mittels Benutzername und Passwort wie gewünscht.
Kann man das SQL Server Management Studio verwenden ist diese Option schnell aktiviert – man muss nur daran denken dies auch zu tun. Hat man diese Möglichkeit wegen fehlenden Berechtigungen oder Security-Anforderungen nicht, wird es mühsam. In diesem Fall ist die Anleitung von Sven Schmalle sehr hilfreich.












