Continue integratie

Maak je team meer agile met snellere feedback. Omdat je maar zo snel beweegt als je tests.

Dan Radigan Door Dan Radigan
Onderwerpen zoeken

Niets kan flexibiliteit zo goed opbouwen of vernietigen als de toewijding van een team aan continue integratie (CI). Dat klinkt misschien onheilspellend (vooral als je team CI nog moet omarmen), maar er is goed nieuws. Ongeacht de technologieën die een team gebruikt, is de kans groot dat er een framework voor continue integratie en geautomatiseerd tests is dat werkt voor de codebase van het team.

Wat is continue integratie?

Continue integratie is een agile en DevOps best practice om codewijzigingen routinematig te integreren in de hoofdbranch van een repository en de wijzigingen zo vroeg en vaak mogelijk te testen. Idealiter integreren ontwikkelaars hun code dagelijks, zo niet meerdere keren per dag.

Voordelen van continue integratie

Investeren in CI resulteert in snelle feedback op codewijzigingen. Zo snel als 'binnen enkele minuten'. Een team dat voornamelijk afhankelijk is van handmatige tests, kan binnen een paar uur feedback krijgen. In werkelijkheid komt uitgebreide testfeedback een dag (of meerdere dagen) nadat de code is gewijzigd. En tegen die tijd zijn er meer veranderingen opgetreden, waardoor het oplossen van bugs een archeologische expeditie wordt waarbij ontwikkelaars verschillende lagen code doorgraven om de oorzaak van het probleem te achterhalen.

Dat gaat zeker niet snel.

Kwaliteit beschermen met continue builds en testautomatisering

Hoeveel van ons hebben de nieuwste broncode gedownload en ontdekt dat deze niet is gecompileerd of een ernstige bug bevatte? Wat een productiviteitskiller!

Twee werkwijzen zorgen dat we niet in die situatie komen:

Continue builds: het project opbouwen zodra er een wijziging is aangebracht. Idealiter is het verschil tussen elke build één set wijzigingen.

Testautomatisering: programmatische validatie van de software om de kwaliteit te waarborgen. Tests kunnen acties in de software starten vanuit de gebruikersinterface (daarover dadelijk meer) of vanuit de laag met backendservices.

Zie deze twee werkwijzen als pindakaas en hagelslag: apart smaken ze goed, samen smaken ze heerlijk! Continue integratie koppelt continue builds aan testautomatisering om ervoor te zorgen dat elke build ook de kwaliteit van de codebasis beoordeelt.

En onthoud: om de voordelen volledig te realiseren, moet een team ook de discipline hebben om de ontwikkeling te onderbreken en defecten meteen aan te pakken. De energie die een team investeert (en vergis je niet: het is een investering) in het schrijven van tests en het configureren van de automatisering is helemaal voor niets als builds in een defecte staat mogen verpieteren. Het beschermen van de investering in CI en het beschermen van de kwaliteit van de codebasis zijn een en hetzelfde ding.

Testen in CI: unit-, API- en functionele tests

CI-runs kennen twee belangrijke fasen. Stap één zorgt ervoor dat de code wordt gecompileerd. (Of, in het geval van geïnterpreteerde talen, pullt gewoon alle delen bij elkaar.) Stap twee zorgt ervoor dat de code werkt zoals ontworpen. De manier om er zeker van te zijn dat dit werkt is door een reeks geautomatiseerde tests uit te voeren die alle niveaus van het product valideren.

Unittests

Unittests worden heel dicht bij de kerncomponenten in de code uitgevoerd. Ze zijn de eerste verdedigingslinie om kwaliteit te waarborgen.

Voordelen: eenvoudig te schrijven, snel uit te voeren, modelleren de architectuur van de codebasis nauwkeurig.

Nadelen: unittests valideren alleen kerncomponenten van software. Ze weerspiegelen geen gebruikersworkflows waarin vaak meerdere componenten samenwerken.

Omdat een unittest duidelijk maakt hoe de code moet werken, kunnen ontwikkelaars unittests bekijken om meer te weten over dat gebied van de code.

API-tests

Goede software is modulair, wat zorgt voor een duidelijkere scheiding van werk tussen verschillende toepassingen. API's zijn de eindpunten waar verschillende modules met elkaar communiceren, en API-tests valideren ze door aanroepen van de ene module naar de andere te doen.

