torsdag 17 december 2009

"The pit of despair"

Nyligen har vi i vårt team gjort en ansats till att göra mera unit tests. Det är en grym känsla när vi alla verkar få samma "tända glödlampa" över våra huvuden, när insikten om att det här är vad vi borde göra slår oss alla samtidigt. Att vara överrens underlättar ju helt klart.

Men vägen till ett bättre och förändrat arbetssätt är motig. Jag har flera gånger den senaste tiden varit på god väg att ta en liten genväg för att slippa ta den jobbiga vägen över unit tests. Jag vet ju självklart innerst inne att vi inte kan fortsätta koda på utan tester, alla de buggar jag kämpat med är ju ett bevis på att något måste bli bättre. Men ändå kryper den gamla vanan fram ibland och man kommer på sig själv att argumentera för att försvara sitt tillfälliga undantag. "Ja men den HÄR grejen kan jag ju inte testa... den är ju trivial och dessutom svinjobbig att testa!"

Som tur är finns det fler än jag i teamet. Hade det bara varit jag hade min monolog enkelt kunnat låtit logisk och ja själv hade säkert accepterat ursäkten för att tillfälligt undvika från planen. Tillfällena hade nog blivit fler... och ännu fler. Till slut sitter man där igen, inte ett dugg bättre och med samma gamla buggar som välkomnar en på morgonen. Men har man människor runt sig som ifrågasätter undantaget (ja ibland räcker det med en tveksam blick för att fånga samvetet...) så blir det inte så.

Nä, det är bara att bita ihop! Under Dan Norths föreläsning på Öredev pratade han om "the Satir Change Model". Den beskriver ungefär hur vi hanterar förändring och hur vi tar oss vidare. Det är en stegvis process.
Steven Smith beskriver den bra i sin blog.


I stort går det ut på att vi befinner oss i ett nuläge, trygga i det vi kan, det vi är vana vid och vårt beteende, även om det är ett destruktivt beteende. En förändring introduceras och genast föds ett motstånd mot det nya där vi, medvetet eller omedvetet, motarbetar förändringen. Nästa steg är KAOS. I botten av detta kaos finns "the pit of despair". Nu är vi på botten och har svårt att se hur vi ska kunna ro iland förändringen.

Men - låter vi oss komma förbi denna grop väntar integrering och nya insikter, när vi ser hur det nya faktiskt hjälper oss i vårt arbete. Och fullföljer vi integreringen väntar ett nytt nuläge där vi förbättrat oss och vant oss vid nya, mindre destruktiva beteenden.

Tänker jag efter känner jag klart igen mitt eget beteende. Fastän jag var fullt delaktig i initiativet till förändringen har jag gjort motstånd med mina lama ursäkter om att slippa undan. Just nu befinner vårt team sig i gropen och med sprattlande armar försöker vi gräva oss upp. Men att bara inse att det är där vi är hoppas jag är ett bra tecken.

Det är dags att släppa motståndet och låta kaoset styra ett tag.
Snart är vi på väg upp igen. Åtminstone lagom till nästa förändring...

Over and out!

Dagens kodarmusik: Ingen musik, utan lite Hanselminutes med Roy Osherove om Unit Testing.

söndag 13 december 2009

Dags att spela i samma lag!

Min uppfattning om vårt yrke, systemutvecklare, har alltid varit att vi gör mer än att knacka kod. Vi gör mer än att designa mjukvaruarkitekturer. Vi löser behov. Vi utvecklar verksamheten tillsammans med de som arbetar i och med den. Utan dem skulle det inte finnas någon verksamhet, inga behov och inget berättigande för vårt yrkes existens. Tyvärr upplever jag att vi ganska sällan kommer till vår fulla rätt.

Den "färdiga" lösningen på ett fat
Allt för ofta kommer en färdig lösning till oss från användare eller ledning. Det innebär att någon annan än vi har tänkt ut vilket systemstöd som ska finnas och när det måste vara klart. Vi kommer in allt för sent i processen när viktiga beslut redan är fattade som på många sätt inskränker i vår möjlighet att utöva det vi är bäst på - att utveckla IT-stöd. Om vi redan tidigt fanns med i processen kunde vi bättre förstå skäl och bakgrund till det man vill åstadkomma och kanske finna bättre vägar eller ännu bättre lösningar. Men när man får en färdig lösning finns det oftast varken tid eller mandat för att gå tillbaka och riva upp beslut eftersom någon annan ju redan "vet" att det är den enda och bästa vägen. Sen sitter man som utvecklare och knackar ihop något man egentligen inte tror på.

