Unsere erste Kata

Heute berichte ich von unserem ersten innerbetrieblichen Coding Dojo. Teilgenommen haben neben meinem Kollegen Alex aus der Anwendungsentwicklung, auch unser Webentwickler Martin und unser Azubi für Anwendungsentwicklung (erstes Ausbildungsjahr) Waldemar, sowie ich. Vorweg möchte ich noch erwähnen, dass ich es besonders interessant fand, dass unsere Admins anmerkten, dass sie auch einmal gerne an einem Dojo teilnehmen würden. Dem Wunsch werde ich demnächst nachkommen.

Als Programmiersprache wählten wir C# und als Entwicklungsumgebung Visual Studio. Auf Grund der Kenntnisstände teilten wir Alex und Martin, sowie Waldemar und mich in jeweils eine Gruppe, da Martin und Waldemar über keinerlei .NET bzw. C# Erfahrung verfügten. Als erste Kata wählten wir den String Calculator. Wir entwickelten testgetrieben und nutzten dabei MSpec als BDD Framework.

Wir entwickelten am ersten Tag ca. 60 Minuten und setzten uns zur ersten Reflektion danach zusammen. Am nächsten Tag investierten wir nochmals 45 Minuten und verglichen dann die Ergebnisse (unsere Lösung ist am Ende zu finden). Im Anschluss verständigten wir uns auf ein gemeinsames Interface und prüften die eigenen Unit Tests gegen den Code des anderen Teams.

Primär konnte in unserer Gruppe natürlich Waldemar Neues lernen. Dabei ging es mir nicht so sehr ums Coding an sich, sondern um Dinge wie:

  • Wie wichtig saubere und explizite Benennungen sind
  • Wie wichtig es ist selbst bei trivialen Aufgabenstellungen genau nachzufragen
  • Wie wichtig Unit Tests sind
  • Klare Strukturen und Trennungen

Doch auch ich habe wieder etwas gelernt – oder vielmehr mich an etwas erinnert: Nämlich das checked-Schlüsselwort bei arithmetischen Operationen, bei denen es zu einem Pufferüberlauf kommen kann. Außerdem wurde mir bewusst, dass man gar nicht früh genug Azubis an Themen wir Software Architektur, Patterns, Coding Guidelines, etc. heranführen kann. Und – mindestens genauso wichtig – an Produktgespräche mit dem Product Owner. Interessant fand ich es, wie stark die Ergebnisse der Teams voneinander abwichen!

CIMG0733CIMG0734

CIMG0735CIMG0736