Voordelen: over het algemeen eenvoudig te schrijven, snel uit te voeren en modelleren gemakkelijk hoe toepassingen met elkaar communiceren.

Nadelen: in eenvoudige onderdelen van de code kunnen API-tests sommige unittests nabootsen.

Omdat API's de interfaces zijn tussen delen van de applicatie, zijn ze vooral handig bij het voorbereiden van een release. Zodra de build van releasekandidaat alle API-tests heeft doorstaan, kan het team er veel meer vertrouwen in hebben om deze naar klanten te verzenden.

Functionele tests

Functionele tests werken over grotere delen van de codebasis en modelleren gebruikersworkflows. In webapplicaties werken HTTPunit en Selenium bijvoorbeeld rechtstreeks met de gebruikersinterface om het product te testen.

Voordelen: meer kans om bugs te vinden omdat ze gebruikersacties nabootsen en de interoperabiliteit van meerdere componenten testen.

Nadelen: langzamer dan unittests en soms rapporteren ze valse negatieven vanwege netwerklatentie of tijdelijke uitval ergens in de technologiestack.

Teams merken vaak dat naarmate ze dichter bij de daadwerkelijke gebruikersworkflow komen, de snelheid waarmee geautomatiseerde tests worden uitgevoerd afneemt. HTTPunit is sneller omdat het geen volwaardige webbrowser is. Selenium kan slechts zo snel werken als de webbrowser, maar heeft het voordeel dat het in meerdere webbrowsers tegelijk loopt. Ondanks deze kanttekeningen zijn functionele tests enorm waardevol en bieden ze veel sneller feedback dan menselijke testers ooit zouden kunnen.

En nu we het er toch over hebben ...

Sommige testers zien geautomatiseerde tests als een existentiële bedreiging. Dit is kortzichtig en kan niet verder van de waarheid liggen. Testers worden bevrijd van de sleur van repetitieve testtaken en kunnen tijd besteden aan risicoanalyse, testplanning en het opbouwen van andere vaardigheden, zoals leren coderen!

Continue integratie snel maken

Bij Atlassian streven we ernaar om te zorgen dat ontwikkelaars blijven innoveren en onze codebases gezond houden. We leggen veel nadruk op het aanscherpen van de ''innerlijke feedbacklus van de ontwikkelaar": de tijd die nodig is om wijzigingen op te bouwen en testresultaten te verkrijgen.

Door geautomatiseerde tests uit te voeren, kan de bouwduur snel oplopen. Eén strategie is om geautomatiseerde tests over meerdere servers of 'buildagents' te parallelliseren zodat de CI-server eigenlijk 2, 20 of zelfs 200 tests tegelijkertijd uitvoert. Met cloudtechnologieën kan de CPU eenvoudig worden geschaald om te voldoen aan de behoeften van je ontwikkelingsteam naarmate je testsuites groeien. Maar de CPU is niet onbeperkt. Test elk gebied van de code volledig, maar niet overbodig. Redundante tests verhogen de bouwduur (en leiden tot verspilling van CPU). Hoe eerder engineers groen licht krijgen, hoe sneller ze door kunnen gaan naar het volgende item in de backlog.

Branching en CI: de ideale combi!

Veel teams vermijden branching vanwege de lastige samenvoegingen. Met nieuwere technologieën voor versiebeheer zoals Git, zijn branching en samenvoegen eenvoudig. Om ervoor te zorgen dat de primaire coderegel ('main' in Git-taalgebruik) gezond blijft, voer je hetzelfde niveau van continue integratie uit op alle ontwikkelings- en stabiele versiebranches. Wanneer de build een branch doorgeeft, heeft het team het vertrouwen om die code stroomopwaarts samen te voegen.

Met branching, continue integratie en testautomatisering kunnen teams productief en innovatief zijn en tegelijkertijd de codekwaliteit beschermen. Als je klaar bent om de volgende stappen te zetten, bekijk dan onze stapsgewijze handleiding om aan de slag te gaan met CI.

Dit is agile ontwikkeling op zijn best: werkende software regelmatig leveren, met minimale technische schulden en zonder concessies te doen aan vindingrijkheid.

Hierna
Ontwerp