terug naar overzicht

Yuri Burger

+31 6 11 75 16 83


04/02/22

Continu feedback

Vandaag de dag wordt software zelden nog gemaakt door één enkele ontwikkelaar. Eigenlijk zien we vooral meerdere teams samenwerken aan applicaties en oplossingen. Hierbij is feedback van het grootste belang: het laat ontwikkelaars zien, dat de software op een bepaalde manier correct werkt. Het vertelt of de code qua syntax correct is (‘it builds!’), maar ook dat vitale onderdelen nog steeds werken zoals bedoeld is (de ‘unit tests’ slagen!) en dat de wijzigingen van individuele ontwikkelaars elkaar niet in de weg zitten. In dit artikel kijken we naar wat we allemaal aan terugkoppeling kunnen organiseren en op welke manier dat kan bijdragen aan betere software!

De ‘Inner Feedback Loop’

Dit type terugkoppeling is dus vrijwel direct. Normaal gesproken begint dit al in ontwikkelomgeving lokaal, de IDE (‘Integrated Development Environment’). De meeste van deze IDE’s hebben manieren om ontwikkelaars te informeren hoe het staat met de code terwijl deze wordt geschreven: in de vorm van rode kringellijntjes die aangeven of de code fout of verdacht is. Op de achtergrond is de compiler bezig met het compileren van de code en voert de unit tests uit. Vooral deze testen laten bijna in real-time zien of de code ernstige gebreken bevat. Dit speelt zich nog allemaal af op de lokale machine van de ontwikkelaar, maar zoals we al eerder gezegd hebben: software wordt tegenwoordig nog maar zelden door één ontwikkelaar gemaakt.rnrnWanneer de ontwikkelaar zijn code af heeft, worden de wijzigingen doorgegeven aan de centrale repository. Op dat moment kunnen een hoop verschillende checks plaatsvinden:rnu003culu003ern tu003cliu003eCompileert de code?u003c/liu003ern tu003cliu003eSlagen de unit- en integratietesten nog?u003c/liu003ern tu003cliu003eZijn er bevindingen naar aanleiding van een (statische) code analyse?u003c/liu003ern tu003cliu003eZijn er bevindingen naar aanleiding van een Code Review door een teamlid?u003c/liu003ernu003c/ulu003ernTegenwoordig gebruiken de meeste teams een 2-staps proces: als eerste dient een ontwikkelaar de wijzigingen in en verpakt deze in een zogeheten ‘Pull Request’. Dit wordt gevalideerd: deels automatisch met behulp van bovengenoemde checks en deels handmatig in de form van een ‘Code Review’. Als de code slaagt voor deze checks, dan wordt ze samengevoegd met de ’main codebase’ of hoofdcode (een samenstelling van alle eerder gemaakte en gevalideerde code). Dit is tevens de start van de tweede terugkoppeling.

De ‘Short Feedback Loop’

In het ideale geval start deze terugkoppeling direct nadat de ingediende code is geïntegreerd met de rest van de code. Normaal gesproken wordt er vanuit deze codebase, direct een versie uitgerold op een omgeving. Maar voordat we uitrollen herhalen we een aantal checks en voeren we een aantal nieuwe checks uit. Het verschil is dat we dit nu doen op de gehele codebase en niet slechts op de ingediende wijzigingen. Dit betekent wel dat deze checks over het algemeen langer lopen en dus meer tijd kosten, maar ook dat we meer/uitgebreidere testen kunnen doen:rnu003culu003ern tu003cliu003eAPI testen;u003c/liu003ern tu003cliu003eSupply Chain testen waar we onze software nalopen op kwetsbaarheden in afhankelijkheden (zogeheten ‘dependencies’);u003c/liu003ern tu003cliu003eKunnen we het uitrollen op een testomgeving?u003c/liu003ern tu003cliu003eGeautomatiseerde security scans en performance testen;u003c/liu003ern tu003cliu003eGeautomatiseerde UI testen.u003c/liu003ernu003c/ulu003ernDit proces loopt een stuk langer vergeleken met de eerste loop, maar verzamelt ook gegevens in meer detail. Toch mag je verwachten dat deze terugkoppeling snel komt. Vooral om ervoor te zorgen dat ontwikkelaars zo min mogelijk verstoord worden, ze zijn immers al aan nieuw/ander werk begonnen. In geautomatiseerde systemen zou je dit soort testen dus het liefst niet in de nacht of wekelijks willen doen, maar direct nadat de wijzigingen aan de hoofdcode zijn toegevoegd. Op die manier kunnen we bevindingen direct terugkoppelen, misschien zelfs via een Slack of Microsoft Teams Channel!

