Follow Us on Twitter

Voortdurend Integreren, Voortdurend Controle

Gepubliceerd in

Januari 2007 - Een groot project bestaande uit een aantal teams met tal van ontwerpers, ontwikkelaars en testers loopt tegen een deadline. Volgende week staat er een belangrijke oplevering gepland. Er heerst op dit project totaal geen gestreste sfeer, want iedereen vertrouwt erop dat de geplande oplevering geen probleem zal zijn. Iedereen heeft namelijk keurig op tijd alle werkzaamheden af kunnen ronden en getest dat zijn/haar gebouwde functionaliteit werkt. Het is slechts nog een kwestie van de losse onderdelen in elkaar schuiven om de distributie compleet te maken.

Tijdens dat integratie proces echter, blijkt dat niet alle delen vlekkeloos op elkaar aansluiten. Plots is de rustige sfeer omgeslagen in paniek en stress. Hoe krijgen we deze situatie weer onder controle?

In dit Whitebook behandel ik de methodiek die ons helpt dit soort integratie vraagstukken te ondervangen. Ik behandel de werkwijze en best practices van het integreren van geproduceerde applicatiecode binnen een project. Daarmee stip ik meteen op integratie vraagstukken aan die organisatie- of landengrenzen overschrijdende zijn.

Inzage en Controle

Goede controle op het totale ontwikkelproces voorkomt dit soort, plotseling opduikende, problemen aan het einde van het project.

Wanneer een ontwikkelteam de opdracht heeft gekregen om een software applicatie te realiseren, vindt er idealiter op projectniveau een afbakening plaats van taken, rollen en verantwoordelijkheden per persoon. De projectleider stuurt de projectleden aan en houdt de globale scope in de gaten. De teamleider stuurt de mensen binnen het ontwerp-, ontwikkel- of testteam aan. De analisten inventariseren de functionele eisen voor de applicatie. De ontwikkelaars ontwerpen en realiseren de applicatie. En testers checken of hetgeen ontwikkeld is voldoet aan de functionele eisen.

Wanneer deze rolverdeling helder is en iedereen zijn taken en verantwoordelijkheden kent, kunnen de projectleden vervolgens redelijk zelfstandig te werk gaan. Procedurele controles zijn daarbij van belang om de voortgang te kunnen bewaken. Daarmee komt meteen een van de voornaamste valkuilen aan het licht. Als medewerkers té “zelfstandig” gaan werken en daarbij nalaten de controle momenten te benutten om te rapporteren over hun voortgang ontstaat al snel een onstuurbare situatie.

Aan de ene kant wordt zelfstandig werkzaam kunnen zijn gezien als een zeer sterke eigenschap van een medewerker. Deze persoon behoeft dan namelijk minder aansturing. Aan de andere kant ligt hier een basis voor uitlopende en falende projecten. Wanneer medewerkers te veel zelfstandig opereren kan dat ten koste gaan van de overkoepelde samenhang. Communicatie is daarbij een van de belangrijke factoren. Het komt nogal eens voor dat ontwikkelaars binnen die eigen verantwoordelijkheden hun eigen wereld creëren. Voor managers levert dat vaak een oncontroleerbare situatie op.

Er zijn een aantal methoden die ingericht kunnen worden om deze situatie voor te zijn. Ten eerste kan men trachten de functionaliteit op te delen in kleinere testbare eenheden (small units of work). Ten tweede kan er op projectniveau een kort dagelijks overleg ingepland worden waarin kort per persoon de werkzaamheden, de status en de problemen besproken kunnen worden(scrum). Zo houdt men het overzicht van de algehele status van het project in de gaten en kunnen problemen snel kenbaar gemaakt en opgelost worden. Tot slot kan men op geautomatiseerde wijze voortgang en status bewaken op zowel project als individueel niveau middels het voortdurend integreren en testen van de broncode. Deze methode wordt ook wel Continuous Integration genoemd.

Continuous Integration

Hoe kan Continuous Integration (CI) hierbij nu hulp bieden? Daarvoor is het wellicht handig eerst een toelichting te geven over de term Continuous Integration.