Två månader på IT-kammaren och sen är det klart
Ett annat vanligt scenario är att vi IT-människor får allt för fria händer. Vi tolkar lite tunna uppgifter vi fått för att sedan stänga in oss och designa en lösning som ur vårt perspektiv verkar klockren. Tyvärr slutar det ju ofta med väldigt komplicerade funktioner som användarna inte förstår eller tycker fungerar i deras vardag. De vet inte vad de ville ha, men det som levererades var inte rätt. Lösningen har fått för stort IT-fokus. Fundera en stund över den där dialogen du designade med lite väl "data-nära" termer här och var...

Det här är två ytterligheter, men de pekar båda på samma område där vi allt för ofta brister - samarbete.

Vi måste på ett bättre sätt lyckas använda varandra. De har kunskap om verksamheten och lever i den varje dag. De är beroende av det vi levererar och måste leva med det, varje dag. Vi har kunskap om hur man gör bra IT-stöd, hur man kan samverka med befintliga lösningar och vilka tekniker som är aktuella idag. Var för sig kommer vi till korta, men tillsammans har vi ju en rätt bra laguppställning. Vi täcker ju in alla väsentliga områden! Vore det då inte bättre om vi blev lite mindre DE och lite mera VI?

VI jobbar gemensamt eftersom vi har ett gemensamt mål, en verksamhet som fungerar bra och presterar på topp. Genom att utnyttja våra olika kompetenser och roller på bästa sätt kan vi få mycket bättre effekt och undvika feltolkningar. VI är större än meningslösa motstridigheter, vi bryr oss om vårt gemensamma arbete och vårt gemensamma resultat. Det spelar ingen roll vem eller vad som är skälet till att något inte fungerar eller brister, vi har ett gemensamt ansvar för att få det att fungera.

Det här är några punkter jag tänker arbeta mer för framöver:
  • I varje verksamhetsprojekt få med kunskap om IT och möjliga lösningar tidigt
  • Upprätta en bra dialog tidigt, lyssna - vad är behovet egentligen?
  • Leverera små, körbara, delar av vår lösning regelbundet som vi kan prova gemensamt - på riktigt!
  • Aldrig mer säga "ok, då fattar vi" och försvinna in på kammaren och tok-koda i 3 månader
  • Aldrig mer säga "ja den lösningen blev ju sådär, men det var ju de på X fel, så det är inte mitt problem"
Vi är ett och samma lag. Vi har ett och samma mål.
Så vad är problemet?

Over and out!

Dagens kodarmusik: Europe - New love in town

måndag 7 december 2009

Unit testing success story!

Jag var bara tvungen att skriva en liten glädjepost om mitt första riktiga äventyr med unit testing.
Jag har under de senaste dagarna lagt till några nya funktioner i en grafisk kontroll. Den består i stort av en datagridview med ett antal rader och kolumner. Vissa rader är summor av ovanstående rader, vissa kolumner är summa av radens värden. Alltså, det finns lite relationer raderna och kolumnerna emellan.
I samband med att jag gjorde de nya funktionerna skrev jag i princip om hela kontrollen och dess affärslogik för att göra den mera testbar. Det verkade som en liten lagom prototyp. Och det var det.

För att bara beskriva läget före min unit testing refactoring, såg det ut ungefär så här:

  • Inga unit tests
  • Grafisk kontroll: Specialhantering för alla typer av rader och kolumner, kontroll mot konstanter och vissa magic numbers. Mycket kontroll av inmatade värden och omvandling från string till int.
  • Coordinator: Specialhantering av samma konstanter, 150 rader kod. 
  • Affärsobjekt: Ärvda versioner av riktiga affärsobjekt för att kunna blanda affärsobjekt med rena summeringsrader och kolumner. Konstanter och magiska siffror lite här och där.
  • Acceptanstest: Starta applikationen. Prova funktion 1, funkade inte. Ändra lite. Prova igen. Prova funktion 2, funkar! Prova den tredje funktionen, funkade inte. Ändra. Funkar! Prova lite till. Nu funkar inte funktion 1. Osv osv. Nervöst inför releasen... Buggfix redan första dagen.

