Mittwoch, 25. Juli 2007

Wann sollte man "Nein" sagen? - Teil II

Sie haben ein scrum Projekt, bei dem ein Team firmenübergreifend zusammenarbeitet, weil der Kunde da so wünsch?

Der Kunde A möchte, dass Sie als IT Dienstleister B mit der internen IT von A zusammenarbeitet, um ein gemeinsames Projekt zum Erfolg zu bringen...

Sie haben das Gefühl, der Partner im Projekt spricht nicht die gleiche Sprache, komplett andere Vorgehensweise hat, eigentlich nicht mit Ihnen zusammenarbeiten möchte , künstliche Hürden aufbaut, bla, bla, bla

"The team will make or break the project"

Sagen Sie "Nein"

Wann sollte man "Nein" sagen? - Teil 1

Aus gegebenem Anlass schnell ein gutes Argument, wenn man vor der Entscheidung steht, einem agilen Projekt zu- oder abzusagen:

" Good trial lawyers don't take bad cases"

Akutell arbeite ich gerade an einem agilen Projekt mit einem Partner-Unternehmen, wo man ausdrücklich agile arbeiten möchte - die Knwo-how-, Methodik und Erfahrungsunterschiede aber so gross sind, dass man besser "Nein" sagt ...

10 Gründe, warum agile Projekte schief gehen

Wenn ein agiles Softwarentwicklungsprojekt schief geht, ist in erster Line immer die Methode schuld, nicht die Personen, die die agile Methode eingeführt bzw. umgesetzt haben. Oft eine falsche Annahme. 10 Gründe, warum agile Projekte scheitern:

#10 Gerüchten glauben, z.B.
  • agile ist besonders gut für kleine Projekte
  • totale Kostenkontrolle
  • Dokumentation ist nicht notwendig
  • agile Vorgehensweise braucht keine Analysten und Tester
  • "jeder" kann "alles" Grundsatz
  • wir machen Scrum, wir sind agile!
#9 Widersprüchliche Terminologie

Wir sagen - der Kunde versteht/interpretiert:
  • extreme - riskant
  • agile - ungenau, unbestimmt, locker
  • pair programming - doppelte Kosten
  • refactor - unnötiger Code
  • unit testing - extra Code
Wenn man es nicht erwähnt, hat man es nicht gehört - jetzt ist man agile!

# 8 Keine Schlüsselfiguren

man fokussiert auf die Entwicklung von Features, ABER es braucht einen
  • Sprint Manger
  • (Business) Analysten
  • Tester
  • Designer
  • WAI Experten
#7 Übertreibung

Beispiele:
  • Sicherstellen, das Dokumente für jemanden bestimmt sind
  • Sicherstellen, dass jede Implementierung ein Problem löst
  • Alles weglassen, was keinen Business-Value hat
  • Kein Micromanagement
  • Keine Statusdiagramme oder ähnliches
#6 Spitzfindigkeiten
  • Man braucht ne Menge Erfahrung
  • Entscheidungsträger sind nur involvierte Personen
  • "Nach Lehrbuch" Vorgehensweise
  • Alles mindestens 3 Interationen ausprobieren
  • Jede Änderung min. 3 Interationen verifizieren
  • Keine Angst, Änderungen rückgängig zu machen
#5 Mangelnde Disziplin & Schleifen lassen
  • Angst Dinge zu ändern oder Änderungen einzufordern
  • Tun und Handeln wird unterschieden - ist man wirklich agile?
  • Rituale vernachlässigen
#4 Nicht das richtige Team
  • es braucht erfahrene Führungspersonen
  • es braucht ein erfahrenes Team
  • es braucht erfahrene Mentoren für jede Rolle
  • man braucht mehr als einen "Plan"
  • Externe Epertentips einholen - und zuhören!
#3 Zu lange Interationen
  • nicht länger als 2 Wochen
  • klarer Rythmus ist erwünscht -> Dienstag -> Dienstag
  • Schneller Teams sollten kürzere Zyklen haben
  • Keine Zeit verliehren
#2 Kein guter "Sponsor"
  • der Kunde muss zum agilen Prozess passen
  • man braucht jemanden, der genug politischen Einfluss ausüben kann, um agile ein Chance zu geben
  • Überzeugung und Begeisterung für agile schaffen
  • Aus Fehlern lernen
#1 Dem Team keine Erholen lassen
  • das Team gewinnt oder verliehrt das Projekt
  • die Führungsperson ist ein wunder Punkt
  • die Umgebung/Arbeitsumfeld ist ein wunder Punkt
  • die (externe) Unterstütztung ist ein wunder Punkt
  • Personalfluktion ist ein wunder Punkt