Met CI wordt bedoeld: het voortdurend samenvoegen en toetsen van applicatiecode gedurende het ontwikkelproces waarmee de toestand van de code gecontroleerd kan worden. Dit principe is ook een onderdeel van de extreme programming richtlijnen.

Het ontwikkelen van een applicatie is een iteratief proces waarbij vaak vele bestanden(broncode) worden geproduceerd. Voortdurend worden er nieuwe functionaliteit en wijzigingen toegevoegd aan de (groeiende) applicatie. Elke toevoeging en wijziging die er plaats vindt op de broncode wordt grondig getest op zowel unit- als systeemniveau. Dit wordt gedaan om zeker te zijn dat de applicatie nog volledig en naar verwachting functioneert na elke wijziging. Dus niet alleen de wijziging zelf wordt getest maar tevens alle andere functionaliteit binnen de applicatie om zeker te zijn dat de aangebrachte wijziging geen nadelige bijeffecten heeft op de overige functionaliteit van de applicatie.

Inrichting

Er zijn diverse tools te vinden, die CI mogelijk maken. Voor het bouwen, testen en distribueren van de applicatiecode kan men gebruik maken van Maven. Maven2 biedt zogeheten build software waarmee zowel centraal als lokaal de mogelijkheid wordt geboden aan ontwikkelaars en projecten om op eenvoudige en eenduidige wijze de applicatiestructuur op te zetten en een distribueerbare applicatie te smeden.

Voor een betere beheersbaarheid en een groter ontwikkelgemak maken we gebruik van een versiebeheerssysteem die de applicatiecode bijhoudt. SubVersion is daar zeer geschikt voor. SubVersion is een versiebeheerssysteem waar de applicatiecode, gelabeld met behulp van een versienummer, bijgehouden wordt. Deze tools worden beide geplaatst op een centrale build server om zo build en version control centraal beschikbaar te stellen.

Nu is er een omgeving gecreëerd waarmee men met meerdere ontwikkelaars aan dezelfde applicatie kan werken. Men heeft de mogelijkheid om de broncode zowel lokaal als centraal te bouwen en men kan deze broncode centraal opslaan, bijhouden en integreren. Met behulp van de juiste discipline kan men nu dus handmatig CI toepassen.

Het is echter beter om deze verantwoordelijkheid niet bij de ontwikkelaar neer te leggen. Die is immers ingehuurd om business logica te implementeren. Gelukkig hoeft dat ook niet, want met tools als Continuum of CruiseControl is deze taak automatisch in te richten.

Met de inrichting van tools als Continuum of CruiseControl verzekeren we het proces van continue code integratie. Men plant hiermee geautomatiseerde taken(cron jobs) in die elke nacht alle code uitchecken uit SubVersion en vervolgens bouwen en testen met Maven(nightly builds). Op die manier wordt dagelijks inzage gegeven in de werkzaamheid van de geproduceerde broncode en kunnen fouten direct gedetecteerd en opgelost worden. Daarnaast heeft het testteam op deze manier elke dag beschikking over de meest recente versie van de applicatie.

Ter ondersteuning van dit proces worden er rapportages gegenereerd worden die inzage geven in de status van de huidig gerealiseerde code. Deze rapportages zijn voor zowel het ontwikkelteam als projectmanagement van belang om beslissingen te kunnen nemen. Enerzijds rapporteert de tool waar de fouten zitten zodat de ontwikkelaars die fouten direct kunnen oplossen. Anderzijds worden er globale rapporten gegenereerd waarmee projectmanagement kan herleiden in welk stadium het project op dat moment verkeerd. Deze directe feedback die CI levert zal voor ontwikkelaars stimulerend werken om hun gerealiseerde functionaliteit vaker te synchroniseren in kortere ontwikkel cycli.

Overigens staat hier slechts een selectie beschreven van tools die ingezet kunnen worden om CI te realiseren. Het voornaamste is dat deze tooling erop gericht is om het voor ontwikkelaars en projecten zo eenvoudig mogelijk te maken om toe te passen. Het betreft hier bovendien open source software welke vrij te gebruiken is.

De praktijk