Och så efter...

  • 40 unit tests, all green!
  • Grafisk kontroll: Bara hantering av hur cellerna ska se ut, hur de formatteras mm. Hämta värde och skriva värde till och från affärsobjekten sker med en enda enkel metod. 
  • Coordinator: En konstruktor och två properties. Det är allt.
  • Affärsobjekt: GUI wrappers som ibland håller referenser till affärsobjekt, ibland inte. Hel uppsatta för att på bästa sätt stödja GUI programmeringen. Och helt testbara!
  • Acceptanstest: Allt funkar med en gång! Iallafall ser det ut så...
  • Känns grymt bra inför releasen!
Med andra ord, att skriva unit tests för min lilla funktionsändring gjorde inte bara att jag fick mer förtroende att den fungerar. Det gjorde också lösningen betydligt bättre eftersom en testbar arkitektur helt enkelt är en bra arkitektur. Testbarhet motverkar nämligen "fix-och-trix-lösningar" som jag lätt faller tillbaka till. Tyngdpunkten på funktionerna ligger i affärslogiken. GUI:t hanterar bara grafisk representation.

Sen kan man säga vad man vill om att jag kanske även utan unit tests borde sett att lösningen... ja...sög.
Men det är skit samma nu. Med hjälp av en unit testing utflykt och genom att tänka på testbarheten blev det en självklarhet även för mig.

Att inte skriva unit tests i fortsättningen känns otänkbart. Nu är de här för att stanna, för den känsla jag nu har inför det jag presterat och inför en stundande release är något jag vill vänja mig vid.


Ett litet citat på vägen, som inte alls har med ämnet att göra, men som var så bra. Andy Hunt sa i sitt keynote på Öredev 2007 på temat "Accidental Complexity", dvs saker som är komplext utan att det egentligen finns skäl till det:
XML is like kids. They start of small and cute. Then they grow.

Over and out!

Dagens kodarmusik: Riva - Time is the healer (Armin van Buuren remix)

söndag 6 december 2009

En nybörjares syn på unit testing

EN sådär 10 år efter branschen är jag igång med lite unit testing. I den nya funktion jag nu ska implementera har jag försökt göra så kompletta unit tests som möjligt. Det är inte lätt.
Så här långt in i kampen har jag kommit fram till ett par saker:

Använd mocks - på rätt sätt
En Mock är ett fake-objekt, som man använder istället för den verkliga implementationen. Man ersätter då alla anrop på en verklig klass med anrop på en mock. Du kan då i testet styra vad din mock ska svara på anrop och på det viset skapa en känd omvärld för ditt test. Generellt sett har jag haft mest användning av mock objekt när det gäller de olika skiktens ställföreträdare och inte så mycket när det gäller affärsobjekt. Till exempel är det lättare att göra en fake implementation av en "ProduktManager", som innehåller funktioner för att hämta och spara produkter än för själva klassen "Produkt" i sig.

Men här märker man direkt om arkitekturen är testvänlig eller inte (läs: bra eller inte...). Om det inte är möjligt att byta ut sina "managers" mot andra implementationer är det svårt att använda mocks. Men om alla användare av managern använder ett interface är det enklare. Om man dessutom använder en instance factory eller en IOC containter (här är jag dock på tunn is) gör det hela lösningen ännu mer testbar.

Sen försöker jag dra gränsen för både mocks och omfattningen av test vid ett skikt. Det innebär att man testar ett skikt i taget och det enda som man "mockar" är skiktet under det skikt man just nu testar. (Phew, hur blev det där egentligen?).




Så, för att förklara:
Om jag ska skriva ett test för en coordinator, kommer jag att ge den en eller flera mocks för de managers den använder. På det sättet ger jag den klass jag använder givna förutsättningar. Inget konstigt så långt. Där drar jag gränsen för testet. Repository skikten är aldrig inblandat i testet. Inte heller GUI. Det gör testet mindre, mer fokuserat och enklare att skriva.

Behovet av att använda mocks för andra objekt, som entiteter har jag ännu inte riktigt utrett. Det jag har märkt är att det kan hjälp att skapa enkla metoder för att fylla på de riktiga affärsobjekten med testdata. Men jag använder då i vilket fall det riktiga affärsobjektet. Men vem vet, kanske din hjälpfunktion är en indikation på att du behöver den även i produktionskoden?

