Mark Robinson is testmanager bij Topic Embedded Systems. Hij heeft succesvol Lean, Agile en diverse testverbeterprocessen geïmplementeerd bij verschillende klanten.

9 March 2009

Lean Engineering gaat erover dat klanten krijgen wat ze echt willen in de kortst mogelijke tijd. Mark Robinson bespreekt de zeven verspillingen die dit ideaal in de weg staan en geeft tips om ze te vermijden.

Lean Engineering is, met de woorden van geestelijk vader Taiichi Ohno van Toyota, ’the absolute elimination of waste‘. Hij zei: ’All we are doing is looking at the timeline from the moment a customer gives us an order to the point when we collect the cash. And we are reducing that timeline by removing the non value-added wastes.‘ Deze quote is te vinden in het boek ’Implementing lean software development – from concept to cash‘ van Mary en Tom Poppendieck.

Lean Engineering is dus een manier om de efficiëntie van het softwareontwikkelproces te maximaliseren door de focus te leggen op het elimineren van verspilling. Maar wat is verspilling en hoe kunnen we het elimineren? Lean identificeert zeven types van verspilling: gedeeltelijk uitgevoerd werk, extra functionaliteit, opnieuw leren, overdracht, wisselen tussen meerdere taken, uitloop en fouten. In dit artikel zullen deze verspillingen een voor een de revue passeren.

1. Gedeeltelijk uitgevoerd werk

Lean Engineering vergelijkt werk dat niet af is met voorraad in het fabricageproces. Voorraad kan verloren of beschadigd raken en verouderen. Zo ook kan oude code beschadigd raken wanneer de oorspronkelijk auteur het team of bedrijf verlaat en anderen met minder kennis er wijzigingen in aanbrengen (in het bijzonder als de software slecht is ontworpen). Requirements kunnen verouderen als ze te vroeg zijn geschreven en de klantwensen inmiddels zijn veranderd. Ook ongeteste code is verspilling, omdat fouten zich opstapelen zolang de code ongetest blijft.

Techwatch Books: ASML Architects

Onaf werk is ook niet verkoopbaar. Jaren geleden werkte ik als softwareontwikkelaar in een klein team. Net als 99 procent van alle ontwikkelaars vonden we het leuk om code te schrijven, maar niet om te testen, laat staan te documenteren. Maar ieder item op onze lijst van ongeveer twaalf requirements per increment vereiste alle drie die activiteiten: coderen, testen en documenteren. Dus wat deden we? Eerst schreven we de code – dat was leuk. Gevolg: na een paar weken hadden we twaalf gedeeltelijk werkende stukken. Onze projectleider heeft ons toen opgedragen om eerst één stuk volledig af te maken alvorens verder te gaan met de volgende deel. Als het project zou uitlopen, konden we zo in ieder geval enkele complete functionaliteiten op tijd opleveren.

De beste manier om gedeeltelijk gedaan werk te voorkomen, is om een systeem in te richten dat vertragingen zo veel mogelijk elimineert. Dit vereist een frequente en regelmatige uitrol van het lopende werk naar de klant, met een korte tijdlijn van aanvraag naar implementatie. Twee acties zijn aan te bevelen: stap over op een Agile-werkwijze, met regelmatige releases (iedere twee tot vier weken), waarbij de klant de prioriteit bepaalt van iedere uitgave, en analyseer het huidige proces, gebruikmakend van de Value Stream Map.

value stream map2
Figuur 1: Een typische Value Stream Map, met de stroom van klantvraag naar –oplossing

2. Extra functionaliteit

Het is niet raar dat het vijf jaar duurde voordat Vista uitkwam, en vervolgens nog minstens een jaar van bugfixes voordat het zo betrouwbaar was als zijn voorganger XP. Vanwege een overkill aan requirements is het product overladen met extra functionaliteit, die bovendien veelal ongebruikt blijft. Dit gebeurt niet alleen bij Microsoft. Ik heb ontwikkelaars en testers zien overwerken om een release af te ronden en vervolgens geconstateerd dat de gebruikers maar een klein gedeelte van de beschikbare functies gebruikten. Om nog maar eens uit Poppendieck te quoten: ’If there isn‘t a clear and present economic need for the feature, it should not be developed.‘

In plaats van enorme requirementsdocumenten te maken (en daarmee de verspilling van gedeeltelijk uitgevoerd werk te introduceren) is het veel beter om eerst een minimaal pakket van functionaliteit overeen te komen. Laat de klant het product gebruiken zodra dit pakket is ontwikkeld, zodat deze direct al kosten kan beginnen te besparen ten opzichte van de huidige oplossing. Ontwikkel het minimale pakket incrementeel, geef het incrementeel vrij en laat de klant er regelmatig feedback op geven. De sleutel is: release snel en vaak. Bij ieder volgend pakket is het zaak om de vraag te stellen: is dit echt nodig? Als er enige twijfel is, ontwikkel de functionaliteit dan niet.