In de inleiding noemde ik al een praktijk situatie van een project dat in de problemen kwam door gebrek aan integratie.
Meerdere handen binnen meerdere teams werken aan dezelfde applicatie. Deze wordt uiteindelijk als een geheel opgeleverd, getest en geïnstalleerd. Elke ontwikkelaar werkt hierbij aan een eigen afgebakend stuk functionaliteit, welke onderdeel uitmaakt van het grotere geheel. Om aansluiting bij de overige ontwikkelde code zo soepel mogelijk te laten verlopen, dient men de code al vroegtijdig te publiceren in de centrale repository. Telkens wanneer er weer een werkend deel functionaliteit wordt gerealiseerd wordt deze centraal gepubliceerd. Dit dient minimaal een keer per dag te gebeuren. Voor het publiceren wordt de functionaliteit getest door de ontwikkelaar tegen zijn lokale code. Na het publiceren worden de testen nogmaals uitgevoerd tegen de centrale code. Pas dan kan men inschatten of de toegevoegde functionaliteit echt werkt. Zo kan men fouten direct constateren en oplossen.

Fouten die men constateert dient men direct op te lossen en niet uit te stellen tot later. De praktijk leert dat wanneer men het herstellen van defecte code uitstelt, het uiteindelijk meer tijd en inspanning kosten om dit op te lossen. Dit komt omdat men voort ontwikkelt op “gebroken” code. Wat ook tot fouten leidt in die nieuwe code. Als de fout bovendien is toegevoegd aan de centrale code heeft het hele ontwikkelteam er last van. Het ‘fix broken windows’ principe. Hiermee doelt men op het feit dat wanneer er in een gebouw een raam gesneuveld is de kans groot is dat er de volgende dag nog een raam gesneuveld zal zijn. En dat er een week later waarschijnlijk geen heel raam meer in het gebouw zit. Dat ene kapotte raam trekt hangjeugd aan die hun verveling botvieren op dat “toch al kapotte gebouw” door nog een paar ramen in te gooien. Wanneer het raam echter direct wordt gerepareerd zal de hangjeugd eerder ergens anders gaan hangen. Hetzelfde principe gaat op voor applicatiecode. Wanneer defecte code niet direct gerepareerd wordt, zal het van kwaad tot erger gaan. Wordt het defect wel direct opgelost, dan voorkomt men een hoop ergernis en inspanning achteraf en bespaard men een hoop tijd.

Deze werkwijze vereist wel enige consequentheid van de ontwikkelaars binnen het project, maar wanneer zij volgens deze werkwijze werken kunnen ze enerzijds zelfstandig opereren en vindt er anderzijds toch de nodige controle plaats. De gegenereerde rapportages zijn hierbij het hulpmiddel om die controle te behouden.

Het gebruik van een centrale Maven repository en Continuous Integration maakt het tevens mogelijk om te werken in gedistribueerde teams. Voorbeelden zijn het integreren van projecten binnen een organisatie of het out-sourcen van een gedeelte van een project waarbij ontwikkelteams fysiek op verschillende plaatsen zitten.

Figuur 1 Landsgrens overschrijdende gedistribueerde teams

In een project met gedistribueerde teams worden drie verschillende soorten repositories ingericht. Ten eerste de lokale repository die elke ontwikkelaar in zijn eigen werkplek heeft staat en waarop hij/zij direct werkt. Ten tweede een de-centrale of on-site repository waarin de ontwikkelaars per team hun code publiceren. Tot slot de centrale repository waarin de on-site repositories hun wérkende code publiceren. De build servers worden hiervoor op een dergelijke wijze ingericht dat alleen code zonder compilatie fouten, met succesvolle unit testen gepubliceerd kan worden in de centrale repository.

Denk nu niet dat continuous integration alleen bedoeld is voor grote projecten. Zeker ook voor de kleine eenmans projecten heeft het zijn nut bewezen. Het feit dat er direct controle is op de correctheid van de gepubliceerde code, heeft direct voordelen voor de ontwikkelaar. Bovendien worden alle testen geautomatiseerd uitgevoerd en vindt er concrete rapportage plaats over de uitgevoerde acties.

