Spartakiade – Marathonlauf für Entwickler

Am Wochenende von 21-22. März hat im Berlin die vierte Spartakiade stattgefunden. Die Idee der Veranstaltung ist einfach: eine Open Space-(Un)Konferenz, die ausschließlich aus Workshops besteht.

Ich habe bisher noch nie geschafft, die Spartakiade zu besuchen. Bis jetzt. Mein Urteil: volle Punktzahl. Diese zwei Tage machen zusammen mit den anderen Open Space Events (Developer Open Space in Leipzig, Open Space Süd in Karlsruhe und Shorty Open Space, der immer spontan via Twitter organisiert wird ) die Sache rund.

Wir waren über 100 Teilnehmer, die in den 2 Tagen 19 Workshops besucht haben. Unsere Coaches genau so wie die Organisatoren sind really most valuable persons der Community, die mehr als unseren Dank verdienen: ein großer fetter Dank von mir nochmal an euch alle (ich hätte Angst, dass ich jemanden vergesse, deshalb schreibe ich hier keine Namen. Aber sie sind alle auf der Homepage der Spartakiade zu finden).

Ich meine, es ist schon großartig, dass wir die Workshops unter traumhaften Bedingungen, in den Räumlichkeiten von Immobilienscout24 haben dürften. Aber einen vollen Kofferraum Gadgets zu besorgen um das Workshop “Smart Things” vorzubereiten, oder neben der Arbeit sich in das Thema Graphdatenbanken einzuarbeiten UND die Präsentation an die 15 oder so “ausgehungerten” Entwickler vorzustellen –  nur um zwei von den Workshops zu erwähnen – , das macht man nicht mal so. Genauso wenig, wie für das Mittagessen mal 1 bis 3 Stunden im verregneten und kalten Berlin neben dem Grill auf der Straße zu stehen und für den zweiten Tag sich einen Burger-Wagen auszudenken, dann ist das schon viel viel mehr, was man normalerweise tun muss. Sowas entsteht nur durch voller Hingabe.

Ich habe hier keine Details über die Workshops, die ich besucht habe, genannt, weil sie auf jedem Fall eigene Blogposts verdienen. Ich kann nur eine Bemerkung eines Kollegen zurückgeben: “die Kosten, die durch dieses Wochenende entstanden sind, sind peanuts im Vergleich dazu, wie viel wir gelernt haben und wie viel return-of-investment aus dieser Investition entstehen wird!”

Wie gesund ist eigentlich mein Code?

 

software quality metric: A function whose inputs are software data and whose output is a single numerical value that can be interpreted as the degree to which software possesses a given attribute that affects its quality.

 Definition nach IEEE Standard 1061 – [Quelle: Wikipedia]

Jede Software, deren Code länger als ein paar hundert Zeilen ist, wird irgendwann den Punkt erreichen, dass man den Code auf Anhieb nicht mehr verstehen kann. Die meisten von uns schreiben Code, der älter als ein paar Monate ist und noch ganz viele Jahre erhalten bleiben soll. (Alle, die das nicht wollen, können hier aufhören zu lesen).

Das Problem, das man früher oder später bekommt, ist die Komplexität unter Kontrolle zu halten. Jeder neuer Kollege hat das Problem, unbekannten, vorhandenen Code so schnell wie möglich zu verstehen. Für beide Fälle ist es sehr hilfreich, wenn man Tools zur Hand hat, die zum Beispiel die Zusammenhänge und Abhängigkeiten visualisieren können.

Als ich bei dem Open Space Karlsruhe die Frage gestellt habe, was die .NET-Community zu diesem Zweck nutzt,war die einstimmige Antwort : NDepend.  Code Metriken sind wichtig, sie sind aber nicht allmächtig. Wenn man allerdings wissen möchte, wie gesund sein Code ist, was sich verschlechtert hat und welche Baustellen aufgeräumt wurden, dann ist NDepend das de facto Standardtool, welches benutzt wird.

Was macht das Tool eigentlich?

Um all die Features zu beschreiben, die NDepend hat, würde man sehr viel Platz und Zeit benötigen – und zum Glück ist dies gar nicht nötig: auf deren Webseite findet man alles, was man braucht: Bilder, Erklärungen, weiterführende Links.

Ich würde hier nur zwei wichtige Funktionalitäten herausheben:

  • Visualisiert

MVC-Runtime Dependency Graph
Abhängigkeiten im MVC-Runtime

 

Auf diesem Bild sieht man, dass man gar nichts sieht 😀

Stellt euch mal vor, ihr müsstet ab sofort an MVC weiterentwickeln. Wo würdet ihr anfangen? Ich würde hiermit beginnen und immer mehr reinzoomen.

Alle Verwender von DotNetOpenAuth.OpenId

 

  • Erklärt

Das coolste für mich bei NDepend ist eigentlich nicht die Tatsache, dass es mir Statistiken und Grafiken liefert, sondern, dass es sie mir Diese auch  erklärt!

 