3. Opnieuw leren

Er zijn twee soorten van opnieuw leren: als een individu iets is vergeten en als een team iets vergeet. Jaren geleden was ik iedere avond verantwoordelijk voor het afsluiten van een magazijn. Ik had een aantal taken in verschillende ruimtes van het gebouw: deuren op slot, lichten uit en alarm aan. Op een avond maakte ik een fout en liet ik een buitendeur open. Niemand brak in, maar de wind activeerde een bewegingssensor, waardoor achtereenvolgens de politie werd gealarmeerd en mijn manager uit bed werd gebeld.

Mijn oplossing: ik maakte een checklist, die ik voortaan iedere avond gebruikte voordat ik vertrok. Het werk ging sneller en het gaf me ook een geruststellend gevoel – ik hoefde niet te vrezen dat ik iets was vergeten. Een checklist is een simpele manier om veel informatie in een bruikbaar formaat te gieten. Het is bruikbaar voor iedere zich herhalende taak, bijvoorbeeld bij het testen alvorens de software te leveren.

De verspilling van opnieuw leren doet zich ook voor als een team geen gebruik maakt van de informatie die het al heeft. Een teamlid zoekt bijvoorbeeld uit hoe de code werkt voor een exotische functie om een probleem op te lossen zonder zich te realiseren dat iemand anders hetzelfde probleem een paar maanden eerder al heeft opgelost in een ander gedeelte van de code. In grote bedrijven is het vaak nog erger. Ik heb meegemaakt dat verschillende afdelingen allemaal hun eigen methode ontwikkelden van automatisch testen.

Dit probleem is grotendeels te verhelpen door een interne wiki bij te houden. Wiki‘s werken goed omdat de drempel om wijzigingen te maken laag is en het makkelijk is om bestaande informatie te vinden. Traditionele documentatie is shelfware, documentatie die niemand ooit zal lezen en die snel overbodig wordt – zoals de voorraad hierboven. Wikidocumentatie is levend, continu veranderend, uitdijend en verbeterend. Tegenwoordig, met uitstekende gratis of goedkope wikisoftware, is er echt geen excuus meer om geen bedrijfsbrede wiki te hebben, vooral niet voor een IT-bedrijf.

4. Overdracht

Hoe goed de documentatie ook is, zolang er overdracht is, zal er altijd sprake zijn van opnieuw leren. Er is overdracht als een persoon die een taak heeft zijn waarde aan het product toevoegt en het dan overdraagt aan de volgende persoon. Lean zegt dat overdracht mislukt omdat een persoon maar maximaal 50 procent van wat hij weet, kan overdragen aan een ander. In een keten wordt dit alleen nog erger: een klant vertelt de klantenservice wat hij wil (50 procent kennisverlies), die afdeling zet dit in een requirementsdocument (75 procent verlies), waarna de ontwikkelaars en testers de requirements interpreteren (88,5 procent verlies). Het zal meerdere iteraties duren voordat de klant krijgt wat hij wil. Gevolg: gedeeltelijk uitgevoerd werk en uitloop.

Er zijn drie oplossingen. De eerste is regelmatig leveren aan de klant en regelmatig feedback terugkrijgen. De tweede is kruisfunctionele teams creëren om de interne communicatie te verbeteren. Maak bijvoorbeeld een team van ontwikkelaars, testers en klantenservicemedewerkers in plaats van een team dat enkel bestaat uit ontwikkelaars. De derde oplossing is: vermijd overdracht. Het komt nogal eens voor dat één ontwikkelaar een fout onderzoekt en een ander die oplost. Het is veel efficiënter om dezelfde ontwikkelaar beide taken te laten doen – bij voorkeur met zo min mogelijk tijd tussen beide taken (om opnieuw leren te voorkomen).

5. Wisselen tussen meerdere taken

Stel er zijn drie taken: A, B en C, die ieder weer zijn opgesplitst in drie subtaken: 1, 2 en 3. En stel dat er twee volgordes zijn om deze taken uit te voeren: A1 A2 A3 B1 B2 B3 C1 C2 C3 en A1 B1 C1 A2 B2 C2 A3 B3 C3. Als iedere subtaak een dag duurt, dan is in de eerste volgorde taak A klaar na drie dagen, maar in de tweede volgorde is na zes dagen nog geen enkele taak af. En dan neemt dit voorbeeld nog niet eens de tijd mee die het duurt om fysiek (naar een andere locatie gaan) en mentaal (bepalen waar je was gebleven) te wisselen tussen de taken. Ten slotte kan de klant in de eerste volgorde A al gebruiken en feedback geven in de drie dagen dat er wordt gewerkt aan B.