Ett sätt att bemästra GUI tester... lite
Hur man testar GUI är ett problem för mig. Men jag har hittat en utväg. Gör GUI:t dummare.

Med en coordinator (som i vårt fall är den GUI pratar med) som levererar så färdig information som möjligt kan man lägga mer kod i den mycket mer testbara coordinatorn. Att tänka på vad som är enklast att hantera för ett GUI, och bygga coordinatorn efter det, gör skillnad.

Funktioner som exempelvis tar in strängvärden kan man evaluera om värdet var giltig integer eller ej i coordinatorn. Sen får GUI:t hantera det som den vill, men problemet kommer inte sprida sig vidare eftersom vi med tester i coordinatorn sett till att alla felaktiga värden hanteras korrekt.

Ett annat bra sätt är att helt ta bort null-problematiken för GUI:t. Låt aldrig coordinatorn returnera null, utan istället en tom lista, tom sträng etc. Kanske är det till och med så att vi borde skapa VårKlass.Empty för att alltid ge tillbaka något. Hur många NullReference problem har man inte fått...

Vid databindning i en DataGridView, använd antingen CellValueNeeded och CellValuePushed som pekar på GetValue(...) i coordinatorn och SetValue(...) i coordinatorn. Eller, vilket oftast är ännu bättre, skapa tillrättalagda, testbara GUI objekt com är gjorda för databindning.

Kontentan är att GUI:t ska vara så dumt som möjligt! Då slipper vi komma på obskyra sätt att testa det med unit tests. Då kan GUI:t testas manuellt utifrån användbarhet och inte för att hitta buggar med vad jag ibland kallar för "Happy testing". Klicka här, klicka där... klicka lite här.... Ja du vet vad jag pratar om.

Håll testerna rena och tydliga
När TDD förespråkarna gav oss utvecklare fribrev vad gäller dokumentation hurrade nog inte bara jag. "Jag skriver kod istället för dokumentation - grymt!". Men då gäller det ju att testerna går att läsa som dokumentation. Här har jag hittat ett par bra tips
  • Låt testerna få tydliga namn, hur långa som helst bara de är tydliga
  • Uttryck testerna som ett krav eller påstående, som SökningPåOkändProduktGerTomLista eller IckeNumerisktVärdeFörAntalPåverkarInteDataOchKastarInteException.
  • Undvik onödiga Asserts i testet. Om du har gjort en assert i ett testfall, gör inte om den i ett annat. Till exempel, du har en funktion som alltid ska returnera resultat och inte null. Säkerställ detta i testet HämtaProdukterReturnerarAlltidEttVärde. I alla andra tester förutsätter man sedan att så är fallet. Inga if != null, inga Assert.IsNotNull, såvida det inte gäller något specifikt för just det nya testet.
  • Skapa hjälpfunktioner i din klass som gör komplexa eller otydliga operationer.
    Jag råkade ut föra att jag i många tester behövde hämta ut ett objekt från en IEnumerable med hjälp av LINQ. Koden blev rätt hårig och var egentligen inte del av testet. Istället för att skapa massa komplex kod i mitt test la jag ut den koden i en hjälpfunktion med enkelt namn. Då ser testet snyggare ut och blir enklare att förstå. Dessutom är det ju inte fel att lägga ett test på hjälpfunktionen också, en gång för alla så att inte heller resultat från den behöver ifrågasättas.
  • Använd alltid möjligheten till att skriva en kommentar till din Assert, alltså en sista inparametern till Assert, inte som en kommentar i koden.
  • Skriv aldrig kommentarer i testkoden. Den ska inte behöva kommenteras.
  • Ta utan att blinka bort tester som heter TestMethod1 eller TestaProdukt mm. Vad gör du när ett sånt test fallerar? Nä, dåligt namngivna tester är faktiskt sämre än inga tester, iallafall ur dokumentationssynpunkt.
  • Låt dina Asserts återspegla vad testet heter, dvs det ska var tydligt att din Assert testar just det som namnet på ditt test säger
  • Klappa dig själv på axeln om du gör ett test med bara EN assert i. Bra gjort!
Med andra ord - ställ samma krav på testkoden, eller högre(!), som på produktionskod vad gäller tydlighet och format.

