Trendsz, Test engineering, Testadvies, Testautomatisering, Tooling

In mijn vorige blog heb ik het uitgebreid gehad over de hoofdpijn die het testen op een end-to-end-omgeving mij bezorgd. Deze hoofdpijn wordt vooral veroorzaakt doordat we met end-to-end testen tightly coupled zijn. In dit deel van mijn blogreeks wil ik kijken naar hoe we onze hoofdpijn kunnen wegnemen. Kunnen we dit doen met contract-based testen?

Het verlaten van de end-to-end omgeving

Wanneer we van onze end-to-end omgeving afstappen, krijgen we een situatie zoals hieronder geïllustreerd. We draaien alle applicaties in hun eigen geïsoleerde omgeving. Onze applicaties verwachten dat de andere applicaties er zijn. Om dit op te vangen, maken we stubs om het gedrag van deze afhankelijkheden te simuleren.

Afbeelding1

In het begin zal het geweldig werken, maar na een aantal releases begint productie links en rechts om te vallen. We kunnen niet vertrouwen op onze testen om integratieregressie vast te stellen, aangezien onze applicaties niet meer gekoppeld zijn. Als een API-provider een breaking change maakt in een API waarvan we afhankelijk zijn, kunnen onze testen het probleem niet ondervangen. Dit gebeurt omdat er tijdens het testen geen coupling is tussen onze applicaties, en daar zal productie onder lijden.

Afbeelding2

Neem bijvoorbeeld een situatie waarin de provider update Amazing 1.5.0 uitbrengt terwijl onze stubs nog steeds werken volgens de specs van Amazing 1.4.0. Dit heet stub drift; de stubs zijn stilletjes afgedreven van de realiteit van de productie.

Afbeelding3

Het goede deel

De eerste keer dat je overschakelt van end-to-end testen naar deze manier van testen, voelt het geweldig. Je kunt plotseling veel sneller testen maken omdat je de volledige controle hebt over alle onderdelen van de test. Het uitvoeren van deze testen gaat ook sneller omdat alles lokaal draait. We praten ineens over milliseconden in plaats van seconden. Het is geweldig! En het allerbeste: geen hoofdpijn meer.

Tranen

Maar, zoals eerder vermeld, zal deze euforie niet lang duren.

Het eerste dat opvalt, is dat je niet alle bestaande testen op deze manier kunt reproduceren. Sommige testen zijn alleen nuttig wanneer gegevens door meerdere applicaties stromen. Aangezien je jouw testen nu geïsoleerd uitvoert, is dat onmogelijk. Sommige soorten testen kunnen per definitie niet in isolatie worden uitgevoerd. Je zult een aantal end-to-end testen moeten houden, maar er zijn er in ieder geval veel minder.

Na een tijdje beginnen de productieproblemen binnen te komen. Een andere applicatie heeft een nieuwe versie uitgebracht en dat heeft een deel van de API die je gebruikt kapot gemaakt. Het is een typefoutje van een ontwikkelaar. De testen van de API-providers hebben het niet opgevangen en jouw testen ook niet. Normaal gesproken had je dit ontdekt met de end-to-end testen, maar voor deze situatie bestaan die ​​niet meer. Jij en je team werken hard om het probleem direct op te lossen en het enige dat je productowner kan doen, is thee en pizza voor het avondeten halen. Jij bent ongelukkig, jouw team is ongelukkig en de eindgebruikers zijn ongelukkig.

Droog je tranen

Je kunt integratieregressie niet opvangen als je test zonder coupling tussen de API-provider en de consumer. Dit leidt tot valse positieven in jouw testen en dus tot productieproblemen. Er zijn meer manieren waarop volledige isolatie tegen je werkt. Maar om het kort te houden: een testpatroon met zo’n groot potentieel voor valse positieven, is geen geschikt patroon.

Laten we dus een manier zoeken om onze applicatie te testen die ons geen hoofdpijn bezorgt en ons niet laat huilen. Als we terugkijken op wat we tot nu toe hebben gezien, weten we dat we hoofdpijn krijgen als we tightly coupled zijn (end-to-end). En als we helemaal niet coupled zijn (volledige isolatie) eet het hele team pizza. Zoals bij veel dingen in het leven, ligt de oplossing ergens in het midden. Contract-based testen is zo’n oplossing.

"Zoals bij veel dingen in het leven, ligt de oplossing ergens in het midden. Contract-based testen is zo'n oplossing."

Contract-based testen

Bij contract-based testen koppelen we elke applicatie met één bestand: een contract. Op deze manier zijn onze applicaties wel coupled, maar lang niet zo strak als bij end-to-end testen.

Afbeelding4

Als je het je herinnert van deel 1; het contract is het gedeelde begrip van de interface tussen de provider en de consumer. Beide partijen kunnen dit gedeelde begrip gebruiken bij hun implementatie en testen. Dat doen ze terwijl ze ervoor zorgen dat de enige coupling via het contract is.

Omdat we enige coupling hebben, zullen we interfaceregressie opvangen in onze contracttesten. Ook houden we de aanzienlijke voordelen van geïsoleerd testen. Met name de onafhankelijkheid van andere teams leidt tot een veel snellere testcreatie.

Conclusie

We hebben meerdere manieren bekeken om volledige applicaties te testen. End-to-end testen zijn per definitie tightly coupled. Hierdoor zijn ze krachtig, maar ook tijdrovend. Wanneer we van onze end-to-end omgeving afstappen, merken we dat we plotseling volledig geïsoleerd zijn zonder enige coupling. Dit veroorzaakt veel problemen, waarvan de grootste leiden tot valse positieven in jouw testen.

Contract-based testen is een oplossing die resulteert in enige coupling, maar niet zo strak als bij end-to-end testen. Dit stelt ons in staat om veel van de nadelen van end-to-end testen te vermijden en tegelijkertijd de vele voordelen van geïsoleerd testen te behouden.

In deel 4 van mijn blogreeks bespreek ik hoe contract-based testen werkt, de benaderingen, de sterke en de zwakke punten. En ik zal het niet meer hebben over hoofdpijn, tranen of pizza. Beloofd.

Met dank aan Vilas Pultoo voor de illustraties

Schrijf je in voor
de nieuwsbrief

werkenbij overall

Werken bij Bartosz?

Vincent Verhelst

Geïnteresseerd in Bartosz? Dan ga ik graag met jou in gesprek. We kunnen elkaar ontmoeten met een kop koffie bij ons op kantoor. Of tijdens ontbijt, lunch, borrel of diner op een plek die jou het beste uitkomt. Jij mag het zeggen.

Mijn Paarsz