Interne Abhängigkeiten von DotNetOpenAuth.OpenId

 

Genau so läuft es auch mit den Metriken. Ich will nicht wissen, wie diese berechnet werden – eventuell später –  aber ich will wissen, was es bedeutet, wenn ein Wert zu hoch oder zu klein ist. Und das Tool erklärt dies alles oder leitet mich gezielt dahin weiter, wo es erklärt wird. Und so, ohne es zu merken, habe ich etwas gelernt, was meine Codequalität höchstwahrscheinlich erhöhen wird. Ich kann dadurch ein besserer Programmierer werden.

Es gibt noch sehr viele Gründe, wofür man NDepend ausprobieren bzw. nutzen sollte. Spätestens, wenn ein Team sich für gemeinsame Regeln einigen möchte, sollte man die Einhaltung durch Tools wie dieses und StyleCop and co. absichern. Dadurch wird irgendwann egal, wie ungesund unserer Code heute ist, morgen wird es ihm auf jedem Fall besser gehen – und uns auch.

You never code alone!

Meine letzte Woche in der Arbeit würde ich gerne the cleverbridge-University-Woche nennen, so großartig war sie. Wir haben 3 von 5 Tagen damit verbracht, unseren Code, unsere Prozesse, unseres Miteinander zu analysieren, zu sezieren, zu verbessern:

  • Dienstag hatten wir fast einen ganz Tag Architektur-Workshop um die Vision und die Strukturen für unseren Code zu definieren.
  • Den Freitag haben wir gemeinsam bei der dotnet-cologne 2014 verbracht.

Das wichtigste hat allerdings am Donnerstag stattgefunden: wir haben uns einen ganz Tag Zeit genommen, um von Ilker, meinem TDD-Mentor, so viel wie möglich über Specs, Tests, Teams und Kommunikation zu verstehen.

Es geht nichts über Verstehen!

from requirement to specifications
Wie schafft es ein Team, das und nur das zu bauen, was der Kunde braucht?

  1. Findet alle zusammen – product owner, Entwickler, Tester – das richtige Wording, die “ubiquitous language” heraus, die die Anforderung beschreiben
  2. Versteht alle zusammen, worum es geht.
  3. Definiert zusammen das Feature
  4. Schreibt zusammen die Akzeptanzkriterien

Wie werden eigentlich eine paar Menschen zu einem Team?

Dies ist wahrscheinlich das Problem aller Firmen weltweit, die sich weiterentwickeln möchten. Und das zu Recht: stell dir vor, du bist ein C#-Entwickler mit zum Beispiel Schwerpunkt Web, hast JavaScript warscheinlich noch nie als Programmiersprache betrachtet und von der Arbeit der anderen C#-Entwickler weißt nichts, außer dass sie existiert und sie irgendwann später erfolgen wird, nachdem du deine Aufgaben schon längst erledigt hast. Einen Abteilungsleiter hast natürlich auch und deine Entscheidungsgewalt beschränkt sich auf “soll ich foreach oder lieber LINQ verwenden?”

Das ist allerdings nicht alles: deine Aufgaben überschreiten niemals die Grenzen deiner Abteilung, genauso wenig wie dein Verständnis über die Anforderungen. Und das stört dich seit langem und nicht nur dich sondern auch den JavaScript-Typen und die Frontend-Entwicklerin und wenn du Glück hast, dann auch deinen Abteilungsleiter. Wenn das der Fall ist, dann hat deine Firma Glück: ihr seid offen für ein Crossfunktionales Team. Ihr musst nur diese Frage bejahen:

Bin ich bereit, jede Rolle in diesem Team zu erfüllen?
Auch mit der Gefahr, dass ich das nicht kann? Wenigstens noch nicht, oder noch nicht gut genug…

Jedes Team braucht noch ein paar Zutaten:

  1. Ein Ziel
  2. Eine Partizipation – eine gemeinsame “Teilhaberschaft”
  3. Den Respekt der Individualität
  4. Die gemeinsame Verantwortung

oder wie Ilker sagt “oder mindestens 3 davon plus jemanden, der die anderen die ganze Zeit daran erinnert”.

 

Ich will nicht behaupten, dass wir bereits alles darauf haben – aber wir sind auf dem besten Wege dahin. Und was das Wichtigste ist: wir werden diesen Weg sicherlich nicht verlassen.

Create class from JSON

Ich habe vor einem Jahr bei einer katastrophalen MSFT-Veranstaltung über ein super Feature in VS2012 erfahren, das ich – brownfield-bedingt – noch nie ausprobieren konnte. Heute hat es mir allerdings mindestens eine halbe Stunde Arbeit und eine große Menge Frust erspart!

Das Feature ist sehr schnell erklärt: wenn man ein Objekt, das als JSON oder XML serialisiert vorliegt – also einen string 😉 – in Zwischenspeicher hat, dann kann man das direkt als Klassenmodel abspeichern. Tatata..Fertig 🙂
Edit/Paste Special

Open Space – agiler geht es nicht