Montag, 2. Juli 2007

Stub vs. Mock

In einem anderen Post habe ich die vier Test Doubles beschrieben und deren Verwendung abgegrenzt. Da Mocks und Stubs immer wieder verwechselt werden, hier ein Beispiel, um deren unterschiedliche Verwendung aufzuzeigen:

Nehmen wir an, es gibt eine Funktion um das Password zu ändern. Wenn man diese aufruft, soll automatisch ein re-login mit den neuen Credentials durchgeführt werden.


public interface LoginService {
   public boolean login (String login, String password);
}


public class LoginServiceStub implements LoginService {
   private Map currentSessions = new HashMap();
   public boolean login (String login, String password) {
      currentSessions.put(login, password);
      return true;
   }
   public int numberOfCurrentSessions() {
      return currentSessions.size();
   }
}


Beim ChangePassword kann man wie folgt testen, ob login aufgerufen wird (state verification):

class ChangePasswordStateTester...
   public void testReLoginAfterPasswordChanged() {
      LoginService loginService = new LoginServiceStub();
      ChangePasswordService systemUnderTest = new ChangePasswordServiceImpl(loginService);
      systemUnderTest.changePassword("accountId", "oldPassword", "newPassword");
      assertEquals(1, loginService.numberOfCurrentSessions());
   }


Der Mock Test dazu sieht folgendermassen aus:

class ChangePasswordInteractionTester...
   public void testReLoginAfterPasswordChanged() {
      Mock loginService = mock(LoginService.class);
      ChangePasswordService systemUnderTest = new ChangePasswordServiceImpl(
         (LoginService) loginService.proxy());

      loginService.expects(once()).method("login")
         .withAnyArguments()
         .will(returnValue(true));

      systemUnderTest.changePassword("accountId",
         "oldPassword", "newPassword");
   }
}


Bei beiden Beispielen wurden Test Doubles verwendet, nicht der "echte" Login Service, wobei der Stub ein state verfication und der Mock eine behaviour verfication durchführt.

Man muss sich bewusst sein, dass man bei Stubs in aller Regel zusätzliche Methoden hinzufügen muss, um den Status zu prüfen. Das bedeutet, dass die Code Basis wächst und dieser Code wird zunehmens anfälliger und muss gewartet werden. Nicht zuletzt eine Frage der Kosten.

Sonntag, 1. Juli 2007

Was sind Test Doubles?

Oft fällt im Zusammenhang mit agiler Software Entwicklung der Begriff Test Driven Development (TDD). Möchte man TDD einsetzten, sollte man wissen, was mit Test Doubles gemeint ist. Dieser Term wird immer wieder in der Literatur im Zusammenhang mit TDD verwendet.

Als Test Doubles bezeichnet man bestimmte Objekte, die beim Testen einen Systems eingesetzt werden, um Zustand und Verhalten zu verfizieren. Es gibt vier unterschiedliche Typen, die jeweils für ein anderes Bedürfniss beim Testen verwendet werden:


Dummy
Ein Dummy Objekt wird nur durch das Sytem gereicht und niemals wirklich verwendet. Dummies werden oft nur zum Füllen von Parameterlisten verwendet.

Fake
Ein Fake Objekt hat eine echte, funktionierende Implementierung, die aber meistens ein abgekürztes Verfahren darstellt. Eine in-memory-database ist ein gutes Beispiel dafür.

Stub
Ein Stub gibt vorgespeicherte Antworten bei Aufrufen während eine Testlaufs, die in keinem Zusammenhang mit dem geschriebenen Test und damit mit dem Caller stehen. Stubs können zusätzlich Informationen über den Aufruf aufzeichnen, z.B. ein Email Gateway, wie viele Emails er verschickt hat und was deren Inhalt war.

Mock
Mock Objekte haben einen definierten Satz von vorprogrammierten Erwartungen (expectations) über die genaue Abfolge von Aufrufen, die erwartet werden, wenn das Mock Objekt verwendet wird.

Wichtig!
Nur Mocks dienem dem Testen von Verhalten (behaviour verfication) eines "System Under Test" (SUT). Alle anderen können nur beim Testen von Zuständen (state verification) verwendet werden.

Ich werde später noch genauer auf Mocks und Stubs eingehen und ein Beipspiel zeigen, da Mocks und Stubs immer wieder verwechselt werden.

Samstag, 30. Juni 2007

Agile Softwareentwicklung auf Platz 18 bei Business 2.0 Umfrage von CNN