Tests:

 1: using System;

 2: using Machine.Specifications;

 3:

 4: namespace Kata1

 5: {

 6:     [Subject(typeof(Calculator))]

 7:     public class Wenn_Uebergabe_eine_leere_Zeichenkette

 8:     {

 9:         Establish context = () =>

 10:         {

 11:             _sut = new Calculator();

 12:         };

 13:

 14:         private Because of = () =>

 15:         {

 16:             _result = _sut.Sum(string.Empty);

 17:         };

 18:

 19:         private It dann_soll_0_zurueckgegeben_werden = () =>

 20:         {

 21:             var expected = 0;

 22:             _result.ShouldEqual(expected);

 23:         };

 24:

 25:         private static Calculator _sut;

 26:         private static int _result;

 27:     }

 28:

 29:     [Subject(typeof (Calculator))]

 30:     public class Wenn_1_uebergeben_wird

 31:     {

 32:         Establish context = () =>

 33:         {

 34:             _sut = new Calculator();

 35:         };

 36:

 37:         private Because of = () =>

 38:         {

 39:             _result = _sut.Sum("1");

 40:         };

 41:

 42:         private It dann_soll_1_berechnet_werden = () => _result.ShouldEqual(1);

 43:

 44:         private static Calculator _sut;

 45:         private static int _result;

 46:     }

 47:

 48:     [Subject(typeof(Calculator))]

 49:     public class Wenn_2_uebergeben_wird

 50:     {

 51:         Establish context = () =>

 52:         {

 53:             _sut = new Calculator();

 54:         };

 55:

 56:         private Because of = () =>

 57:         {

 58:             _result = _sut.Sum("2");

 59:         };

 60:

 61:         private It dann_soll_2_berechnet_werden = () => _result.ShouldEqual(2);

 62:

 63:

 64:         private static Calculator _sut;

 65:         private static int _result;

 66:     }

 67:

 68:

 69:     [Subject(typeof(Calculator))]

 70:     public class Wenn_keine_Zahl_uebergeben_wird

 71:     {

 72:         Establish context = () =>

 73:         {

 74:             _sut = new Calculator();

 75:         };

 76:

 77:         private Because of = () =>

 78:         {

 79:             _result = Catch.Exception(() => _sut.Sum("b"));

 80:         };

 81:

 82:         private It dann_soll_eine_Argument_Exception_geworfenwerden = () => _result.ShouldBeOfType<ArgumentException>();

 83:

 84:

 85:         private static Calculator _sut;

 86:         private static Exception _result;

 87:     }

 88:

 89:     [Subject(typeof(Calculator))]

 90:     public class Wenn_0_uebergeben_wird

 91:     {

 92:         Establish context = () =>

 93:         {

 94:             _sut = new Calculator();

 95:         };

 96:

 97:         private Because of = () =>

 98:         {

 99:             _result = _sut.Sum("0");

 100:         };

 101:

 102:         private It dann_soll_0_zurueckgegeben_werden = () => _result.ShouldEqual(0);

 103:

 104:

 105:         private static Calculator _sut;

 106:         private static int _result;

 107:     }

 108:

 109:     [Subject(typeof(Calculator))]

 110:     public class Wenn_1_und_2_uebergeben_wird

 111:     {

 112:         Establish context = () =>

 113:         {

 114:             _sut = new Calculator();

 115:         };

 116:

 117:         private Because of = () =>

 118:         {

 119:             _result = _sut.Sum("1,2");

 120:         };

 121:

 122:         private It dann_soll_3_zurueckgegeben_werden = () => _result.ShouldEqual(3);

 123:

 124:

 125:         private static Calculator _sut;

 126:         private static int _result;

 127:     }

 128:

 129:     [Subject(typeof(Calculator))]

 130:     public class Wenn_1_und_2_und_3_uebergeben_wird

 131:     {

 132:         Establish context = () =>

 133:         {

 134:             _sut = new Calculator();

 135:         };

 136:

 137:         private Because of = () =>

 138:         {

 139:             _result = _sut.Sum("1,2,3");

 140:         };

 141:

 142:         private It dann_soll_3_zurueckgegeben_werden = () => _result.ShouldEqual(6);

 143:

 144:

 145:         private static Calculator _sut;

 146:         private static int _result;

 147:     }

 148:

 149:     [Subject(typeof(Calculator))]

 150:     public class Wenn_1_und_a_uebergeben_wird

 151:     {

 152:         Establish context = () =>

 153:         {

 154:             _sut = new Calculator();

 155:         };

 156:

 157:         private Because of = () =>

 158:         {

 159:             _result = Catch.Exception(() => _sut.Sum("1,a"));

 160:         };

 161:

 162:         private It dann_soll_eine_Argument_Exception_geworfenwerden = () => _result.ShouldBeOfType<ArgumentException>();

 163:

 164:

 165:         private static Calculator _sut;

 166:         private static Exception _result;

 167:     }

 168:

 169:

 170:     [Subject(typeof(Calculator))]

 171:     public class Wenn_eine_zu_große_Zahl_uebergeben_wird

 172:     {

 173:         Establish context = () =>

 174:         {

 175:             _sut = new Calculator();

 176:         };

 177:

 178:         private Because of = () =>

 179:         {

 180:             _result = Catch.Exception(() => _sut.Sum(int.MaxValue + ",1"));

 181:         };

 182:

 183:         private It dann_soll_eine_OverflowException_geworfen_werden = () => _result.ShouldBeOfType<OverflowException>();

 184:

 185:

 186:         private static Calculator _sut;

 187:         private static Exception _result;

 188:     }

 189: }

Implementierung:

 1: using System;

 2:

 3: namespace Kata1

 4: {

 5:     internal class Calculator : ICalculator

 6:     {

 7:         public int Sum(string input)

 8:         {

 9:             if (String.IsNullOrWhiteSpace(input))

 10:                 return 0;

 11:

 12:             var inputs = input.Split(new[] { ',' });

 13:             int sum = 0;

 14:

 15:             foreach (var summand in inputs)

 16:             {

 17:                 int convertedNumber;

 18:

 19:                 var conversionSuccessfull = Int32.TryParse(summand, out convertedNumber);

 20:

 21:                 if (!conversionSuccessfull)

 22:                     throw new ArgumentException();

 23:

 24:                 try

 25:                 {

 26:                     sum = checked(sum + convertedNumber);

 27:                 }

 28:                 catch (OverflowException ex)

 29:                 {

 30:                     throw;

 31:                 }

 32:             }

 33:

 34:             return sum;

 35:         }

 36:     }

 37: }

Da freut sich das Entwicklerherz – alles grün!

image

– Verfasser: Uli Armbruster

Advertisements

Über hecogmbh

Die heco gmbh ist ein Handelshaus sowie ein Produzent für Fittings und Armaturen aus rostfreiem Edelstahl. Unsere Produkte werden im Maschinen-, Anlagen- und Fahrzeugbau sowohl in der chemischen Industrie als auch in der Nahrungsmittelindustrie eingesetzt. Mit mehreren Standorten europaweit sind wir immer in Ihrer Nähe.
Dieser Beitrag wurde unter Uli Armbruster abgelegt und mit , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Eine Antwort zu Unsere erste Kata

  1. Pingback: Coding Dojo in Karlsruhe | Die heco IT

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s