Wanneer een programmeur tijdens het ontwikkelen van een applicatie een stuk code wil aanpassen, kan deze aanpassing direct van invloed zijn op de overige code van de applicatie. Wanneer er door deze aanpassing iets anders kapot gaat kan dat zeer vervelende gevolgen hebben wanneer dat niet meteen hersteld wordt. Idealiter zou men direct willen checken of met deze aanpassing alle overige code nog steeds werkt. Of deze ontwikkelaar nu alleen of in een team verband aan deze applicatie werkt is daarbij niet relevant.

Best practices

Naast de handreikingen die de tooling biedt, dient men zich ook te conformeren aan een bepaalde werkwijze om de CI methodiek optimaal te laten werken:

  • Opdelen van functionaliteit in kleinere testbare eenheden. Hiermee kan men vrij snel unit testen definiëren en wordt de hoeveelheid werk overzichtelijker. Men heeft op deze manier tevens sneller een werkend onderdeel gerealiseerd, welke gepubliceerd kan worden in de centrale repository. Dit komt ten goede aan de controle op de voortgang.
  • Unit testen schijven voor elke onderdeel (Test Driven Development). De TDD methodologie schrijft voor om de test code te schrijven voordat men de functionaliteit gaat bouwen. Initieel zal deze test dan falen. En wanneer deze test slaagt, is de functionaliteit gebouwd. Dit geeft een goed overzicht van de nog te bouwen en reeds gerealiseerde functionaliteit.
  • Een centraal versie beheerssysteem inrichten(repository), waarin iedereen zijn code publiceert. Met een centrale repository wordt alle code vanaf het begin van het project samengevoegd en centraal bijgehouden. 
  • Met hoge frequentie, gerealiseerde functionaliteit toevoegen aan de centrale repository(synchroniseren). Wanneer alle teamleden hun werkzaamheden met regelmaat synchroniseren, komen defecten vroegtijdig aan het licht.
  • Een aparte geautomatiseerde build server inrichten. 
  • Los defecten direct op. Het ‘fix broken windows’ principe.

Conclusie

Om de voortgang en status van een applicatie ontwikkelproject inzichtelijk en beheersbaar te maken is de methodiek Continuous Integration beschikbaar. Middels het inrichten van de beschreven tooling is het eenvoudig deze methodiek toe te passen.

De voornaamste voordelen zijn: 

  • Integreren van nieuwe code binnen het iteratieve ontwikkelproces verloopt eenvoudig en gecontroleerd.
  • Het testteam heeft tijdens het ontwikkelproces voortdurend beschikking over de meest recente versie van de applicatie. 
  • Defecten in zowel de nieuwe als de bestaande functionaliteit komen middels unit testen meteen aan het licht(Test Driven Development). 
  • De voortdurende controle draagt tevens bij aan meer iteratieve werkwijze met een hogere synchronisatie frequentie en kortere ontwikkel cycli. 
  • Er is voortdurende controle dat de totale applicatiecode goed gebouwd kan worden. 
  • Goede controle op het totale ontwikkelproces voorkomt plotseling opduikende, ontbrekende functionaliteit aan het einde van het project. 
  • Deze projectopzet dwingt af dat er goed nagedacht wordt over ontwerp en architectuur wat tevens de onderhoudbaarheid ten goede komt.

Met deze argumenten op tafel is CI mijns inziens een must voor elke project. Ongeacht welke omvang. Deze methodiek levert dé oplossing voor controle, inzage en sturing die van elk willekeurig applicatieontwikkelingsproject een serieus IT project maken.

Genoeg reden dus om Continuous Integration serieus te nemen en in te richten bij huidige en aanstaande projecten waaraan u uw bijdrage levert.

Links

Waardering:
 
Tags:

Reacties

Nieuwe reactie inzenden

De inhoud van dit veld is privé en zal niet openbaar worden gemaakt.

Meer informatie over formaatmogelijkheden

CAPTCHA
Deze vraag is om te testen of u een persoon bent en om spam te voorkomen
Image CAPTCHA
Enter the characters shown in the image.