De ‘Long Feedback Loop’

Dit is feedback die we niet direct het team in gooien. Denk aan bevindingen uit ‘Gebruikers Acceptatie Testen’ of foutenmeldingen uit logfiles op productie. In dergelijke gevallen is meestal een vorm van onderzoek of triage nodig en om die reden meer geschikt voor ticket- of bugtracking systemen. En voor feedback waar snel op gehandeld moet worden, denk dan aan ‘emergency hotfixes’, e.d.? Daar kun je het beste een apart proces voor inrichten, want die moeten normaal gesproken zo snel mogelijk door het team opgepakt kunnen worden.rnrnIn deze loop vind je dus zaken als:rnu003culu003ern tu003cliu003eDe uitrol naar een productieomgeving (succesvol of niet, dat is ook feedback);u003c/liu003ern tu003cliu003eSignalen uit het testen in productie (A/B testing, Blue/Green, Canary Releases, etc.);u003c/liu003ern tu003cliu003eBeschikbaarheidstesten, waarbij downtime meestal zorgt voor zo’n eerdergenoemd ticket waarop snel gehandeld moet worden;u003c/liu003ern tu003cliu003eGebruikers Acceptatie Testen (User Acceptance Tests) ;u003c/liu003ern tu003cliu003eHandmatige testen door de business of eindgebruikers;u003c/liu003ern tu003cliu003eToegankelijkheidstesten (Accessibility).u003c/liu003ernu003c/ulu003e

De keten

Als we de drie feedback loops aan elkaar koppelen krijgen we een reeks aan stappen die bestaan uit de checks en validaties. Als we de stappen uit deze reeks willen automatiseren komen we in de meeste gevallen al snel uit bij een zogeheten “Continuous Integration / Continuous Deployment” pipeline.rnrnIn de meest eenvoudige vorm geeft CI/CD je controle over de voortbrenging van software door geautomatiseerde stappen. Continuous Integration is het mechanisme waarbij je het werk van individuele ontwikkelaars samenvoegt in de hoofdcode. Je zorgt er dus voor dat de losse wijzigingen goed samenwerken met elkaar én met het werk dat al eerder is gedaan. Continuous Deployment neemt deze wijzigingen zo vaak als nodig uit de hoofdcode en rolt deze direct uit op een (productie) omgeving. Om uit de hele keten de feedback te organiseren (en standaardiseren) kunnen we daarnaast gebruik maken van iets wat ‘Continuous Testing’ heet.

Continuous Testing

Laten we kijken naar een voorbeeld waarin het allemaal samenkomt. Het volgende diagram toont een CI/CD pipeline waarin een aantal van de checks en tests zitten die in dit artikel langs zijn gekomen. Hoewel het hier een versimpelde versie betreft van een echte pipeline (te weten van Amped, een Open Source project), zit er toch al aardig wat in. Het zal ook zeker niet op alle situaties van toepassing zijn, maar het toont wel hoe de drie typen feedback samenwerken om waardevolle terugkoppeling te verzamelen.

Omdat we, vooral bij de eerste twee feedback loops, zo min mogelijk tijd willen verliezen maken we in dergelijke pipelines in hoge mate gebruik van geautomatiseerde stappen. In dit getoonde diagram zit ook maar één handmatige stap (de ‘Code Review’) op de weg naar de productieomgeving! Deze methodiek kennen we als Continuous Testing, soms ook wel Agile Testing genoemd. Het beschrijft het proces van het uitvoeren van geautomatiseerde testen als onderdeel van de software delivery pipeline om feedback te krijgen op de risico’s van een bepaalde software release. Met andere woorden: wat zijn de (bedrijfs)risico’s van de software die je uitrolt op productie.rnrnDe naam is overigens verwarrend, want met Continuous Testing wordt niet bedoelt dat we de hele tijd testen… het betekent vooral dat we in elke fase van het software delivery proces testen hebben zitten die bepaalde risico’s in kaart brengen. Omdat wij toch terugkoppeling willen in elke fase van het proces is dit een mooie methodiek om onze drie feedback loops in onder te brengen!

Delen