TDD eller... ?
Precis som med Unit tests är det ju inte direkt ett buzzword längre. TDD ha funnits ett bra tag, men jag har inte lyckats ta det till mig än. Jag tycker Uncle Bob är en riktig hjälte med många bra idéer. Jag skulle gärna vilja känna att TDD är min grej. Du vet väl vad TDD reglerna är?
  • You are not allowed to write any production code unless it is to make a failing unit test pass.
  • You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
  • You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
Mitt förfarande för unit tests är just nu trevande och utforskande. Det består i stort i att koda i mindre sjok för att sedan skriva tester i mindre sjok och så börja om igen. Istället för att känna mig missnöjd över att jag ännu inte kör TDD väljer att se det så här: Nu gör jag tester, det gjorde jag inte förut. Mina kodsvängar är kortare nu och jag tänker hela tiden på testbarheten. Jag är på gång!

Uncle Bob själv sa sig vara lite skeptisk till TDD först, men blev helt såld på det. Jag gillar ett citat han gav angående insikterna efter att ha givit sig hän till TDD, det säger lite av min känsla också.
I can no longer concieve of typing in a big long batch of code hoping it works. I can no longer tolerate ripping a set of modules apart, hoping to reassemble them and get them all working by next Friday.
- Uncle Bob

Over and out!

Dagens  kodarmusik: Supersnälla Silversara - Samla Samla (okej udda, men den är OMÖJLIG att få ur huvudet!!! Prova - jag vill inte lida själv.)


Lite länktips
Know Your Units - Kevlin Henney, Curbralan, UK
Coplien och Martin debaterar TDD, CDD och professionalism
TDD artikel från mästaren själv, Uncle Bob

fredag 27 november 2009

Videos från Öredev

Missa inte chansen att se dessa guldkorn från Öredev!
Scott Hanselman - Information overload and managing the flow
Neal Ford - The Productive Programmer

Och som en bonus, från ett tidigare Öredev,  missa absolut inte
Uncle Bob - The renaissance of craftsmanship

Jag lovar att var och en av dessa är väl värd sina 50 minuter. Garanterat!

Jag vill ha en databas i rött och grönt!

Alltså det här med automatiska tester är ju "old news" vid det här laget. Ja, att automatiska tester finns är ingen nyhet, men användningen av det är fortfarande nytt för många av oss, inte minst mig själv.
Med en kodbas på 100.000-tals rader kod är ett par hundra tester inget vidare facit. Men, nu var det inte det jag funderade på...

Vad jag länge funderat över är hur man testar databasen och DB2 i synnerhet. Det finns ju fina grejer som "Linq to SQL" eller "Visual Studio for Database Developers". Men - det gäller ju allt som oftas SQL Server. Jag har absolut inget emot MSSQL, tvärtom! Men, nu sitter jag inte med Microsoft utan med IBM DB2. Det finns mycket att säga om den, men i vår utvecklingsgrupp har vi efter en del besvärligheter äntligen hittat bra vägar att utveckla mot DB2.

Men att jobba med databaser innebär ju att man, hur man än vänder och vrider på accessen mot den, delar sin applikation i minst två delar. En del kör Stored Procedures med affärslogik (not my flavor...), en del SP's som ersättning mot SQL i koden (smakar bättre) och en del släpper loss med SQL kod blandat med den vanliga källkoden (smakar bäver). O/R mappers eller inte, databasen är en del av applikationen. Att designa och bygga den är en vital del av att bygga applikationen.

Men säg då att man valt SQL i koden, då är väl bara DB:n ett dumt lager? Nä. Det finns fortfarande triggers, referensintegritet, vyer... Så länge man lagt kod i databasen på ett eller anat sätt är det också en del av applikationen och måste på så vis också testas.

Okej. Du har inga triggers och ingen RI (skojar du eller?). Vet du vad, du har fortfarande ett testbehov! Vad händer om du förändrar schemat. Vad händer om du lägger till en kolumn eller byter en datatyp? Vad händer om någon annan gör det utan att du vet om det? Hur testar man att applikationen klarar det? Ofta tror man att "ja, men en sån ändring påverkar ju inte någon annan applikation". Men hur vore det att verkligen veta?

Nog om behovet. Det finns.

Min önskan är att jag skulle kunna lägga mina tester av databasen tillsammans med testerna av den övriga koden. Att få samma inbyggda Visual Studio stöd för mina tester. Att enkelt kunna testa fram om min nya release gör det den ska i databasen och hur bakåtkompatibel  den är.