Zweimal jährlich macht CNN bei der Business 2.0 Initiative ein Umfrage zu Persönlichkeiten, neuen Ideen, Trends und Produkten, die die Geschäftswelt beinflussen und verändern.

Agile Softwareentwicklung als "neuer" Ansatz für web-basiertes Softwareentwicklung belegt Platz 18!

CNNMoney.com

Donnerstag, 28. Juni 2007

TheServerSide: Test Driven Development

Bei TDD, oder auch Test Driven Development genannt, geht es nicht primär ums Testen, sondern es geht um gute Programmierung! Genauer, wie schreibt man Code, der sich testen lässt.

Es gibt da mehrere Ansätze, ein Beispiel-Dependency Injection:

Schlecht!

public class MyServiceImpl implements ServiceInterface {
   private final TheOtherService theOtherService;
   public MyService() {
      this.theOtherService = new TheOtherServiceImpl();
   }

   public int doIt(String a) {
      return this.theOtherService.doSomething(a);
   }
   ...
}

Besser!

public class MyServiceImpl implements ServiceInterface {
   private final TheOtherService theOtherService;
   public MyService(TheOtherService theOtherService) {
      this.theOtherService = theOtherService;
   }
   ...
}

Nur um dass nochmal deutlich klarzustellen: TheOtherService ist ein Interface! Die eigentliche Implementierung wird durch den Konfigrationskontext "incjected", z.B. Spring der JUnit in Verbindung mit JMock.

Warum? loose coupling! Im zweiten Beipiel kann man zum Bespiel ein Mock Object per Dependency Injection im Unit Test übergeben und prüfen, ob und wie Methoden von der injected Klasse aufgerufen werden. So kann sichergestellt werden, dass die Implementierung von ServiceInterface den(die) Aufrufe von einem Dao, einer Message Queue, einem SOA Endpoint etc. durchführt.

Unit Test:

public class MyServiceTestCase extends MockObjectTestCase {
   public void testSomething() {
      Mock mock = new Mock(TheOtherService.class);
      ...
      ServiceInterface objectUnderTest = new MyServiceImpl(mock );
      objectUnderTest.doIt("foo.bar");
      mock.expects(once()).method("doSomething").with(eq(a))
         .will(returnValue(result1));
      ...
      }
      ...
}

Grundsätzlich gilt bei TDD der "red-green-refactor-mantra".Erst schreibt man einen Test, der wird zunächst mal failen (red). Dann schreibt man die Implementierung und lässt den Test erneut laufen. Jetzt sollte er passen (green). Bei jedem folgendem Refactoring sollten die Tests ohne Modifikation immer "green" sein!

Ein ständiger red-green-red-green Lifecylce ist nicht die Idee!

TheServerSide: WIFI ist teuer und funktioniert nicht!

Der System Engineer ist sichtlich überrascht, als ich mit meiner Maschine vor ihm stehe und er einen Blick auf die Meldung "Es besteht ein IP Adressenkonflikt mit einem anderen System im Netzwerk" wirft. Er erklärt mir auch noch nett und freundlich, dass es 2 DHCP Server gebe und er nun in den Keller geht, um einen davon zu re-booten. Ich soll dann in ein paar Minuten noch mal einen Versuch starten....

Das war von ca. 1.5 Stunden - nothing happend! Es hat sich rumgesprochen und es gibt noch ein paar andere Kursteilnehmen mit ähnlichen Leiden ...Ok, wer führt nach die Verhandlungen über ein "Geld-Zurück" Deal, denn WIFI ist ja teuer ...

Mittwoch, 27. Juni 2007

TheServerSide: Agile Software Development in the Large

Jutta Eckstein (www.jeckstein.com) berichtet zunächst über die Geschichte der agilen Software Enwicklung, geht aufs agile Manifest ein, schildert das agile Wertesystem und deren Prinzipien.

Wie sieht jetzt aber Software Development in grossen Projekten aus (Gross heisst hier mehr als 12 Members)?

Neben dem allgemeinenen Erläuterungen zum agilen Vorgehen im Allgemeinen habe ich folgende Punkte herausgenommen, die neu für mich sind:

1. Feature-Teams
Wenn mehrere Teams an einem Feature arbeiten, z.B. Datenbank Team, Business Analyst Team und Sofware Developer Team, so ist es wichtig, dass jedes Team einen Teil der Verantwortung für ein Feature übernimmt. Wenn nicht, kommt es leicht zu Situationen, wo ein Team am Ende argumentiert:
"Ja, wir waren ja fertig, aber die anderen nicht, weil ...".
Um das zu vermeiden gibt es pro Feature aus jedem Team einen Verantwortlichen - in der Summe dann das Feature Team.