Dit voorbeeld illustreert de verspilling die inherent is aan het wisselen tussen taken. Waarom wordt er dan toch zo veel gewisseld? Soms zijn mensen gewoon chaotisch, soms hebben ze chaotische managers die voordurend met prioriteiten schuiven. De meest voorkomende reden is echter: uitloop.

6. Uitloop

Verschillende kleine interne vertragingen tellen al snel op tot een grote uitloop voor de klant. Dit is tegenstrijdig met Lean: hoe langer de klant op zijn product moet wachten, hoe langer het duurt voordat je je geld krijgt. Maar dat is niet alles: de klant mag dan wel voorbereid zijn om op het product te wachten, de buitenwereld wacht niet. De wereld blijft veranderen en dus ook de klantrequirements. Veel van het geïmplementeerde is niet langer relevant. Daarnaast heeft de klant een heel pakket van extra eisen die hij geïmplementeerd wil zien. Dit leidt niet alleen tot nog meer uitloop (vicieuze cirkel), maar ook tot extra testinspanningen.

Vertraging betekent dat een klant niet krijgt wat hij wil wanneer hij het wil. En als de concurrent dit wel kan bieden, dan heb je een serieus bedrijfsrisico. Uitloop komt voor bij zowel nieuwe requirements als bugfixes. Overweeg deze vraag eens: als de klant een kritische fout vindt in het product, hoe lang duurt het dan voordat de fout onderzocht, opgelost, getest en vrijgegeven is? Uren? Dagen? Of weken?

Uitloop treedt op als werk zich opstapelt op één plek, bijvoorbeeld in de requirements- of de testfase. Daar ontstaan dan buffers met gedeeltelijk uitgevoerd werk. Daarnaast kan er vertraging optreden door extra werk (churn), bijvoorbeeld bij het repareren van fouten. De oplossing voor deze verspilling begint bij het zichtbaar maken van de uitloop. Dit kan weer met een Value Stream Map.

7. Fouten

Een lineaire toename van requirements veroorzaakt een exponentiële groei in complexiteit van de code, en dus in het aantal fouten. Eén manier om dit te voorkomen, is door extra requirements weg te laten. Hoe kan Lean Engineering nog meer helpen?

Lean gebruikt het concept van mistake proofing: maak het onmogelijk voor mensen om fouten te maken. Mijn twee jaar oude dochter houdt bijvoorbeeld van bellenblazen. Haar eerste flesje bellenblaas had een dop die je eraf schroeft en een stokje met een ring eraan om de bellen te blazen. Heel simpel, maar niet foutvrij: het was heel makkelijk voor haar om het stokje in de fles te laten vallen en moeilijk om het er weer uit te krijgen. Dus kwamen haar handen onder de bellenblaasvloeistof te zitten, of ze hield de fles op de kop. In de volgende versie zat het stokje vast aan de dop. Hierdoor kon mijn dochter het niet meer in de vloeistof laten vallen. Helaas hield ze nog steeds de fles op de kop, waardoor alle vloeistof eruit liep. De tweede versie was dus dichter bij, maar nog niet helemaal foutvrij. De derde en laatste fles had een stokje dat groter was dan de fles, zodat het niet helemaal in de vloeistof kon zakken. Ook had deze versie een slimme trechter in de fles, waardoor de vloeistof er niet uit kon lopen, ook niet als het flesje op de kop werd gehouden. Foutvrij? Niet helemaal: mijn dochter liep naar de zandbak en vulde de fles met zand.

Hoe kun je foutvrije software schrijven, zonder gebruik te maken van de traditionele (en verspillende) test-alles-aan-het-einde-aanpak? Door processen te introduceren die fouten vroeg vinden. Automatisering van de regressietests, ten minste één smoketest of een eenvoudige end-to-endtest maakt het mogelijk om vroeg en vaak te testen. Als je uitloop kunt voorkomen door fouten eerder op te lossen, zal dit een enorme hoeveelheid tijd schelen op de lange termijn. Wat hoor je liever van je testers: we hebben een fout gevonden in je code die je gisteren hebt geïntroduceerd, of we hebben een fout gevonden die je hebt geïntroduceerd sinds de laatste release, drie maanden geleden? Zoals het aloude spreekwoord zegt: voorkomen is beter dan genezen.