Gruppe 1 hat sich für die Closest to Zero Kata und Implementierung in TypeScript entschieden.
Gruppe 2 hat sich für die Vending Machine Kata und Implementierung in Java entschieden. Den Codestand findet ihr unter https://github.com/mob-archive/2024-01-31-vendingmachine
Unter anderem hatten Sie folgende Maßnahmen als erfolgreich erwiesen:
In der Diskussion wurde u.a. besprochen, ob es bei größeren Systemen überhaupt noch möglich ist, dass alle im Team alle Bereiche kennen und betreuen können. Hier tendierte die Runde dazu, dass dies je größer und umfangreicher das System ist, nicht mehr mit vertretbarem Aufwand möglich ist und man eine gewisse Trennung von Kompetenzen (also Silos) hinnehmen muss.
Dabei kam auch die Frage auf inwiefern das Management Wissenssilos erkennt und als Problem wahrnimmt. Die meisten Teilnehmenden berichteten dabei eher ernüchtert von wenig Interesse und Bewusstsein für dieses Thema.
Sie haben uns verschiedene Schulen von Test Driven Development (TDD) vorgestellt (Folien). Anschließend konnten wir die verschiedenen Vorgehensweisen anhand der Diamond-Kata ausprobieren.
Als gute Einführung in die Chicago-Schule wurde Test Driven Development: By Example von Kent Beck erwähnt.
Growing Object-Oriented Software, Guided by Tests von Steve Freeman und Nat Pryce stellt die London-Schule dar.
Der Kata-Log wurde als gute Quelle für Katas gekannt.
Marco hat bei Heise auch eine Artikel zu einigen der TDD-Schulen veröffentlicht:
]]>Strukturierung von Tests
BDD
UI-Tests und fachliche Tests trennen:
Approval-Tests
Wann einsetzen?
"Um mal einen Fuß in die Tür bekommen, wenn man sonst keine bis wenig Tests hat: Ok"
Unterschied Approval-Tests und Tests mit handgeschriebene Assertions:
Test mit handgeschriebene Assertions testen erstmal nichts, was geprüft werden soll wird Stück für Stück (Assertion für Assertion) ergänzt (eher Gefahr von false negatives).
Approval-Tests testen erstmal alles, also eventuell/eher zu viel, da auch nicht relevante Dinge geprüft werden, so dass der Test ständig rot wird, auch, wenn noch alles funktioniert (eher Gefahr von false positives).
Snapshot-Tests: Bildvergleich
Property-based Tests vs. example-based Tests
Anschaulichere Tests (Cucumber, Board-Darstellung bei GoL) können aus mehr Gründen kaputt gehen bzw.
nicht das testen, was man eigentlich will, da der Glue-Code/Parsing-Code falsch sein kann.
Tests sollten erklären, warum die Werte erwartet werden (sie also die richtigen sind).
Falls das nicht der Fall ist, dann sind sie eine Art Approval-Test.
Geschachtelte Tests und parametrisierte Tests
@Nested
in JUnit 5 oder describe
-> it
in RSpec oder JS-Testing-FrameworksWarum schreiben wir fachliche Tests nicht immer in Cucumber und Co?
Links zu Emilys Site (Sammancoaching):
Hier schonmal die Links aus dem Chat als Sammlung
interesting podcast on mob/ensemble
https://www.youtube.com/channel/UCgt1lVMrdwlZKBaerxxp2iQ (Mob Mentality Show)
https://youtu.be/fdpmfOfd4FY (Webinar: Mob Programming 101)
https://hackerrank.com
https://codewars.com
Online-IDE
https://lp.jetbrains.com/projector/
Produktivität
https://arxiv.org/abs/2111.04302v1 (How Developers and Managers Define and Trade Productivity for Quality)
Klassiker in diesem Zusammenhang
https://www.amazon.de/Peopleware-Productive-Projects-Teams-3rd/dp/0321934113/
deutsch: https://www.amazon.de/Wien-wartet-auf-Dich-Produktive/dp/3446438955/
Emilys Repos
https://github.com/emilybache?tab=repositories
Mob Tool
https://github.com/remotemobprogramming/mob
DevOps Studie
https://software-architektur.tv/2020/08/14/folge012.html
In der Runde wurden einige der Kritikpunkte eher als überspitzt angesehen (z. B. der Vorwurf, dass OOP zwangsläufig zu komplexem Code führt). Wir sahen häufiger das Problem weniger bei OOP selber sondern eher bei der falschen Anwendung.
Es kamen aber auch Stimmen auf, dass in der doch recht langen Geschichte von OOP (mittlerweile mehr als 50 Jahre) sicher auch einige fehlgeleitet Entwicklungen stattgefunden haben (z. B. Einsatz von großen Vererbungshierarchien oder übermäßiger Gebrauch von veränderlichem Zustand).
Insgesamt war sich die Runde einig, dass manche Probleme mit OO sehr gut gelöst werden können, es aber Gebiete gibt, in denen andere Paradigmen sich eher anbieten.
]]>Wie auch in den letzten Jahren waren wir im Trainingscenter der Fidicua GAD IT AG in Karlsruhe zu Gast.
10:30
11:30
12:30
14:15
15:15
Folien: https://speakerdeck.com/marcphilipp/produktive-tests-german
]]>In der Einleitung wurde der Ablauf des Tages, die Programmieraufgabe (View Gewinnt), Four Rules of Simple Design und PairProgramming vorgestellt.
Um die Teilnehmer in die Einleitung mit einzubeziehen, ließen wir sie nach ihrer "Hauptprogrammiersprache" Gruppen bilden. Somit konnten die Teilnehmer auch sehen, mit wem man in einer der Session ein Pair bilden könnte um eine Programmiersprache auszuprobieren.
Das Finden der ersten Pairs haben wir unterstützt, indem wir alle Teilnehmer gebeten hatten, sich nach ihrer Code-Retreat-Erfahrung in eine Reihe aufzustellen. Die Reihe wurde dann zusammengeklappt, sodass diejenige Person mit der meisten Code-Retreats mit derjenige Person mit am wenigsten Code-Retreats gepaired hat, diejenige Person mit den zweit meisten mit derjenigen Person mit den zweit wenigsten, usw.
Diese Constraint zwingt alle Teilnehmer ihre Finger auf der Tastatur zu behalten, einzige Ausnahme, dass auffinden des Shortcuts.
Auf Grund des sehr diversen Umfelds (alle Programmiersprachen, Tastaturlayouts, IDEs und Betriebssysteme) stellte sich der Constraint als durchaus große Herausforderung dar.
Diese Constraint war zum lockeren reinkommen gedacht, verfehlte aber ihren Zweck.
Beim diesem GDCR in Karlsruhe hatten wir TDD nicht mehr als verpflichtend vorgegeben sondern als eines der Werkzeuge, die man einsetzen bzw. ausprobieren kann. Zumindest in dieser Session sollte die Gruppe dieses Werkzeug aber einmal konzentriert und bewusst ausprobiert.
Das Constraint wurde positiv aufgenommen. Dadurch, dass man sich in der ersten Session bereits mit der Aufgabenstellung befasst hatte, fiel das schreiben des ersten Tests leichter.
Da TDD in den letzten Jahr teilweise öfters ein kontroverses Thema war, waren wir überrascht, dass die Rückmeldung durchweg positiv war. Daher fühlen wir uns bestärkt in der Entscheidung TDD als optionales Werkzeug anzubieten aber nicht für den ganzen Tag als gesetzt vorzugeben, jedoch eine einzelnen Session zum Fokus zu machen.
Dieses Constraint sollte den Fokus auf die Domäne und ihre Modellierung im Code legen. Die Vorgabe war, dass primitive Datentypen wie String
, int
, boolean
nicht direkt verwendet werden sollten, sondern immer in einer Objekt gekapselt werden sollte, das die Bedeutung für die Domäne beschreibt. Für String
also z. B. Name
.
Das Feedback aus der Gruppe war positiv. Ein Pair hat angemerkt, dass sie mehr über die Domäne diskutiert haben als in den Sessions davor.
Das Constraint scheint seinen Zweck erfüllt zu haben.
Beim Typen boolean
gab es noch die Diskussion, ob z. B. bei einer Methode isEmpty
dieser Typ nicht die Domäne schon ausreichend beschreibt, was man durchaus so sehen kann. Eine Alternative wäre ein Enum oder State-Objekt, dass z. B. die Ausprägungen Empty
, PartiallyFilled
und Full
hat einzuführen.
https://keybase.pub/chr1shaefn3r/slides/ka-gdcr19.pdf
Vielen Dank an alle Teilnehmer für das konzentrierte Mitmachen und das positive Feedback. Der zweite ganz groẞe Dank geht an Peter Fichtner der uns bei der Fiducia & GAD IT AG unter optimalsten Bedingungen gehostet hat.
In der Einleitung wurde der Ablauf des Tages, die Programmieraufgabe (Vier Gewinnt), Four Rules of Simple Design und PairProgramming vorgestellt.
Um die Teilnehmer in die Einleitung mit einzubeziehen, ließen wir sie nach ihrer "Hauptprogrammiersprache" Gruppen bilden. Somit konnten die Teilnehmer auch sehen, mit wem man in einer der Session ein Pair bilden könnte um eine Programmiersprache auszuprobieren.
Das Finden der ersten Pairs haben wir unterstützt, indem wir alle Teilnehmer gebeten hatten, sich nach ihrer Code-Retreat-Erfahrung in eine Reihe aufzustellen. Die Reihe wurde dann zusammengeklappt, sodass diejenige Person mit der meisten Code-Retreats mit derjenige Person mit am wenigsten Code-Retreats gepaired hat, diejenige Person mit den zweit meisten mit derjenigen Person mit den zweit wenigsten, usw.
Diese Constraint zwingt alle Teilnehmer ihre Finger auf der Tastatur zu behalten, einzige Ausnahme, dass Auffinden des Shortcuts.
Auf Grund des sehr diversen Umfelds (alle Programmiersprachen, Tastaturlayouts, IDEs und Betriebssysteme) stellte sich der Constraint als durchaus große Herausforderung dar.
Diese Constraint war zum lockeren reinkommen gedacht, verfehlte aber ihren Zweck. "Keine Maus" sollte nur angewandet werden, wenn die Pair-Teilnehmer Sprache und IDE (inkl. Tastaturlayout etc.) grundlegend behrschen. Dies war durch die initiale ("zufällige") Zusammenstellung der Pairs nicht gegeben.
Beim diesem GDCR in Karlsruhe hatten wir TDD nicht mehr als verpflichtend vorgegeben sondern als eines der Werkzeuge, die man einsetzen bzw. ausprobieren kann. Zumindest in dieser Session sollte die Gruppe dieses Werkzeug aber einmal konzentriert und bewusst ausprobiert.
Das Constraint wurde positiv aufgenommen. Dadurch, dass man sich in der ersten Session bereits mit der Aufgabenstellung befasst hatte, fiel das schreiben des ersten Tests leichter.
Da TDD in den letzten Jahr teilweise öfters ein kontroverses Thema war, waren wir überrascht, dass die Rückmeldung durchweg positiv war. Daher fühlen wir uns bestärkt in der Entscheidung TDD als optionales Werkzeug anzubieten aber nicht für den ganzen Tag als gesetzt vorzugeben, jedoch eine einzelnen Session zum Fokus zu machen.
Dieses Constraint sollte den Fokus auf die Domäne und ihre Modellierung im Code legen. Die Vorgabe war, dass primitive Datentypen wie String
, int
, boolean
nicht direkt verwendet werden sollten, sondern immer in einer Objekt gekapselt werden sollte, das die Bedeutung für die Domäne beschreibt. Für String
also z. B. Name
.
Das Feedback aus der Gruppe war positiv. Ein Pair hat angemerkt, dass sie mehr über die Domäne diskutiert haben als in den Sessions davor.
Das Constraint scheint seinen Zweck erfüllt zu haben.
Beim Typen boolean
gab es noch die Diskussion, ob z. B. bei einer Methode isEmpty
dieser Typ nicht die Domäne schon ausreichend beschreibt, was man durchaus so sehen kann. Eine Alternative wäre ein Enum oder State-Objekt, dass z. B. die Ausprägungen Empty
, PartiallyFilled
und Full
hat einzuführen.
Als zweite Session nach dem Mittagessen, haben wir uns für Baby Steps entschieden, d.h. jeder Zyklus von einem grünen Commit über einen weiteren Test oder über Refactoring hin zu einem grünen Commit darf maximal zwei Minuten lang sein. Falls die Zeit überschritten wird, muss zurückgesetzt werden. Dieses Constraint fördert das kleinteilige Arbeiten im TDD-Zyklus.
Ingesamt positives Feedback, der Constraint hat sein Ziel erfüllt. Die Teilnehmer konnte kurze Zyklen erleben. Allerdings gab es auch Probleme, wie z.B. die unterschiedlichen Tasturlayouts die bei einer zeitlichen Einschränkung doppelt im Weg stehen.
Der Constraint hat wieder seinen Zweck erfüllt und die Teilnehmer ein kleinteiliges Arbeiten ausprobieren lassen. Allerdings ist er gerade für Anfänger, die bereits viel neues aufnehmen müssen (GDCR, TDD, etc.), besonders herausfordernd, mit der Gefahr, dass nicht viel mitgenommen werden kann.
Einschränkung auf eine Einrücktiefe pro Methode, sowie eine maximale Methodenlänge von drei Zeilen.
Der Constraint wurde gemischt aufgenommen. Teilweise wurde mit den der drei Zeilen Beschränkung gekämpft (auch in den Tests). Andere Pairs wiederum empfanden es als einfachen Constraint. Sich daraus ergebende Vorteile wurden erkannt (übersichtliche Methoden, Single-Responsibility pro Methode, etc.).
Der Constraint war als "einfacher" Ausklang des Tages gedacht, um den Teilnehmern ein (kleines) Erfolgserlebnis mit auf den Weg zu geben. Das hat auch für ein paar Pairs ganz gut funktioniert.
Insgesamt hat sich dieses Constraint als das bessere erste Constraint erwiesen. Des Weiteren wollen wir, basierend auf dem Feedback, in Zukunft darauf achten, dass die Constraint-Schwierigkeit zum Ende hin nicht mehr zu stark sinkt.
Ingesamt hat es den Teilnehmern wieder gut gefallen. Vor allen Dingen TDD und Pair-Programming ohne Leistungsdruck ausprobieren zu können ist gut angekommen. Des Weiteren konnte jeder sich neue Ideen in den verschiedenes Session einholen. Auch die neue Aufgabe (Vier Gewinnt) wurde positiv aufgenommen und hat die erhoffte Abwechslung zum sonst üblichen Game of Life gebracht.
Alles in allem wieder ein sehr erfolgreiches Event. Bis auf das zu schwere erste Constraint und das als zu leicht empfundene letzte Constraint, ging die Auswahl der Constraints sehr gut auf. Obwohl wir dieses Jahr TDD nicht als Vorgabe gesetzt haben, wurde häufig TDD praktiziert.
Wir freuen uns, dass das Event eine immer größer werdende Teilnehmergruppe anzieht. Und dadurch einen großen Pool an Erfahrungen und Erfahrungsaustausch ermöglicht.
Bei einem GDCR mit einer derartig großen Vielfalt war "Keine Maus" im Endeffekt doch kein Einsteiger-Constraint. Da uns diese Vielfalt wichtig ist, werden wir den Constraint überdenken.
Indem TDD nicht vorgeschrieben wurde, konnten Pairs sich selbständig dafür oder dagegen entscheiden und damit ihren individuellen Schwierigkeitsgrad bestimmen.
Der große Raum hat sich als Vor- und Nachteil erwiesen. Wir hatten das erste Mal Probleme die Constraintbeschreibung durch den Raum zu rufen. Wir wollen auf das Feedback eingehen, aber auf die vorhandenen Mikrofons wollen wir verzichten. Der klare Vorteil des großen Raums ist die geringe Lärmkulisse während die Teilnehmer in der Session sind.
Unsere Feedback-Wände wurden dieses Jahr, dank der Ankündigung direkt am Anfang, mehr genutzt. Auch die Frage nach "Wie habt ihr vom GDCR-Event erfahren" hat sich als teilweise nützlich erwiesen.
https://keybase.pub/chr1shaefn3r/slides/ka-gdcr19.pdf
Vielen Dank an alle Teilnehmer für das konzentrierte Mitmachen und das positive Feedback. Der zweite ganz groẞe Dank geht an Peter Fichtner der uns bei der Fiducia & GAD IT AG unter optimalsten Bedingungen gehostet hat.
Ausgerüstet mit meinem Laptop und Entwicklungsumgebung mit Programmiersprache meiner Wahl betrete ich Saal 1 im FAZ, wo sich schon die ersten mit Kaffee und Butterbrezeln stärken. Von diesen erfahre ich, woher sie kommen, ob sie zum ersten Mal da sind und wie sie vom GDCR erfahren haben. Später in der Mittagspause werde ich noch mehr Zeit haben, mit den Einzelnen zu reden.
Um 9.30 Uhr beginnt es offiziell mit Begrüßung, Organisatorischem und dem Erklären der Aufgabe von heute: Wir sollen die Geschäftslogik von dem bekannten Spiel „Vier gewinnt“ implementieren. In jeder der fünf Sessions programmieren wird dieselbe Aufgabe, variiert durch je ein „Constraint“ – eine Übungsvariante.
Für die Zusammenstellung der Programmierpaare für die erste Session stellen wir uns nach der Anzahl teilgenommener GDCRs auf und teilen uns dann so auf, dass diejenigen mit viel Vorkenntnissen mit jemand mit wenigen Vorkenntnisse zusammenarbeiten.
Mein erster Partner programmiert Kotlin. Das passt prima, denn diese Sprache wollte ich eh mal kennen lernen, da meine Freundin mir davon schon vorgeschwärmt hat.
Ich finde es recht viel auf einmal mit den vielen Infos zu der für mich neuen Programmiersprache und der fremden IDE. Ich versuche mir die Shortcuts zu merken, denn ich weiß, dass damit effizienter und schneller programmiert und die Programme damit fehlerfreier überarbeitet werden können.
Allerdings brauchen wir erstmal mehr Zeit als erwartet, bis alles eingerichtet ist und wir uns über die genaue Aufgabe, Vorgehensweise und Programmiersprache genauer ausgetauscht haben. Daher bleibt gar nicht mehr so viel Zeit für den ersten Constraint „ohne Maus“ zu arbeiten.
Mein Partner der 2. Session ist ein Kollege der Fiducia & GAD aus einer anderen Abteilung, den ich davor noch nicht kannte. Mit Java und dem Constraint Test-Driven-Development (TDD) klappt es ganz flüssig. Mit dieser Technik können gut testbare und schnell lesbare Programme in kleinen Schritten erstellt werden. Hierbei entstehen maschinelle Tests mit extrem hoher Codeabdeckung. Ein Kollege hat mir berichtet, dass in seinem Team die Ticketanzahl durch maschinelle Tests stark reduziert werden konnte. Ich selbst habe erlebt wie ich eine große Klasse in meinem Themengebiet mit TDD wesentlich übersichtlicher und damit schneller erweiterbar gestalten konnte.
In den weiteren Sessions stelle ich fest, dass hier bei dieser Veranstaltung der Softwerkskammer jeder sein Handwerk beherrscht, denn alle meine Programmierpartner verwenden TDD ohne dass wir uns deswegen groß abstimmen müssen. Ich finde es sehr hilfreich, eine Vorgehensweise zu haben, um zügig und gezielt mit jemand Fremden mit der Implementierung loszulegen.
Damit auch Neulinge mit gut ausgestattetem Werkzeugkasten an den Start gehen können, wurde zu Beginn TDD nach Kent Beck in 3 Schritten erklärt. Die offene und konstruktive Atmosphäre hilft dies praktisch umzusetzen. Wer trotzdem noch Fragen hat, kann sich jederzeit an einen der 4 Coaches wenden, die sehr hilfsbereit, freundlich und echte Meister in ihrem Fach sind!
In der Pause lerne ich T. kennen. Sie arbeitet in Pforzheim, hat viele Kollegen in Indien und kommt gerne zum GDCR, da sie sich hier mit anderen Programmierern vor Ort austauschen kann.
In der 3. Session schlägt sie vor, dass ich doch gleich die Tastatur übernehmen soll, obwohl ich die Sprache Python noch gar nicht kenne. Sie ist die perfekte Navigatorin und führt mich toll in die für mich neue Sprache ein. Ungern gebe ich dann die Tastatur an sie ab, weil es so gut klappt. Der Constraint keine primitiven Datentypen zu nutzen, ist gar kein Problem. Über die Vorteile, mehr Objekte zu verwenden, unterhalten wir uns in der großen Runde in der anschließenden Retro.
Beim Mittagessen in der Kantine habe ich die Möglichkeit mich mit den verschiedenen Programmierern zu unterhalten.
Gegenüber von mir links sitzt C. aus einem großen bekannten Unternehmen, der dort erst vor ein paar Wochen den Bereich gewechselt hat. Das Thema Testautomation liegt ihm in seiner neuen Abteilung besonders am Herzen.
Mir gegenüber sitzt eine Physik-Studentin, die nach dem erst kürzlich abgeschlossenen Studium überlegt, ob sie in die Softwareentwicklung einsteigen soll. Natürlich erwähne ich gleich, dass die Fiducia & GAD neue Mitarbeiter sucht!
Rechts daneben sitzt ein langjährig erfahrener Mitarbeiter. Früher war er eine Zeitlang in der Qualitätssicherung tätig, nun ist er wieder in der Entwicklung mittendrin dabei und erzählt mir von seinen Erfahrungen in den verschiedenen Abteilungen.
Nach der Mittagspause möchte ich noch die Programmiersprache Go anschauen, denn schließlich hat mir letztes Jahr ein Kollege begeistert davon erzählt. Als mein Programmier-Partner erfährt, dass wir nun in Baby-Steps von 2 Minuten programmieren sollen, fragt er mich, ob wir das wirklich mit der für mich neuen Programmiersprache probieren sollen oder ob ich nicht doch lieber Java nehmen möchte. Aufgrund der positiven Erfahrung mit dem Baby-Step-Partner letztes Jahr, der immer total ruhig und cool geblieben ist, entscheide ich mich für Go.
Mein Partner legt gleich mit dem ersten Test los und schafft diesen tatsächlich in den 2 Minuten. Nach dem Committen legen wir erstmal das Smartphone mit der Stoppuhr beiseite und er erklärt mir die Grundlage dieser Sprache. In meinem ersten Versuch schaffe ich es selbst nicht, als ich das nächste Mal drankomme – dank seiner guten Anleitung – dann doch. Bald stellen wir fest, dass wir für den nächsten Test den Schritt wesentlich kleiner wählen müssen, um es in 2 Minuten hinzubekommen. Allmählich haben wir es raus, wie groß – genauer gesagt – wie klein die Schritte sein müssen und ich bekomme es nun auch in 2 Minuten hin! Wow, und das in einer fremden Sprache!
Nicht nur große Elefanten sollte man vor dem Verspeisen in Scheiben schneiden. Das ist auch mit kleinen Mäusen notwendig, wenn die Zeit eng bemessen ist! Und erst recht sollte man das Aufteilen der Problemstellung fürs Programmieren üben!
In der Abschlusssession wird es wieder einfacher: In Java programmieren wir Methoden, die maximal 3 Zeilen haben dürfen. Mit Hilfe von Eclipse geht es ganz schnell, den Code in eine neue Methode zu extrahieren, wenn diese zu groß wird. Wir kommen recht zügig voran.
Ich weiß, wenn auch in der Praxis darauf geachtet wird, dass die Methoden klein sind, bleibt der Code übersichtlich und Erweiterungen sind schneller und damit kostengünstiger.
Während ich an einer Stelle überlege, ob dieser Schritt nicht zu groß ist, scheint meine Programmierpartnerin meine Gedanken erraten zu haben und spricht genau dies aus. Diese Gedankenübertragung muss daran liegen, dass sie – wie ich – aus dem Schwäbischen kommt!
Abends um 18 Uhr lasse ich die zusätzlichen Trainingsgewichte an Händen und Füßen – die Constraints – im Trainingszentrum zurück, gehe mit gestärkten Programmierer-Muskeln zum Auto und freue mich schon auf den GDCR im nächsten Jahr!
Ein großes Dankeschön an die Softwerkskammer für die inhaltliche Gestaltung und an die Fiducia & GAD für Hosting und Sponsoring!
]]>Zu finden unter:
www.menschenwuerdigeprojektgestaltung.de/reportage/besuch-bei-der-softwarekammer-karlsruhe
]]>Wie auch im letzten Jahr waren wir im Trainingscenter der Fidicua GAD IT AG in Karlsruhe zu Gast.
In der Einleitung wurde der Ablauf des Tages, die Programmieraufgabe (Game of Life), Four Rules of Simple Design, TDD und PairProgramming vorgestellt.
Um die Teilnehmer in die Einleitung mit einzubeziehen, ließen wir sie nach ihrer "Hauptprogrammiersprache" Gruppen bilden. Somit konnten die Teilnehmer auch sehen, mit wem man in einer der Session ein Pair bilden könnte um eine Programmiersprache auszuprobieren.
Das Finden der ersten Pairs haben wir unterstützt, indem wir alle Teilnehmer gebeten hatten, sich nach ihrer TDD-Erfahrung in eine Reihe aufzustellen. Die Reihe wurde dann zusammengeklappt, sodass diejenige Person mit der meisten TDD-Erfahrung mit derjenige Person mit am wenigsten TDD-Erfahrung gepaired hat, diejenige Person mit der zweit meisten TDD-Erfahrung mit derjenigen Person mit der zweit wenigsten TDD-Erfahrung, usw.
Hierbei geht es darum, alles was noch getan werden muss, auf einen Zettel zu notieren. Somit lässt sich auf den jeweiligen Aspekt fokusieren, weitere Dinge werden direkt auf einen Zettel geschrieben. Hat man nun den Aspekt abgeschlossen kann man bei Bedarf die Liste umpriorisieren oder doch nicht mehr benötigte Dinge streichen.
Teilnehmer haben berichtet, dass man sich bremst, zu große Aufgaben angehen zu wollen und dahin kommt, kleine Schritte zu machen. (Es war nicht ganz klar wie viel Anteil TDD vs. Beck's Inbox daran hatte). TDD Neulinge haben sich schwer getan, erst den Test zu schreiben, bzw. einen ersten kleinen sinnvollen Test zu finden.
Zum Einstieg ein leichtes Constraint hat wieder gut gepasst. Allerdings wurde Beck's Inbox nicht konsequent angewendet. Zumeist wurden Block und Stift genutzt um Spielfeld, Definition von Nachbarn und Algorithmen zu visualisieren.
Pairprogramming ohne miteinander reden zu dürfen. Hier in der Ausprägung kooperatives pairing, im Kontrast zu "evil" pairing, bei dem der Partner bewusst versucht zu sabotieren.
Fragen zu Sprache, IDE, Shortcuts, OS waren explizit erlaubt. Ein Umgehen des Constraints durch Kommentare im Code oder Schreiben auf einem Block war untersagt!
Ping-Pong haben wir erklärt als Wechsel der Rolle (Driver/Navigator) jeweils nach der Erstellung den nächsten roten Tests.
Insgesamt haben die Teilnehmer Vor- und Nachteile dieses Constraints erlebt. Vorteile waren z.B. die Erkenntnis, dass man mit guten Variablen-, Methoden- und Testnamen erstaunlich weit kommen kann. Außerdem kann es dabei helfen, Entscheidungen treffen zu müssen.
Allerdings ergeben sich auch einige Reibungspunkte, wie zum Beispiel die fehlende Absprache zu Konzepten, Begriffen und Modellentscheidungen. Das künstliche Unterbinden von Kommunikation führt zu sehr konstruierten Problemen, wie z.B. darf bei einem "offensichtlichen" fachlichen Fehler (assertThat(add(1, 2), is(4)
) dem Partner kein Hinweis gegeben werden kann/darf und somit erstmal eine eigentlich fehlerhafte Implementierung entsteht. Zusätzlich erlebten die Pairs verlängerte Zyklen bis wieder gewechselt wurde.
Immer wieder ein spannendes Constraint. Allerdings werden die Probleme um die künstliche Kommunikationsunterbindung deutlich. Der Kosten-Nutzen Mehrwert dieses Constraints sind im Vergleich zu einem reinen Ping-Pong oder Naiv Ping-Pong nicht deutlich.
Nach dem Mittagessen haben wir mit dem Constraint TDD-Zyklus weitergemacht. Es geht darum, nochmal deutlich den Fokus auf den red-green-refactor Zyklus zu legen. Wir haben die Teilnehmer ermutigt, mit den Greenbar-Patterns (Fake, Obvious Implementation, Triangulation) zu arbeiten und die eigentliche Implementierung in der Refactoring-Phase entstehen zu lassen.
Die Teilnehmer waren zu einem erleichtert, dass sie wieder miteinander reden durften, zum anderen taten sie sich schwer in den Anfängen der Implementierung die Refactoring-Phase auszunutzen, da es noch nicht viel zu refaktoren gab.
Die Vermutung ist, dass doch nicht ganz konsequent der TDD-Zyklus angewendet wurde. Im speziellen die Verteilung zwischen geschriebenem Code in der "green"-Phase und "refactor"-Phase. Das heißt es wurde "zu viel" in der green-Phase implementiert und nicht rein auf "make it green" fokusiert.
Einschränkung auf eine Einrücktiefe pro Methode, sowie eine maximale Methodenlänge von drei Zeilen.
Das Feedback war gemischt. Einige Pairs empfanden, dass ihr Code schlechter wurde durch das stumpfe einhalten der Regeln. Andere Pairs haben durch das Befolgen besseren, testbareren Code geschrieben. Zusätzlich gab es Pairs, die das Constraint als Chance gesehen haben, ihre Struktur zu überdenken (z.B. das Board anstatt als Array als Liste zu implementieren), wodurch sie zu neuen Lösungsansätzen gefunden haben.
Es scheint den Teilnehmern schwer zu fallen, erstmal "dreckigen" Code zu schreiben um diesen dann in der Refactoring-Phase aufzuräumen. Die Constraint-Erklärung könnte wir noch mehr auf die Intention eingehen, um zu vermeiden, dass Stumpf die Regeln eingehalten werden. Zusätzlich wurde als Abschwächung "one dot per line" nicht erwähnt, was wiederum zu Ideen der Teilnehmer geführt hat, dies auszunutzen.
Als letzte Session des Tages, haben wir uns für Baby Steps entschieden, d.h. jeder Zyklus von einem grünen Commit über einen weiteren Test oder über Refactoring hin zu einem grünen Commit darf maximal zwei Minuten lang sein. Falls die Zeit überschritten wird, muss zurückgesetzt werden. Dieses Constraint fördert das kleinteilige Arbeiten im TDD-Zyklus.
Auch hier gab es wieder gemischtes Feedback zwischen Pairs, denen der Zeitdruck geholfen hat kleine Schritte zu gehen. Während andere Pairs sich sehr schwer getan haben kleine Schritte zu finden. Des Weiteren ist aufgefallen, dass gerade in diesem Constraint das Ausprobieren von neuen Programmiersprachen und/oder IDEs doppelt schwierig wird.
Dieser Constraint brachte die Teilnehmer regelmäßig aus ihrer Komfortzone, was genau das war, was wir erreichen wollten. Das Feedback war wie zu erwarten gemischt, dennoch halten wir es für eine gute Übung um in Richtung kleinteiligem Entwickeln zu kommen. Zusätzlich deckt der Constraint konsequent zu große Schritte auf.
Das Feedback war überwältigend positiv. Die wieder einmal sehr heterogene Gruppe, mit den verschiedensten Hintergründen, Programmiersprachen und Erfahrungsleveln, hat wieder voll gewirkt und jeder konnte neue Ideen mitnehmen und neue Programmiersprachen ausprobieren.
Ein durchweg erfolgreiches Event: Positive Stimmung, tolles Miteinander arbeiten, konstruktive Diskussionen. Unser Zeitplan hat gut gepasst. Die Entscheidung hin zu fünf Sessions und einem leicht späteren Startzeitpunkt hat sich als sinnvoll dargestellt. Gerade in Diskussion mit TDD-skeptischen Teilnehmern konnten einige neue Blickwinkel ausgetauscht werden.
Peter hat sich nach dem offiziellen Ende bereiterklärt, nochmal im Mob die Aufgabe zu bearbeiten. Mit Fokus auf Outside-In konnten nochmals dediziert Vor- und Nachteile von TDD diskutiert werden. Hintergrund war, es den in den Session-Retros aufkommenden TDD-Diskussionen nochmals ein Forum zu bieten und am gemeinsam geschaffenen Codestand zu diskutieren.
https://keybase.pub/chr1shaefn3r/slides/ka-gdcr18.pdf
Vielen Dank an alle Teilnehmer für das konzentrierte Mitmachen und das positive Feedback. Der zweite ganz groẞe Dank geht an Peter Fichtner der uns bei der Fiducia & GAD IT AG unter optimalsten Bedingungen gehostet hat.
Anfänglich noch in eine konventionelle Unternehmensstruktur eingeteilt, konnten die „Mitarbeiter“ erfahren, welche Schmerzen es bereitet, wenn Development, Test und Operations getrennt voneinander organisiert sind. Gebundenes Kapital, Wissensinseln und Silodenken wurden in kürzester Zeit Realität.
Über die Erkenntnisse aus gemeinsamen Retros wandelte sich die Unternehmenskultur aber schließlich im Lauf des Workshops immer mehr von einer Kultur des „Nebeneinander“ zum „Miteinander“. Durch den Beitrag jedes einzelnen wurde DevOps möglich. Die Ausbringung der Software beschleunigte sich und die Unternehmensgewinne stiegen.
Unser Dank geht an die mutigen Teilnehmer, die sich auf das Experiment eingelassen haben. Wir haben viele nette und offene Menschen kennengelernt, viel gelacht und neue Erkenntnisse gewonnen.
Dankeschön! Gerne wieder!
]]>Nachdem Peter den TDD-Zyklus vorgestellt hatte, haben wir uns noch darüber ausgetauscht, warum Baby Steps eine gute Übung sein könnte.
Dann ging es schon los und die Timer klingelten und die Teilnehmer schwitzten :-).
Als Einstieg gab es einen Überblick über die verfügbaren Tools im Java-Umfeld durch Stefan und Urs: EvoSuite, Randoop und Testrecorder. Wir haben die Leistungsfähigkeit der genannten Tools besprochen. Die Folien des Vortrags befinden sich hier.
In der Diskussion kam dann noch die Themen
Um die Robustheit eines Programms gegen große, ungewöhnliche Strings zu testen gibt es die Big List of Naughty Strings.
]]>Von dort aus haben wir auf Consumer Driven Contract Testing mit Pact gewechselt. Pact ist ein Werkzeug um Contracts zwischen, über json kommunizierende Services aufzuzeichnen und zu validieren. Der gute alte Taschenrechner auf Provider Seite wurde von verschiedenen Consumern {OperationsClient, SumClient} abgefragt. Der Abend endete mit einigen Details zur pact-foundation und persönlichen Einschätzungen des Projekts.
Wer es nicht zum Treffen geschafft hat kann sich die Folien und den Beispielcode auf Github anschauen.
Der Talk "Verifying Microservice Integrations with Contract Testing" gibt in ~40 min einen guten Einstieg in pact.
Für einen Hands-On Einstieg gibt es eine Reihe sprachspezifischer Workshops die man in ~2h durcharbeiten kann.
Die Dokumentation findet ihr auf pact.io und den Pact Code gibt es auf Github.
Statisch (d.h. nicht ausführen) Source-Code (manchmal auch Bytecode oder Binärcode) Analyse
Leichtgewichtig:
Schwergewichtig: Verifizierend vs. Nicht-Verifizierend
Es wird nicht viel (Zeit) investiert in SCA
Früh einsetzen, nicht erst wenn "die Kacke am dampfen ist"
Idealerweise in IDE/Entwicklungsprozess integrieren, muss aber integriert werden
Akzeptanz im Team (aber wenn die Schmerz haben, akzeptieren sie die Kosten)
Wie Stakeholder motivieren?
-> es muss Schmerz (von altem Projekt) da sein
Wie suzkessive anfangen?
-> Erst mal ganz viele Kategorien ausschließen!
Wenn ein Bug/Warnung zu schwer zu verstehen/fixen? (z.B. Boolean-Variable undefined)
-> man holt sich eine Umgebung und probiert aus;
oder man schreibt Justification, ist aber keine wirkliche Lösung
Das Erweitern der Test, so dass wir auf vollständige Abdeckung (gemessen in abgedeckten Zweigen) hat uns recht lange beschäftigt. Dafür konnten wir zum Ende sehr zügig und mit Zuversicht den Code refaktorieren.
Abschließend hat uns Stefan noch einen kurzen gezeigt, wie man mit dem von ihm entwickelten Testrecorder Golden-Master-Tests für die Codebasis aufzeichnen kann. Da dies auf großes Interesse stieß, hat sich Stefan bereit erklärt beim Februartreffen einen Workshop zum Testrecorder zu machen.
]]>Durch das Feedback aus dem letzten Jahr ("einmal ohne Constraint bitte") wurde in der ersten Runde komplett auf Constraints verzichtet. Damit hatten die Teilnehmer die Möglichkeit sich voll auf das Problem bzw. die Domäne zu konzentrieren und diese dadurch kennen zu lernen. Gerade auch um eine neue Programmiersprache auszuprobieren eine gern genutzte Session.
Der kleine Bruder von Object Calisthencs: Parameter und Rückgabewerte dürfen nicht aus primitiven Datentypen wie Zahlen oder Strings bestehen sondern müssen domainenspezifische Objekte gekapselt werden (Ausnahme: Die Konstruktoren dieser domainenspezifische Objekte).
Als letzte Session vor der Pause, haben wir uns für Baby Steps entschieden, d.h. jeder Zyklus von einem grünen Commit über einen weiteren Test oder über Refactoring hin zu einem grünen Commit darf maximal zwei Minuten lang sein. Falls die Zeit überschritten wird, muss zurückgesetzt werden. Dieses Constraint fördert das kleinteilige Arbeiten im TDD-Zyklus. Vermeintlich kleinste Schritte lassen sich oft in noch kleinere Schritte unterteilen.
Retro: Da sich viele Gruppen doch recht schwer getan haben, stellte Peter in der Retro die green bar patterns, im deutschsprachigen oft auch als "drei Wege zu grün" bezeichnet ("obvious implementation", "fake it 'til you make it" und "triangulation") vor.
Klar soweit?
Retro: Wurde als recht einfaches Constraint empfunden.
Als einzige Ausnahme, wurde vor dieser Session der Code nicht gelöscht. Die Paare wurden wie gehabt gewechselt, wobei nun einer der "alt eingesessene" ist, und einer der "neue". Nun sollte ein gemeinsames Code-Review stattfinden, „Wie gut wurde 'Four Rules of Simple Design' eingehalten“? Sind die Tests lesbar?
Retro: Der Constraint hat seinen Zweck erfüllt, die Teilnehmer mussten sich mit dem gegebenen Code auseinandersetzen, neue Kompromisse eingehen. Ganz im Gegensatz zu den vorherigen Sessions in den stets auf grüner Wiese begonnen werden konnte.
https://keybase.pub/chr1shaefn3r/slides/ka-gdcr17.pdf
Vielen Dank an alle Teilnehmer für das konzentrierte Mitmachen und das positive Feedback. Der zweite ganz groẞe Dank geht an Peter Fichtner der uns bei der Fiducia & GAD IT AG unter optimalsten Bedingungen gehostet hat.
Weitere testbare Aspekte waren:
Bei Single Page App Frameworks bietet sich hingegen ein Unit-Test einzelner Komponenten an. Das hat uns zu der Diskussion geführt welche Werkzeuge es für das testen von JavaScript-Code insbesondere im Frontend gibt:
Jasmine biete gerade für ältere JavaScript-Projekte, in denen man schnell eine Test-Infrastruktur bereitstellen möchte, die Möglichkeit mit der Standalone-Version zu starten.
Im Zuge der Diskussion kamen wir noch auf Build-Tools für JavaScript-Projekte zu sprechen:
Da es gerade für Einsteiger auf dem Gebiet der JavaScript-Frontend-Entwicklung schwierig ist, im "Tools-Zoo" durchzublicken, bieten die meisten Frontend-Frameworks Werkzeuge an um schnell ein Grundgerüst zu erstellen, z. B. Angular CLI, Create React App oder vue-cli. Daneben gibt es noch sogenannte "Seeds", die ein statisches Grundgerüst bieten. Der Vorteil der erstgenannten Werkzeuge liegt daran, dass man beim Erstellen der Grundgerüste verschiedene Dinge konfigurieren kann.
]]>Cheers,
Christoph
Anhand von Beispielen haben wir uns die Funktionsweise der Observables erschlossen.
Dabei haben uns folgende Hilfsmittel geholfen:
Aber was ist mit den Security Tests und warum bleiben die auf der Strecke liegen?
Es ist einfach, wenn man folgenden Fragen beantworten kann und hier sind die Antworten darauf:
**Structure das frame work
**
\bdd-security-master\zap
liegt der OWASP Zed Attack Proxy tool\bdd-security-master\src\test\resources\drivers
liegen die selenium web driver\bdd-security-master\src\test\resources\features
liegen die cucumber feature file beschreiben den test.\bdd-security-master\src\test\java\net\continuumsecurity\examples\ropeytasks
liegt die selenium navigation class Bsp.\bdd-security-master\
liegt die config.xml
Wie benutze ich das framework ?
`\bdd-security-master\config.xml` editieren und anpassen
Die selenium navigation class implementieren unter `\bdd-security-master\src\test\java\net\continuumsecurity\examples\ropeytasks` liegt ein Bsp.
Start parameter
gradlew.bat -Dcucumber.options="--tags @iriusrisk-cwe-89" scan für sql injection
gradlew.bat -Dcucumber.options="--tags @iriusrisk-cwe-79” scan für XSS cross site script
gradlew.bat -Dcucumber.options="--tags @app_scan" scan für alle Top 10
Mit dem BDD-Security Framework wird der Traum von Continuous Security Testing wahr.
Viel Spass beim Security Testing
Djelloul Belarbi (Senior Software Quality Engineer bei E2open)
Die Slides findet ihr hier: Slides
Die beiden gezeigten Repositories:
Bei Fragen erreicht ihr uns unter:
aleksandar.thoshovski@abas.de
pascal.laier@abas.de
After the introduction we took a deeper look at a possible test setup for testing React-Redux apps. Jest, developed by Facebook, was presented as a possible test-runner. With a build-in option to easily enable the creation of a coverage report, and snapshots test to easier test UIs, it's a good pick to start with.
Additionally we added Enzyme, developed by AirBnB, to the mix. This library provides a great API to write assertions on UI criterias (e.g. a rendered component should have a exactly three elements in a list).
The example application used to discuss the test-strategies was "fml" currently developed as playaround-project by Christoph Haefner.
While going through one of the container-component tests, which was particularly interesting as it tests a user-interaction scenario, we had a hart time figuring out why the tests works.
We couldn't quite wrap our head around how Enzymes second parameter on the simulate method is handled.
Thanks to all participant for great discussions and insights. I definitely learned a lot!
]]>Durch das Feedback aus dem letzten Jahr ("einmal ohne Constraint bitte") wurde in der ersten Runde komplett auf Constraints verzichtet. Damit hatten die Teilnehmer die Möglichkeit sich voll auf das Problem bzw. die Domäne zu konzentrieren und diese dadurch kennen zu lernen.
Der kleine Bruder von Object Calisthencs: Parameter und Rückgabewerte dürfen nicht aus primitiven Datentypen wie Zahlen oder Strings bestehen sondern müssen domainenspezifische Objekte gekapselt werden (Ausnahme: Die Konstruktoren dieser domainenspezifische Objekte).
Um die Teilnehmer mit viel Gesprächsstoff in die anschließende Mittagspause schicken zu können, haben wir uns für "Mute Ping Pong" entschieden, d.h. das Sprechen in den Pairs ist während der Session verboten (Ausnahmen Fragen zum Editor/IDE). Erkenntniss: Die Teilnehmer haben erkannt, wie wichtig der Austausch während der pairens ist.
Das Constraint Baby Steps (drei Minuten um einen roten Test zu schreiben und ihn dann grün zu kriegen) fördert das kleinteilige Arbeiten im TDD-Zyklus. Vermeintlich kleinste Schritte lassen sich oft in noch kleinere Schritte unterteilen.
Erkenntniss: Die Teilnehmer haben die Regel umschifft, in dem sie ausserhalb der drei Minuten überlegt und besprochen haben, was sie genau vorgehen wollen und damit die reine Tipparbeit in die drei Minuten gelegt.
Während der ersten vier Sessions haben die Teilnehmer meist zu "obvious implementation" und "Fakes" gegriffen. Wir haben zu Beginn die green bar patterns, im deutschsprachigen oft auch als "drei Wege zu grün" bezeichnet ("obvious implementation", "fake it 'til you make it" und "triangulation") vorgestellt. Die Teilnehmer sollten sich dann für jeden Zyklus im Vorfeld überlegen, auf welchem der drei Wege sie den kommmenden Schritt lösen möchten.
Erkenntnis: Die Vorstellung hilft den Teilnehmern zukünftig eine gemeinsame Sprache zu sprechen. Viele haben unbewusst bzw. intuitiv zwei bis drei der Möglichkeiten genutzt.
Zum Abschluss gab es ein eher methodisches Constraint: Die Teilnehmer sollten bewusst versuchen ihre Ideen und Aufgaben (d.h. Testfälle, Refactorings, ...) auf einem Stück Papier festzuhalten, zu priorisieren und diese Liste während des Arbeits entsprechend zu aktualisieren: erledigte oder nicht mehr als nötig angesehene Aufgaben streichen, neue Aufgaben oder Ideen aufnehmen, Aufgaben neu priorisieren. Diese Methode wird u.a. in Kent Becks Buch "Test Driven Development by Example" vorgestellt, daher auch der Name des Constraints.
Erkenntnis: Kam zu spät, wäre in einer der ersten Session besser platziert gewesen.
Im folgenden sind die Session mit ihren Constraint aufgeführt.
Die erste Session diente zum Aufwärmen und das Problem kennenzulernen. Daher als Constraint "nur" eine verstärkte Variante von Becks "Four rules of simple design". Da die Pairs erstmal ins Problem reinfinden mussten, lag der Fokus weniger auf Einhaltung des Constraints.
Lesson learned: die erste Runde dient zum Aufwärmen :-).
Als erste "richtiges" Constraint wurde ein Aspekt der Object Calisthencs verwendet: primitive Datentypen wie Zahlen oder Strings dürfen nur gekapselt in Objekten, die die Domäne beschreiben, vorkommen.
Ein bisschen "echtes" OO üben :-).
Lesson learned: die Teilnehmer sind sehr erfinderisch darin, die Regeln auszuhebeln, da es sich für die meisten sehr komisch anfühlt ohne jegliche Rückgabetypen zu arbeiten.
weiterführende Links:
Die Pairs durften nicht miteinander reden!
Lesson learned: Es wandert tatsächlich viel mehr Information in die Methoden- und Testnamen. Wissen das sonst undokumentiert bleibt ist jetzt schriftlich festgehalten.
Ziel war es den Fokus auf den TDD-Cycle (roter Test -> grüner Test -> Refactoring) zu lenken.
Das Constraint Baby Steps fördert das kleinteilige Arbeiten im TDD-Zyklus und stellt damit eine Verschärfung der vorherige Session dar.
Lesson learned: Durch die Aufteilung
wurde der Fokus auf Refactoring erstaunlich erhöht.
Die verwendeten Folien stehen hier zum Download bereit: "Klick".
Es hat uns sehr viel Spaß gemacht, da sowohl während der Sessions als auch in den Retrospektiven nach den Sessions interessante Diskussionen aufgekommen sind.
Hilfreich war, dass wir schon einen grob Plan für die Sessions und die eingesetzten Constraints hatten an dem wir uns lang hangeln konnten, auch wenn wir währendes des Tages kleine Anpassungen vorgenommen haben.
Die verschiedenen Constraints hätten wir jedoch besser erklären können, so dass die Teilnehmer gleich zu Beginn der Session einen klare Vorstellungen von den Rahmenbedingungen und ihren Bedeutungen haben. Teilweise wurden die Constraints erst klar, nachdem wir als Facilitators bei den Pairs "interveniert" haben.
Ein weiterer interessanter Gast war Julian von Welcome2Work, der sein Projekt vorgestellt hat und der auf der Suche nach Unterstützung bei der Weiterentwicklung bzw. Neuentwicklung der Webseite ist. Wir haben kurz diskutiert, was für Möglichkeiten es gibt und ob vielleicht eine Vernetzung mit anderen Plattformen sinnvoll wäre. Wer Interesse hat, bei diesem Projekt mitzuwirken, kann sich mit Julian über die Welcome2Work-Webseite in Verbindung setzen.
Danach haben wir uns ein paar der Projekte des Refugee Hackathon angeschaut und festgestellt, dass einige davon noch nicht über das Ideensammlungs-Stadium hinausgekommen sind; andere existieren schon, aber nur in sehr rudimentärer Form (z. B. das Refugee Phrasebook). Keiner von uns hat so recht Zeit und Muße, sich in einem solchen Projekt über einen längeren Zeitraum zu engagieren,
aber ein Wochenende konnten sich einige schon vorstellen. So kamen wir auf die Idee, im kommenden Frühjahr (ab April) selbst einen Hackathon auf die Beine zu stellen. Dafür benötigen wir Raum und Sponsoren, die uns mit Essen versorgen. Ggf. sollte im Vorfeld schon eine Auswahl von Projekten getroffen werden, bei denen schon eine gewisse Basis da ist und die mit einem solch kurzfristigen Einsatz auch sinnvoll unterstützt werden können. Hier ist es vermutlich ratsam, sich vorher mit den Organisatoren des Refugee Hackathon in Berlin oder Mannheim abzustimmen und von dort Tipps einzuholen.
Was die grundsätzliche Durchführung des Hackathon angeht, ist es sicher nicht verkehrt, sich mit regionalen Organisationen kurzzuschließen, die Erfahrung mit sowas haben. Hier wurde die Nerd-Zone genannt, die in Karlsruhe ansässig ist. Auch Entropia ist sicher ein guter Ansprechpartner, sie führen jedes Jahr die Gulaschprogrammiernacht durch und haben bestimmt viel Erfahrung.
Zum Abschluss des Abends, nachdem wir uns mit Pizza gestärkt hatten und die Kalorien beim Kickern wieder losgeworden waren, haben wir noch einen Vortrag von Rami Ismail, Spieleentwickler bei Vlambeer in den Niederlanden, angeschaut. Dieser Vortrag hatte auch irgendwie was mit dem Thema zu tun...
Zum Abschluss noch eine allgemeine Linksammlung zum Thema. Falls Ihr andere Links kennt, ergänzt sie bitte hier!
Refugee Hackathon mit 11 Projekten
Refugeehelper mit unzähligen (oft regionalen) Projekten
Refugees on Rails in Berlin
Refugee Guide, Orientierungshilfe im deutschen Alltag
Yallah Deutschland Deutsch-Arabische Informationsseite von Krautreporter
Das syrische Haus in Deutschland, Facebook-Seite mit allen möglichen Infos, Fragen und Antworten (oft in Arabisch)
Flüchtlinge Willkommen, Vermittlung von Privatunterkünften
In Deutschland als Flüchtling studieren, viele Informationen zum Studium
Das wohl bekannteste ist "Git Large File Storage". Außerdem ist noch git-annex zu erwähnen.
Beide verfolgen das gleiche Prinzip: Nur die Metadaten werden in git eingecheckt, die Datei selbst wird separat gespeichert.
Die üblichen Verdächtigen für Mac-User: Tower und SourceTree (auch für Windows).
Wer es mehr konsolen-basiert mag, kann sich mal tig anschauen.
Die große Mehrheit verwendet Gitlab. Wahlweise kann man sich auch Github-Enterprise ins Haus holen.
Eine noch viel, viel ausführlicher Linkliste gibt es hier: awesome-git.
Und wer den Vortrag verpasst hat, sich aber trotzdem mehr Wissen über die Git Internals anlesen will, dem kann ich die ausführliche Doku empfehlen: 10.1 Git Internals - Plumbing and Porcelain.
Wahlweise ein gut geschriebener Essay: Git from the inside out (danke an @michaellihs für den Link).
Cheers,
Christoph
Beim Mocken von Klassen in Unittests besteht immer die Gefahr, dass sich der Mock anders verhält als die tatsächliche Klasse. Deswegen genügt es nicht nur Unittests zu schreiben, sondern mit Hilfe von Integrationstests muss sichergestellt werden, dass die einzelnen Units auch korrekt zusammen arbeiten.
Integrationstests selbst haben aber auch einige Nachteile, wie z.B. Laufzeit, erhöhter Setupaufwand, geringere Aussagekraft.
Mit dem assume-verify-approach kann man sich ganz auf Unittests konzentrieren und trotzdem die Sicherheit haben, dass am Ende die einzelnen Units zusammen funktionieren. Und das ganze ohne einen einzigen Integrationstest.
Link zu chadojs:
https://github.com/robindanzinger/chadojs
Installieren via npm:
npm install chado
Folien zum Vortrag:
https://github.com/robindanzinger/chado_presentation
Hier noch der versprochene Link zu den Talks von Dan North bei der CraftConf
]]>Jeremias ist gerade dabei mit ReTest ein eigenes Unternehmen basierend auf einem Software-Werkzeug zu gründen. Diese Software realisiert vollautomatisches Regressionstesten auf der Benutzeroberfläche. Zuerst werden entsprechen Monkey-Testing zufällige Benutzereingaben (Klicks und Tastatureingaben) generiert. Diese "Tests" werden dann mit einem Genetischen Algorithmus verbessert um die Code-Abdeckung (Coverage) zu erhöhen. Die Funktionsweise von Genetischen Algorithmen wurde in einem ausführlichen Beispiel anhand der Türme von Hanoi gezeigt. Dann wird anhand dieser Tests der Zustand der Benutzeroberfläche festgehalten. Dieser Zustand kann nun genutzt werden, um Änderungen des getesteten Programmes zu verdeutlichen. Der Nutzer kann dann relativ schnell entscheiden, ob diese Änderungen gewollt sind, oder nicht.
Alle Code-Beispiele und weiterführende Informationen finden sich in den Links in obigem Text.
]]>Das Thema Continuous Delivery (CD) hatte ich beim letzten Treffen spontan vorgeschlagen, nachdem Nicole nach einem Thema für das nächste Treffen gefragt hatte.
Meine Präsentation (Folien siehe unten) war darauf angelegt einen schnellen Einstieg zu geben um eine Diskussion anzustoßen.
Noch vor der eigentlichen Präsentation machten wir eine Vorstellungsrunde, bei der auch jeder ein paar Worte zum Thema CD sagte.
Bereits aus der Vorstellungsrunde ergab sich der erste Diskussions-Stoff. Einige äußerten sich dahin gehend das es sich für sie sehr riskant anhört jede Änderung auszuliefern. Andere vertraten die Meinung das es dem Kunden zu viel wird wenn er ständig neue Software ausgeliefert bekommt.
Genau hier wurde Continuous Delivery mit Continuous Deployment verwechselt. Bei Continuous Delivery geht es nicht darum jede Änderung automatisch Auszuliefern. Es geht viel mehr darum sich so zu organisieren, dass jede Änderung ein Release Candidate ist und mit einem Knopfdruck ausgeliefert werden könnte.
Martin Fowler schreibt zu Continuous Delivery: "Continuous Delivery is a software development discipline where you build software in such a way that the software can be released to production at any time."
Carl Caum (Product Owner bei PuppetLabs) hat speziell zum Thema Continuous Delivery vs. Continuous Deployment einen sehr informativen und anschaulichen Blog geschrieben: Continuous Delivery Vs. Continuous Deployment: What's the Diff?
Eine besonders interessante Diskussion entstand als ich Continuous Integration als Vorraussetzung für Continuous Delivery angesprochen habe.
Es stellte sich heraus, dass die konkrete Anwendung von CI in mehreren Interpretationen gelebt wird.
Konkret ging es darum ob Akzeptanztests am Anfang eines Sprints gleich scharf gestellt werden und während des Sprints darauf hingearbeitet wird alle Tests grün zu bekommen.
Dagegen stellte sich Jez Humbles Erklärung was CI ist. Der wichtige Teil: So lange der Build oder die Tests fehlschlagen darf keiner weiterarbeiten, es sei den er löst das Problem. Das heißt das der Build zu jedem Zeitpunkt lauffähig sein muss.
Die Diskussion erweiterte sich dann dahingehend wie was in der Praxis umgesetzt werden kann, denn alle waren sich einig das Akzeptanztests geschrieben werden sollten. Eine mögliche Lösung war hierbei das nutzen von "Ignore" (sofern ein derartiges Feature vom verwendeten TestRunner unterstützt wird). Das heißt alle Akzeptanztests werden geschrieben, aber so lange beim zentralen Build Ignoriert, bis die Implementierung fehlerfrei läuft. Lokal kann die Lauffähigkeit mittels dem Akzeptanztests überprüft werden.
Insgesamt wieder eine sehr informative und lebhafte Veranstaltung.
Nochmal vielen Dank an Lindenbaum und Rusi für den riesigen Service!
Cheers,
Christoph
Folien: Herunterladen
Video: Continuous Delivery with Jez Humble
Buchtipp:
Das Thema Refactoring for Testability war nichts neues auf dem Radar, hat aber anscheinend Interesse geweckt. Die Teilnahme war wie immer sehr lebhaft und es sind einige interessante Diskussionen entstanden. Die Folien sind mittlerweile Online.
Für mich war der Ablauf sehr positiv und gleichzeitig unerwartet. Kaum war ich nach der Theorie für zwei Minuten aufs Klo, hatten alle mit den Aufgaben angefangen. Irgendwann ist dann die Struktur verloren gegangen und ein Impro-Theater entstanden, aber es hat mich trotzdem gefreut.
Schön fand ich das viele sehr fortgeschritten in dem Bereich Refactoring und TTD waren. Gut waren auch die interessanten Diskussionen über Entfurf-Stil und auch die Art wie wir die letzte Aufgabe mit dem FtpClient interaktiv gelöst haben.
Eine der Fragen die dabei entstanden ist war ungewöhnlich, aber durchaus interessant - sind Interfaces mit einer einzigen Implementierung YAGNI? Ist es ein Design-Smell wenn man ein Interface extrachiert, welches nur den Overhead mit sich bringt, ohne hinreichenden Nutzen? Diese Frage hat mich in den letzten Tagen beschäftigt, und ich versuche hier die Hintergründe zu beleuchten und meine Rationale darzustellen.
In der frühen Zeit der TDD Geschichte, wo Mocking-Frameworks noch nicht populär waren, hat man manuelles Mocking verwendet. Man hat Kollaborateure mit Hand-gemachten Mocks ersetzt hat und diese in dem zu testenden Objekt injiziert. Dies erfortdert dass der Kollaborator ein Interface implementiert, damit man ihn in dem Test mit einem Fake/Dummy/Stub/Mock transparent für das zu testende Objekt ersetzen kann.
Hat man beispielsweise einen BookingService, die mit Hilfe eines MeetingCalendars eine Konferenz bucht, so hat man beim old-school Mocking ein Interface für MeetingCalendar extrachiert und in dem BookingService gegen das Interface programmiert. In dem Test injiziert man dann einen manuellen Mock.
Heutzutage können Frameworks wie Mockito automatische Mocks on-the-fly generieren. Für Interfaces werden dabei dynamische Proxies generiert, und für konkrete Klassen werden Bytecode-Manipulationen angewendet. Diese neue Tatsache - Mocks für konkrete Klassen - verringert die Notwendigkeit von Interfaces für das Testen. Man braucht sie jetzt nur noch wenn man finale Klassen mocken will, aber abgesehen davon, warum dann noch den Interface Overhead wenn eine einzige Implementierung vorliegt? Ist final wirklich so viel Wert dass es eine zusätzliche Datei, und ein zusätzlicher Typ rechtfertigt?
Nun final ist eine Sache mit Pro und Contra. Gut für Value Objects und bei der Idee einer normalisierten Klassenhierarchie. Gleichzeitig erläutert Feathers aber auch die Schwierigkeiten fürs Testen, die bei excessiver Verwendung entstehen können.
Lassen wir das final also bei Seite. Es gibt aber weitere Situationen, wo ein Interface selbst bei einer einzigen Implementierung sinnvoll sein kann.
Eine solche Stelle ist bei der API eines Moduls. Das sind die wenigen zentralen Abstraktionen, die von Clients verwendet werden, die 10% der Typen, die für Nuntzung nach aussen vorgesehen sind. Wenn z.B. der MeetingCalendar mit einer Outlook-Datenbank kommuniziert, so ist es für den Client einfacher diese externe Verbindung zu isolieren wenn er ein Interface in der Hand hat.
Weiterhin verhilft ein Interface der Testbarkeit wenn die Klasse systemnahen Code ausführt. Schmerzhafte Repräsentanten dafür sind final Klassen aus der Standardbibliothek - ProcessBuilder in Java oder Timer in .NET, die kein Interface haben und damit nicht mit konventionellen Frameworks mockbar sind. Um hier Tests zu verwenden ist man auf selbstgemachte Adapter oder Power-Mocking Frameworks angewiesen, die aber eine Reihe von anderen Problemen mit sich bringen. Aber auch dies könnte man zur Seite legen, wenn man diese Fälle als seltene Ausnahmen betrachtet.
Wo man sich ein Interface nicht so gut ersparen kann ist bei zwei Prinzipien des OO-Entwurfs:
Dependency Inversion Principle. "High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions." -- Die typische Situation ist wenn das Interface in einem Modul liegt und von den Klassen dieses Moduls verwendet wird, aber die Implementierung des Interfaces in ein anderes Modul liegt.
Interface Seggregation Principle. "ISP states that no client should be forced to depend on methods it does not use. ISP splits interfaces which are very large into smaller and more specific ones so that clients will only have to know about the methods that are of interest to them. Such shrunken interfaces are also called role interfaces." -- Die typische Situation ist wenn man zwei Interfaces in einer Klasse implementiert und ein Client das erste Interface verwendet und ein anderer das zweite.
Man kann also nicht pauschal sagen dass Header-Interfaces per se YAGNI sind. Oftmals kann man sie wahrscheinlich weglassen, besonders bei internen Klassen innerhalb eines Moduls. Anders sollte man jedoch auf dem API-Level abwägen. Nichts desto trotz ist das eine gute Einsicht, denn es gibt vielleicht mehr Stellen wo man auf ein Interface verzichten kann wie man sich denkt!
CU,
Rusi
Validating the Object Calisthenics
Im Vortrag habe ich die Regeln von Jeff Bay's "Object Calisthenics" vorgestellt und die Patterns und Prinzipien kurz erläutert. Im Rahmen meiner Studienarbeit "Validating the Object Calisthenics" untersuche ich die Validierbarkeit dieser Regeln mithilfe eines Eclipse Plugins. In der Arbeit werden die hinter den Regeln stehenden Prinzipien erläutert, es wird die Regelvalidierung mithilfe eines Abstrakten Syntaxbaums diskutiert und anschliessend wird die Prototypische Implementierung des Validierers mithilfe eines Eclipse Plugin beschrieben.
Die Studienarbeit wird von mir noch bearbeitet und ich muss in dieser unter anderem eine "Eidesstattliche Erklärung" abgeben. Da das Ende der Studienarbiet erst Ende Mai ist, wurde mir von meiner Hochschule geraten die Validierung der Regeln und die Beschreibung der Prototypischen Implementierung erst nach Abgabe meiner Studienarbeit zu in einem Text (oder Blog online) zu beschreiben. Daher folgt hier mehr, sobald die Arbeit abgegeben ist...
]]>