2. Done-Done
Bei einem Multi-Team Projekt kommt es schnell vor, das ein Team ein Feature auf Done setzt, teamübergreifend das aber nicht der Fall ist. Dafür verwendet man einen neuen Zustand für ein Feature: Done-Done, was soviel bedeutet, wie dass ein Feature vom Feature Team auf Done gesetzt wurde und definitiv done ist.

3. Resourcen-Sharing
Um die Kommunikation zu beschleunigen werden die Resourcen der Teams in einem rotierendem Modus ausgetauscht. Damit sind alle Team Members auch teamübergreifend immer syncronisiert.

4. Communication faciliator
Um sicherzustellen, das alle Informationen fliessen und das gesamte Team fokussiert an den Kundenwünsch arbeitet, sollte ein Chief Architect eingesetzt werden. Er ist zentrale Anlaufstelle für neue Ideen, technische Fragen und für generelle Problemstellungen.

5. Common Development Culture
Es ist wichtig, dass es eine gemeinsame "Entwicklungs-Kultur" gibt. Dazu zählen Code-Guidelines, Code Reviews, extreme Programming, Unit Testing und so weiter. Um das gesamte Team auf dem laufenden zu halten bietet sich eine Projektplattform an, z.B. ein Wiki.

6. Staged Retrospective
Jedes Team macht ein eigenes Review Meeting und bringt die Top 3 Verbesserungsvorschläge bei einem Gesamt-Review-Meeting ein, bei dem von jedem Team nur eine Delegation gesandt anwesend ist.

Ok, hat jemand damit schon Erfahrungen gesammelt? Ich persönlich habe bisher nur in Teams < 8 Mitgliedern gearbeitet.

TheServerSide: Language-oriented Programming - DSL

Das TheServerSide Java Symposium, Barcelona hat soeben begonnen und er der erste Slot zum Thema 'Language-oriented Programming' wurde von Martin Fowler und Neal Ford gehalten (ThoughtWorks).

DSL - Domain Specific Language, das zentrale Thema in diesem Vortrag. Was ist DSL? DSL kann man am Beispiel einer menschlichen Sprache gut beschreiben. Wir verwenden Vokabeln, quasi API's. Vokabeln werden durch eine Grammatik, der Domain Specific Language, mit einer Semantik versehen. Je nach Sprache und Inhalt ergibt sich die Semantik.

DSL vs. API

Bei Domain Specific Language gibt es einen impliziten Kontext, beim API nicht, der muss explizit gemacht werden.
Bespiel: Kaffebestelllung bei Starbucks (DSL): "Ein Kaffe bitte, gross, mit Milch, kein Zucker, wenig Fett, zum Mitnehmen".
Beim API würde das in etwa so aussehen (Java API):

Coffee starbucksCoffee = new Coffee();
starbucksCoffee.setSize(Size.HUGE);
starbucksCoffee.setFatness(Fat.LOW);
starbucksCoffee.setSweetness(false);
etc.

Grundsätzlch unterscheidet man interne/embedded und externe DSL. JMock ist eine interne DSL (auch Fluent Interface genannt), externe DSL sind meistens XML basierte Beschreibungen und Konfigurationen, z.B. eine Konfiguration des Apache Webservers.

Warum DSL?

Ziel ist es, dass ein Business Analyst den Code lesen kann, um diesen zu verifizieren.

TheServerSide: WIFI ist teuer

Angekommen im Princesa Sofia Conference Hotel stellt sich natürlich die Frage, wie kommt man ins Internet? Hm, wohl nicht so ganz naheliegend, denn die Service Crew
ist sichtlich überrascht über mein Anliegen ;-)

Man bekommt einen WIFI Gutschein, einzulösen bei der Reception gegen eine kleine Gebühr von 45 Euro + 7% Steuer ...
Mal schnell rechnen: ca. 300 Teilnehmer à 45 Euro macht schlappe 13.500 Euro - da sind ja die Auslagen für die Veranstaltung schon fast refinanziert....

Montag, 25. Juni 2007

Scrum trifft RUP


RUP - Rational Unified Process®

RUP ist ein strukturiertes Vorgehens- modell, Scrum ein agiles Vorgehens- modell - lässt sich das miteinander vereinbaren, kann man RUP "agilisieren"?

Joe Krebs, Senior IT Specialist , IBM Rational, schreibt in einem Artikel "RUP in the dialogue with Scrum" über RUP, Scrum, die wesentlichen unterschiede und wie man RUP mit agilem Ansatz erweitern kann.