Letztes Wochenende war wieder Hightide für Entwickler: es war “Open Space Süd Time” in Karlsruhe. Es gab viele bekannte und viele unbekannte (= neue) Gesichter. Es gab sogar ich glaube fünf weibliche Teilnehmer und auch noch einen Hund 😀

Wegen den vielen neuen Teilnehmer war es nach mehreren Jahren wieder notwendig, die Prinzipien zu erklären, die bei einem Open Space gelten:

Regeln

Im Open Space gibt es vier Prinzipien (eigentlich eher Beobachtungen, wie sich die Welt zeigt)

  1. Wer auch immer kommt, es sind die richtigen Leute – einer oder 25 ist egal, und jeder ist wichtig und motiviert.
  2. Was auch immer geschieht, es ist das Einzige, was geschehen konnte – Ungeplantes und Unerwartetes ist oft kreativ und nützlich.
  3. Es beginnt, wenn die Zeit reif ist – wichtig ist die Energie (nicht die Pünktlichkeit)
  4. Vorbei ist vorbei – Nicht vorbei ist Nicht-vorbei – wenn die Energie zu Ende ist, ist die Zeit um.

und ein Gesetz:
Gesetz der zwei Füße

Das Gesetz der zwei Füße ist Ausdruck der Freiheit und Selbstverantwortung: Der Teilnehmer bleibt nur so lange in einer Gruppe, wie er es für sinnvoll erachtet, also solange er etwas lernen und/oder beitragen kann.
(Wikipedia)

Es gibt auch eine Beschreibung der Teilnehmer:

Teilnehmer

Bei Open Space gibt es nicht den richtigen oder falschen Teilnehmer. Jeder ist willkommen, der oder die sich direkt betroffen und motiviert fühlt, etwas verändern zu wollen. Es sollen möglichst unterschiedliche Menschen eingeladen werden (Berufsgruppen, Verantwortungsbereiche, Alter, aber auch Kunden, Nachbarn, etc.), darunter die wesentlichen Meinungsmacher und Multiplikatoren.

Nach diesem letzten Open Space würde ich diese Definition erweitern:
jeder, der teil nimmt muss zu einem offenem Gespräch bereit sein. Das bedeutet, er muss nicht nur neugierig auf die Meinung der anderen sein, sondern muss bereit sein, seine Ansichten zu revidieren, wenn er sich geirrt hat.

Kommt jemand hin, um etwas zu präsentieren anstatt zu diskutieren: dafür ist Open Space nicht geeignet. Das ist keine Konferenz, wo die Leute bezahlen und hoffen, dass es sich lohnt 😉
Andererseits kommt jemand ohne irgendwelche Ansichten dahin, hat er die Möglichkeit, sie hier zu formen, die Meinung der anderen an zu hören und seine eigenen Schlussfolgerungen zu ziehen.

Was hat das alles mit Agilität zu tun? Schauen wir mal, was während diesen 2 1/2 Tagen immer wieder – in Zyklen sozusagen – passiert:

  1. – wir beschreiben Probleme oder Angebote und schmeißen sie in die Runde. Es werden die Interessenten gezählt und auf die Karte notiert => hört sich wie Planungsmeeting an, oder?
  2. – wenn das Bord voll ist – wie ein Backlog – , muss die zeitliche und räumliche Reihenfolge definiert werden, und zwar nach Sinn und Machbarkeit => genau wie in einem Priomeeting?
  3. – jetzt kommt die größte Herausforderung: welchen Session soll ich besuchen? Welcher hat für MICH die höchste Prio? Wie organisiere ich meine Zeit so, dass mein “Backlog” auch abgearbeitet wird?

Die ganzen Zeit stellen wir Fragen gestellt und Antworten überlegt: Anforderungen an andere definiert und selbst welche erfüllt. Wenn diese Anforderungen sich geändert haben – siehe spontane Coding Dojo von 18 bis fast 20 Uhr am Samstag Abend – dann wird vom Team sofort eine Entscheidung getroffen: passt es noch in diesem oder erst im nächsten Sprint (also am zweiten Tag).

Wir versuchen ununterbrochen durch die richtige Kommunikation die Lücken zu schließen, die wegen den Unterschiede in Erfahrung, Ausbildung, Alter, Geschlecht, Herkunft usw. existieren. Wir haben eine zeitliche Vorgabe – jeder Timeslot ist 45 Minuten lang – den wir zwar wahrnehmen aber uns damit nicht unter Druck setzen lassen.

Und jeden Abend wird der wichtigste Teil eines agilen Prozesses zelebriert: die Retrospektive – bei einem kühlen Bier 🙂

Coding Dojo – der Trainingsraum für Entwickler

Definition: A Coding Dojo is a meeting where a bunch of coders get together to work on a programming challenge (the Code Kata). They are there to have fun and to engage in deliberate practice in order to improve their skills.