Att testa att rätt saker händer i databasen
Det här ju egentligen rätt elementärt. Du ser till att databasen ser ut på ett visst sätt, att vissa data finns och att andra inte gör det. Du kör din kod. Du kontrollerar att rätt saker hänt.
Men hur gör man det på ett sätt som låter oss inkorporera det i Visual Studio tester?

Låt oss skapa en struktur av hjälpklasser som representerar databasen vid ett givet tillfälle, ett snapshot. Det rymmer sig extremt mycket information i databasens metadata, så det här kan autogenereras. Egentligen liknar min vision egentligen typade dataset, men med mindre buggar och kanske en aaaning snabbare.

Okej, jag ger mig på ett försök att förklara tanken med lite pseudokod.

Vi tänker oss en tabell med kunder som vi ska testa mot. Vi börjar med att se till att vår testkund inte finns redan.

TableCustomer.DeleteIfExists(12345); 

Varje tabell har ett antal hjälpmetoder, för att skapa, ta bort eller uppdatera rader. Vi känner till metadatan och vilka fält som är nycklar samt vilka som är NOT NULL. Det gör att vi kan skapa alla möjliga operationer mot databasen automatiskt. Särskilt mycket nytta får vi av de som arbetar mot primärnyckeln (som givetvis INTE behöver vara ett RowId, utan kan vara sammansatt)

När vi väl tagit bort kunden, kan vi köra vår riktiga kod. I detta fall ett anrop på en SP som skapar en kund.

// Detta är produktionskoden, ett anrop på en stored procedure
CustomerProxy.SaveCustomer(12345, "Test Customer", "West street 25", "Waynesburg, PA");

TableCustomer.Row row = TableCustomer.GetByPrimary(12345);
Assert.IsNotNull(row);
Assert.AreEqual(12345, row.CustomerId);
Assert.AreEqual("West street 25", row.StreetAdress);
Assert.AreEqual("Waynesburg, PA", row.CityAdress);


För de av er som ifrågasätter min simpla och uppenbart sunkiga datamodell - grattis! Ni lider av samma skada som jag. Men det är inte det viktiga. På ett enkelt sätt har vi testat att databasen ser ut som vi tänkte oss.Dessutom har vi gjort det med unit tests och testmöjligheterna är autogenererade.

Men vi har ytterligare en vinst: Vi märker när schemat ändras. Om någon skapar nya fält som krävs av kundtabellen kommer vår snapshot inte att fungera. Vår SP kommer inte heller fungera.

Om vi autoskapar vår snapshot varje natt i samband med det nattliga bygget kan vi få med alla de ändringar som skett i databasen. På det sättet kan vårt snapshot hänga med i förändringarna. Då blir det rätt uppenbart om någon ändrat någonting som påverkar våra tester. Efter vårt bygge kör vi ju givetvis vårt stora testpaket och hittar då en eller flera röda "pluppar" i testprotokollet.

Inte nog med det! Om vi inkluderar vårt snapshot med vår release som just nu ligger i produktion så vet vi vad applikationen förväntar sig av databasen. Det gör ju att testerna av releasen direkt smäller om någon släppt en "helt ofarlig ändring". Detta eftersom vi givetvis inte genererar om releasens snapshot utan kör på det den förutsatte vid releasetillfället.

Eller, ännu bättre! Om vi istället kör två uppsättningar tester av vår releasekod, en med den gamla snapshoten och en med en helt ny autogenererad snapshot. Då ser vi om vår kod klarar av den nya strukturen. Två sätt att testa samma sak, men ur olika vinkel och på det viset bättre!

Jag vet inte om ni har hängt med på hälften av det jag yrat om eller om det ens verkar vettigt. Jag brinner verkligen för det här ämnet och om allt vill sig väl hoppas jag presentera lite exempelkod vad det lider.

Kanske finns det till och med visst stöd i befintliga lösningar därute:
http://db2unit.sourceforge.net/
http://www.theserverside.net/discussions/thread.tss?thread_id=23702
http://www.anydbtest.com/

Vad som än finns i dessa lösningar, är själva idén något jag tror starkt på!

Phew! Dags att släppa vilda databastester för ett tag och ta helg!

Over and out!

Dagend kodarmusik: C-Quence - Endorphine (Original mix edit)

torsdag 26 november 2009

We are the Commitments!

Ja jag har inte ens sett den där "Commitments" rullen, men begreppet "Commitment" har jag funderat kring en del.

Att göra ett commitment är att förbinda sig, att förpliktiga sig att göra någonting. Att ställa upp helhjärtat för något och ingå en överenskommelse. Det här är ju en grundbult i all form av planering. Att kunna räkna med vad jag förväntas göra och att jag vet vad jag kan förvänta mig av andra.

Vissa personer är svårare än andra att få ett "commitment" från. Titta bara på hantverkare. Hur många av oss har inte fått "om en vecka" eller "i början av nästa månad" i ansiktet om vi frågat om den snälle rörmokaren/elektrikern/snickaren om han kanske eventuellt möjligen kommer snart?

Jag har mer än en gång raljerat över hur det skulle se ut om vi i IT branschen också gjorde så. För det gör vi väl inte? Vi säger väl alltid en fast tid och levererar väl alltid till den tiden? Vi kan väl enkelt räkna ut hur lång tid en funktion tar att införa? Tyvärr är det ju inte så. Jag tror att det till stor del på brister i våra commitments.

Dela upp saker i mindre uppgifter
Att få frågan "hinner du implementera denna funktionen på 3 veckor?" är oftast inte lätt att svara på. Tyvärr brukar jag lite väl snabbt göra ett överslag för att kunna svara "ja" direkt. Man vill ju inte sätta käppar i hjulen för en redan satt deadline och visst fixar man det där? Men en uppgift som tar 3 veckor att göra innehåller ju en hel del detaljer. Därför tycker jag att vi borde vara mer försiktiga med våra commitments och ta med oss en sådan fråga in på kammaren. Där delar man upp uppgiften i hanterbara delar som var för sig blir enklare att planera. Låt vara att det tar ett tag, men när man kommer tillbaka med sitt svar blir det mer säkert. Dessutom kan det självfallet också bli så att man svarar "ja, del 1,2 och 3 hinner jag. Men del 4 kommer inte finnas med". Då får beställaren bestämma sig för att tilldela mer resurser eller acceptera bortfallet.

Detta är en av delarna i Scrum som jag gillar skarpt. Att man avsätter tid i början av varje sprint för att planera, bryta ner och definiera vad man kommer hinna med. Att man faktiskt gräver ner sig lite i början för att kunna ge ett bättre commitment. Sen kan det ju finnas osäkra punkter man dyker på, men då är det ju ypperliga saker att börja med.

Daily scrum
Som jag skrev i ett tidigare inlägg är det här med "daily scrums" något jag tror starkt på. Vi har i teamet kommit överrens om vissa saker, vad som ska göras och när det kommer att vara klart. Att varje dag följa upp hur det går är att respektera våra gemensamma commitments. Då märker man tydligt om någon faller efter eller har svårt att klara sitt commitment. Eller förresten, det är ju hela teamet  som gjort ett commitment och de har vi ju alla intresse av att klara av! Att inte följa upp varje dag blir att kasta en överrenskommelse i ett svart hål och sedan få reda på vad som kom ur det där hålet. Jaha, det blev en sån!

Tydlighet i uppdrag och commitments
Ska vi kunna ge bra besked till våra beställare måste vi vara tydliga mot varandra, både som uppdragsgivare och som den som utför uppdraget. Allt för ofta pratar vi i lösa termer som "när du har tid" eller "ja, när du känner dig klar med A, kanske du kan titta på B?" Vad är det egentligen man har förbundit sig till i ett sådant läge? Ingenting! Vad kan beställaren förutsätta att du gör? Dito! Lägg till detta att man inte kommunicerar läget på sina commitments dagligen och vilken planering har du?

Det skulle kännas så mycket bättre om jag själv var säker på vad olika kravställare förväntar sig av mig och att jag har varit tydlig med vad jag kommer leverera. Då behöver man inte lägga onödig energi på spekulation, besvikelse eller frustration. Iallafall inte beroende på sina och andras commitments.

Efter att ha skrivit detta inlägg började jag googla lite och hittade ett mycket intressant dokument som beskrev hur agila metoder motverkar teamets problematik. Ett av dessa problem var just "Lack of commitments". Läs gärna How agile practices adress the five dysfunctions of a team!

Over and out!

Dagens kodarmusik: Darude - In The Darkness