(Quelle: http://codingdojo.org/)

The Principles of a Coding Dojo
(extracted from the Laurent Bossavit’s Blog: bossavit.com/dojo/archives/2005_02.html)

  1. The First Rule
    One important rule about the Dojo is : At the Dojo one can’t discuss a form without code, and one can’t show code without tests. It is a design training place, where it is acknowledged that “the code is the design” and that code without tests simply doesn’t exist.
  2. Finding a Master
    The master can’t be a master of every forms. I feel quite at ease with recursive functions and list processing e.g. but I think I don’t know how to create even a simple web app. Fortunately, while it’s the first time they really deal with “tail-recursion” some practionners here have done professional web apps for years!
  3. Come Without Your Relics
    Of course, you know how to do it. You know how and why this code is better than that one. You’ve done it already. The point is to do it right now, explain it to us, and share what you learned.
  4. Learning Again
    In order to learn again something, we just have to forget it. But it’s not easy to forget something when you’re alone. It’s easier when we give our full attention to someone who just tries to learn it for the first time. We can learn from others mistakes as well as from ours if we listen carefully.
  5. Slow Down
    Learning something should force you to slow down. You can go faster because you learned some tricks, but you cannot go faster and learn at the same time. It’s OK, we’re not in a hurry. We could do that for years. Some of us certainly will. What kind of deadline will we miss if we spend four more weeks on this subject rather than on four different subjects? More precisely, when we reach the next plateau, is it because we went through the previous one, or is it just because we were flying over it?
  6. Throwing Yourself In
    At some time someone begins to master a subject and wants to approach another one. Those threatened by boredom should throw themselves first into a presentation. The goal is to get back to a good motivation level, ie. an acceptable level of difficulty.
  7. Subjecting To A Master
    If it seems difficult to you, look for other practitionners who can judge your code and could easily show something new about it to you. Ask again until the matter contains absolutely no more difficulty to you.
  8. Mastering A Subject
    If it seems easy to you, to explain it to other who find it difficult. Explain it again as long as they find it difficult.

(Quelle: http://codingdojo.org/)

Seit mehreren Monaten experimentieren wir mit Coding Dojos in der Firma. Nach jedem bisherigen Dojo haben wir etwas gelernt und diese Erkentnisse bei dem nächsten Session gleich angewendet: Wir haben sozusagen die Dojo-Finding-Kata gelöst und eine gute Lösung dafür gefunden, wie wir dabei das meiste lernen können.

Es gibt 2 Levels: für Anfänger und für weniger Anfänger, mit einem gemeinsamem Punkt: alle sind Softwareentwickler. Anfänger bedeutet: neu in der Welt der Tests und/oder neu in C#. Dadurch, dass wir sowohl C# als auch JavaScript-Dojos machen, werden wir uns mal den einen mal den anderen Schuch anziehen müssen ;). Durch diese Aufteilung sind wir in der Lage, eine passende Übung durchzuführen. Die Einladung geht an alle und es bleibt jedem selbst überlassen, zu entscheiden, bei welchem Level er/sie mitmachen möchte. Diese Selbst-Verpflichtung führt automatisch dazu, dass man es ernst.

Was die Form betrifft, haben wir mehrere Varianten ausprobiert:

  • Mit oder ohne Moderator: Erkenntnis: es muss einen Moderator geben, wenn man nicht will, dass der Abend in Frust und Streit endet 😉
  • mit Coder und Driver (Randori Modus): Erkenntnis: der Coder war gleichzeitig der Driver, der andere saß nur da und wartete auf seine ReiheThumbs-down-icon
  • mit Wechsel der Paare nach einer bestimmten Zeit: Erkenntnis: das mentale Ticken einer Uhr hat teilweise zu einer kompletten Blockade geführt. Warum soll man überhaupt einen Stopper verwenden? Niemand sagt einem bei der Arbeit: du hast 5 Minuten für diese Aufgabe sonst müssen wir die Firma schließen!!Thumbs-down-icon
  • ein Dojo für alle, unabhängig von Kenntnissstand: Erkenntnis: ein guter Entwickler, der in C# noch noch nicht so bewandert ist, hat genauso gute oder gar bessere Ideen, als die anderen bzw. braucht länger um den Syntax des Lösungsweges zu verstehen. Das kann dazu führen, dass man sich unterschätztThumbs-down-icon

Nach verschiedenen Diskussionen mit anderen Entwickler, die Dojos in Unternehmen erfolgreich etabliert haben (danke nochmal Ralf und Uli) und nach diesen eigenen Erfahrungen, haben wir uns für die folgende Variante entschieden:

  • die Tastatur geht herum, und nicht der Entwickler (das hat auch immer wieder zu Störungen geführt).
  • Jeder, der dran ist, muss entweder den allerersten Test schreiben oder den vorherigen lösen: das bedeutet, er muss den Code schreiben, wodurch der Test grün wird – nicht mehr und nicht weniger. Danach muss er noch den nächsten Test schreiben, und zwar so, dass er rot ist. (Es gab Fälle, wo die nächste Anforderung – also der nächste Test – gleich mit implementiert wurde.)
  • Es gibt keine zeitliche Begrenzung und niemand muss alleine grübeln. Wenn Fragen oder Mißverständnisse im Raum stehen, sie werden sofort geklärt. Die Fragen müssen trotzdem vom Entwickler formuliert werden: der Lernprozess ist immer da.
  • Der Weg ist das Ziel: wird eine Aufgabe nicht in der Zeit erfüllt, die uns zur Verfügung steht, dann ist das auch ein Erkenntniss, aus dem man lernen kann.

Thumbs-up-icon

Wir verfolgen durch diese Trainingsstunden verschiedene Ziele:
– lernen, wie man Tests schreibt, um eine nachhaltige Qualität abzusichern,
– lernen, wie man Features gegen Code-Veränderungen schützt.
– lernen, wie man eine Anforderung interpretiert,
– lernen, wie man eine Anforderung definiert,
– lernen, wie man eine konstruktive Diskussion führt um sich auf eine Lösung zu einigen,
– lernen, wie man SOLIDen Code schreibt, Abhängigkeiten erkennt und trennt, wie man für Menschen lesbaren Code schreibt.

Die Liste der Lerneffekten solcher Übungen ist sicher viel länger, aber vorerst reicht es, wenn wir das hier schaffen :). Diese Prozesse werden sich sicherlich ändern – genauso wie wir Entwickler. Die Grundlagen aber bleiben bestehen: alles, was wir hier lernen, soll sich – wird sich –  in der täglichen Arbeit wiederspiegeln und uns zu besseren Softwareentwickler und gleichzeitig zu besseren Teamplayer machen.

Regions or no regions – this is the question

Die dnc12 ist gerade vorbei und wir könnten uns schon wieder zusammensetzen 🙂
Heute gab es auf Twitter eine kurz angerissene Diskussion, die das Zeug dazu hatte, die Gemüter aufzuheizen: soll man oder soll man nicht #regions nutzen?

 

Nach dem kurzen Tweet-Austausch wurde es klar, dass es viele Entwickler gibt, die Regions gerne nutzen. Ich habe zwar den ganzen Abend nachgedacht, habe allerdings keine Gründe gefunden, sie selbst verwenden zu wollen.

 

Ich meine, warum sollte man Code NICHT sehen wollen?

  • Geht es vielleicht um eine oder mehrere Methoden, die man ausblenden will? Das würde aber entweder bedeuten, dass man
    – die Funktionalität der ganzen Klasse ausblendet, aber dann wozu, man öffnet einfach die Klasse nicht 😉
    – nur ein Teil der Funktionen ausblendet, und dann stellt sich die Frage, warum manche Funktionen viel öfter angeschaut werden als andere? Das hat für mich irgendwie ein CodeSmell
  • Geht es vielleicht um ein Teil einer einzigen Methode, und zwar einer ganz großen, sonst würde man sie nicht teilweise ausblenden wollen? Zusammengeklappt würde man dann eine Art Kommentar sehen, was mich sofort an Martin Fowlers Hinweis bezüglich Kommentare erinnert hat: Kommentare sind ideale Namensgeber. Wenn man im Code einen Kommentar braucht, dann ist das meistens ein Smell für ein Extract Method (genauso wie die Tatsache, dass die Methode wahrscheinlich zu lang ist)

    You have a code fragment that can be grouped together.

    Turn the fragment into a method whose name explains the purpose of the method.

  • Geht es vielleicht um Regionen um Methoden, Events, Fields, Properties, also nach Sichtbarkeit und Rolle? Dafür könnte ich einen einzigen Grund vorstellen, und zwar den, dass man auf Anhieb die öffentliche Methoden und Eigenschaften sehen will. Das wäre allerdings die Aufgabe eines Interfaces, oder? Dazu kommt auch noch meine – persönliche – Vorliebe, Code wie ein Buch zu lesen, von oben nach unten, also von einer öffentlichen Methode weiter in die Details, also zu den privaten Methoden (ganz nach CCD – Single Level of Abstraction (SLA))

    Hilfreich als Analogie ist der Blick auf Artikel in der Tageszeitung: dort steht zu oberst das Allerwichtigste, die Überschrift. Aus ihr sollte in groben Zügen hervorgehen, wovon der Artikel handelt. Im ersten Satz des Artikels wird dies auf einem hohen Abstraktionsniveau beschrieben. Je weiter man im Artikel fortschreitet, desto mehr Details tauchen auf. So können wir auch unseren Code strukturieren. Der Name der Klasse ist die Überschrift. Dann folgen die öffentlichen Methoden auf hohem Abstraktionsniveau. Diese rufen möglicherweise Methoden auf niedrigerem Niveau auf, bis zuletzt die “Bitpfriemelmethoden” übrig bleiben. Durch diese Einteilung kann ich als Leser der Klasse entscheiden, welchen Detaillierungsgrad ich mir ansehen möchte. Interessiert mich nur grob, wie die Klasse arbeitet, brauche ich mir nur die öffentlichen Methoden anzuschauen. In ihnen wird die Funktionalität auf einem hohen Abstraktionsniveau gelöst. Interessieren mich weitere Details, kann ich tiefer einsteigen und mir die privaten Methoden ansehen.

Was meint ihr, übersehe ich da was? (Notiz an mich: bei #nossued das Gespräch fortsetzen!)

Sind Unit Tests wirtschaftlich untragbar?

Immer wieder höre ich die Aussagen “Unit Tests sind schön und gut, wir haben nur keine Zeit dafür.” Oder “Klar, man kann Tests machen, hauptsache, es nimmt nicht zu viel Zeit von der Arbeit weg” ??!!

 

Nur um Missverständnisse zu vermeiden: Tests macht man nicht zum Spaß oder aus Langeweile, die Tests stellen die Essenz, die abstraktester Form der Lösung dar!

 

Ich habe bis heute Schwierigkeiten damit, meinem Gegenüber zu erklären, dass er sich irrt. Ich WEIß es einfach aus Erfahrung, dass dies eine Milchmädchenrechnung ist. Keine ernsthafte Argumente gegen Tests würden bei einer tieferen Überprüfung standhalten. Die Pros übertreffen klar die Kontras. Aber wie soll ich etwas – für mich – Offensichtliches in Worte fassen? Wie soll ich etwas in ein paar Sätzen erklären, was ich in einem andauernden Prozess durch jeden NICHT (oder nicht richtig) geschriebenen Test gelernt habe? Oder durch jeden Aha-Effekt oder durch jeden stressfreien Release (kein Stress entsteht, wo kein Platz für Bugs existiert 😉 )

 

Unit Tests sind für den Open Mind “selbsterklärend”: wenn der Bug in einem ungetesteten Code steckt, dann wird das zu einer “blinden” Fehlersuche führen, die Tage dauern kann und auf jedem Fall Geld und Ruf kostet. Wie lange dauert es, den Fehler in einem getesteten Codebasis zu finden, wo die Eingrenzung innerhalb von Sekunden erfolgt? Wie oft kommt es überhaupt vor, dass dieses Problem entsteht? Für mich schaut die Rechnung so aus:

 
Zeit_für_fehlersuche = Unproduktive_Zeit;
f(Unproduktive_Zeit) = Verschwendetes_Geld;
 
0->Zeit_für_fehlersuche(getesteter_Code)----------------------->Zeit_für_fehlersuche(ungetesteter_Code)---.....oo
 

Ok, ich glaube, ihr kennt jetzt meinen Standpunkt 😉 Aber ich bin ja nicht die ultimative Maßstab dafür, wie man arbeiten sollte. Deshalb habe ich ein paar Artikel und Statistiken von klügeren Leuten zusammengesucht, bitte liest die auch.

 

Diese Infos habe ich bei stackoverflow gefunden:

Realizing quality improvement through test driven development: results and experiences of four industrial teams und hier eine Diskussion darüber.

The study and its results were published in a paper entitled Realizing quality improvement through test driven development: results and experiences of four industrial teams, by Nagappan and research colleagues E. Michael Maximilien of the IBM Almaden Research Center; Thirumalesh Bhat, principal software-development lead at Microsoft; and Laurie Williams of North Carolina State University. What the research team found was that the TDD teams produced code that was 60 to 90 percent better in terms of defect density than non-TDD teams. They also discovered that TDD teams took longer to complete their projects—15 to 35 percent longer.

“Over a development cycle of 12 months, 35 percent is another four months, which is huge,” Nagappan says. “However, the tradeoff is that you reduce post-release maintenance costs significantly, since code quality is so much better. Again, these are decisions that managers have to make—where should they take the hit? But now, they actually have quantified data for making those decisions.”

Es gab auch kleinere Experimente dazu wie z.B. Code Lab – TDD vs. Non-TDD

Over 3 iterations, average time taken to complete the kata without TDD was 28m 40s. Average time with TDD was 25m 27s. Without TDD, on average I made 5.7 passes (delivering into acceptance testing). With TDD, on average I made 1.3 passes (in two attempts, they passed first time, in one it took 2 passes.)

Now, this was a baby experiment, of course. And not exactly laboratory conditions. But I note a couple of interesting things, all the same.

Und weil ein Bild mehr als tausend Worte spricht: Die Kostenverteilung bei getesteten Code schaut ungefähr so aus
Testing Benefits

Tests schreiben ist einfach, der Ertrag ist riesig. Warum soll man also keine Tests schreiben? Sind wir wirklich unfehlbar, schreiben wir immer den perfekten Code? Seien wir mal ehrlich…Ich bin es sicher nicht und ihr auch nicht.

 

Und hier noch die obligatorische Buchempfehlung: The Art Of Unit Testing Das Buch ist wunderbar verständlich geschrieben mit echten Beispielen und guten Argumenten, warum und wie man testen soll.

Templating mit Razor aber ohne MVC

Ich habe unlängst nach einer Möglichkeit gesucht, Seiten schnell und effektiv zu generieren, sowohl für Web als auch für E-Mails als Background-Jobs. Ein Kollege hat mich auf @razorengine aufmerksam gemacht und diese Templating Engine scheint alles zu bieten, was ich gesucht habe.

A templating engine built upon Microsoft’s Razor parsing technology. The RazorEngine allows you to use Razor syntax to build robust templates. Currently we have integrated the vanilla Html + Code support, but we hope to support other markup languages in future.

Die Installation ist so einfach wie möglich:

//mit NuGet:
Install-Package RazorEngine

Man muss danach nur noch die RazorEngine.dll und System.Web.Razor.dll referenzieren und das war’s.

 

Das Generieren von Seiten kann entweder direkt oder mit vorkompilierten Templates erfolgen:

[Test]
public void PageCanBeParsed()
{
   const string template = "Hello @Model.Name! Welcome to Razor!";
   var result = Razor.Parse(template, new {Name = "World"});

   Assert.That(result, Is.EqualTo("Hello World! Welcome to Razor!"));
}
//unterstützt anonyme Klassen
[Test]
public void PageCanBeParsedWithCompiledTemplate()
{
   const string template = "Hello @Model.Name! Welcome to Razor!";
   Razor.CompileWithAnonymous(template, "world");
   var result = Razor.Run(new {Name = "World"}, "world");

   Assert.That(result, Is.EqualTo("Hello World! Welcome to Razor!"));
}
//oder konkrete Typen
[Test]
public void TemplateIsCompiledWithModelType()
{
   const string template = "Hello @Model.Name! Welcome to Razor!";
   var testModel = new TestModel{ Name = "World" };
   Razor.Compile( template, typeof(TestModel), "world2" );
   var result = Razor.Run(testModel, "world2");
   Assert.That(result, Is.EqualTo("Hello World! Welcome to Razor!"));
}

public class TestModel { public string Name; }

Um ehrlich zu sein, ich habe noch keinen Grund gefunden, warum man nicht die vorkompilierte Variante nutzen soll. In diesem Fall wird das Template EIN MAL kompiliert und in Cache abgelegt. Ein Vergleichs- und Stresstest, in dem ich ein halbwegs komplexes Template 500-mal mit Razor.Parse bzw. mit Razor.Compile + Razor.Run aufgerufen habe, hat folgendes geliefert:

   Parse: 03:35.97 min
   Compile+Run: 00:00.63 min

Ich glaube, damit ist alles gesagt. Es sei denn, eine Zeile weniger gilt auch als Argument 🙄

 

RazorEngine unterstüzt fast alles, was Microsoft’s Razor in Views anbietet, wie zum Beispiel Helper-Methoden, Model-Definitionen direkt im Template oder partielle Views:

[Test]
public void EngineSupportsInlineHelper()
{
   const string template = @"@helper MyMethod(string name) {Hello @name}@MyMethod(Model.Name)! Welcome to Razor!";
   var testModel = new TestModel{ Name = "World" };
   var result = Razor.Parse(template, testModel);
   Assert.That(result, Is.EqualTo("Hello World! Welcome to Razor!"));
}

[Test]
public void EngineSupportsInheritsCommand()
{
   const string template = @"@inherits RazorEngine.Templating.TemplateBase
@helper MyMethod(string name) {Hello @name}@MyMethod(Model.Name)! Welcome to Razor!";
   var testModel = new TestModel{ Name = "World" };
   Razor.Compile(template, typeof(TestModel),"testModel");
   var result = Razor.Run(testModel, "testModel");

   Assert.That(result, Is.EqualTo("Hello World! Welcome to Razor!"));
}

[Test]
public void EngineSupportsSubtemplating()
{
    const string masterTemplate = "You are on www.yellow-brick-code.org!";
    Razor.Compile(masterTemplate, typeof(TestModel), "master");

    const string contentView = @"@inherits RazorEngine.Templating.TemplateBase
@helper MyMethod(string name) {Hello @name}@MyMethod(Model.Name)! Welcome to Razor!";
    var testModel = new TestModel{ Name = "World" };

    const string template = contentView + " @Include(\"master\")";

    Razor.Compile(template, typeof(TestModel), "testModelMaster");
    var result = Razor.Run(testModel, "testModelMaster");
    Assert.That(result, Is.EqualTo("Hello World! Welcome to Razor! You are on www.yellow-brick-code.org!"));
}

Und nun sind wir soweit, das Ganze im Web zu testen.

 

Die Engine funktioniert so, dass sie zur Laufzeit aus dem Template eine dll mit einem Zufallsnamen erstellt. Also wenn man die Engine im Web nutzen will, müssen noch ein paar Dinge getan werden:

  1. RazorEngine.Web.dll referenzieren
  2. Ein VirtualPathProvider in Global.asax.cs registrieren
    public class Global : System.Web.HttpApplication
    {
       protected void Application_Start(object sender, EventArgs e)
       {
          HostingEnvironment.RegisterVirtualPathProvider(new RazorVirtualPathProvider());
       }
    ...
    
  3. In Web.Config muss der BuildProvider registriert werden:
    <configuration>
    <configSections>
    <section name="razorEngine" type="RazorEngine.Configuration.RazorEngineConfigurationSection, RazorEngine" requirePermission="false" />
    </configSections>   <razorEngine factory="RazorEngine.Web.WebCompilerServiceFactory, RazorEngine.Web" /><system.web>
    <compilation debug="true" targetFramework="4.0">
    <buildProviders>
    <add extension=".csrzr" type="RazorEngine.Web.CSharp.CSharpRazorBuildProvider, RazorEngine.Web" />
    </buildProviders>
    </compilation>

So aufgerüstet kann man mit den Models und Templates beginnen. Man kann die Templates als html-Dateien speichern. Allerdings wenn man IntelliSense haben möchte, dann muss MVC3 auf den Rechner installiert und die Datei als cshtml gespeichert werden.

 

Das Beispiel hier ist über ein MasterHeader mit dem Anfang der Seite, ein MasterFooter mit dem Ende, beide eingebettet mit " @Include(\"master...\")" in Content. Die ganze Seite bekommt ein Objekt vom Typ Model zum Parsen. Alle Templates werden mit einem ITemplateFinder geladen.

...
ITemplateFinder templateFinder = new TemplateFinder(path);
Razor.Compile(templateFinder.GetTemplate("masterHeader.cshtml"), typeof(Model), "masterHeader");
Razor.Compile(templateFinder.GetTemplate("masterFooter.cshtml"), typeof(Model), "masterFooter");

var model = new Model
{
    PurchaseNo = "011313074142",
    Amount = "270.63",
    Date = "20110121"
};

var template = templateFinder.GetTemplate("Content.cshtml");
Razor.Compile(template, typeof(Model), "content");
var parsedTemplate = Razor.Run(model, "content");
context.Response.ContentType = "text/HTML";
context.Response.Write(parsedTemplate);

Bevor ihr was über Namen oder Verantwortlichkeiten was sagt: das Projekt wurde als Spike erstellt, und als solche hat seine Rolle  perfekt erfüllt 🙂 In Produktion würde ich das Kompilieren von statischen Templates in Application_Start verschieben und das ITemplateFinder sollte auf  jeden Fall Injected werden.

 

Ich muss mich bei den 2 Jungs, die das Projekt entwickeln, sehr bedanken, es war eine super Idee! Schaut es einfach an, die dll kann noch viel mehr.

NOS Süd – ein etabliertes Konzept

Man nehme 50 bis 80 engagierte Menschen, ein gemeinsames Thema (Softwareentwicklung rund um .NET), 4 oder 5 Räume mit vielen Stühlen und ein paar Steckdosen und Flipcharts oder Beamer, gebe ausreichend Kaffee und ein Versprechen auf ein späteres Bier dazu. Man gebe ihnen alle Freiheiten der Kreativität – und eventuell ein Paar Gadgets, da es vorwiegend um Männer geht 😉 – und lasse sie machen. Fertig ist das OpenSpace-Gericht, mit Erfolgsgarantie.

 

Nach ca. 60 Stunden werden alle NOS-Süd 2011 mit einem gefüllten “mentalen” Rucksack verlassen! Manche werden konkrete technische Fragen geklärt bekommen haben, manche werden in ihrem Vorgehensweisen bestätigt und manchen werde eine ganz neue Richtung aufgezeigt. Manche lernen endlich die kennen, dessen (deren) Blogs sie seit langem lesen und manche werden aus der Anonymität “des einsamen Softwareentwicklers” herauskommen und sich als “Nerds” outen. Es werden Freundschaften gegründet und sicherlich auch künftige Geschäftsbeziehungen.

 

Und alle gehen müde und voll mit Tatendrang nach Hause, sich in der Community weiter zu engagieren und nächstes Jahr wieder zu kommen.

 

Das alles ist Open Space und gilt speziell für den .NET Open Space Süd, der an diesem Wochenende abgehalten wurde. Erstens war er schon für das zweite Mal in Karlsruhe, wo es bekanntermaßen immer schönes Wetter ist 😉 Zweitens waren da gerade so viele Menschen, dass keine Person und/oder Frage untergehen konnte. Aber das besondere “Salz” lieferten die Organisatoren dazu: Frank, Alex, Ralf und Aydin und all ihren großartigen Helfer. Es ist für mich immer wieder erstaunlich, wo sie die Zeit und Energie finden, das alles “so nebenbei” zu organisieren. Manchanderer findet nicht mal genug Zeit, zu einem User Group-Treffen hin zu gehen und die Jungs opfern ihre Freizeit dafür, uns diese jährliche Treffen zu organisieren. Nochmal DANKE dafür!

 

Ja, und nur zur Info: ich habe mir ein Twitteraccount eingerichtet 🙂