...

Test je API met Specmatic 

Categorie: Software Engineering | Leestijd: 7 min. | Deel dit artikel

Schrijver: Max van Deursen, Software Engineer

Contract Testing voor providers; test je API met Specmatic
Als developer implementeer je een API op basis van een specificatie. Die specificatie is het contract tussen jou en je consumers. In mijn vorige blog gebruikte ik Specmatic om vanuit consumer-perspectief te testen of de integratie klopt, voordat de API live staat.

In deze blog kijk ik naar de andere kant van het contract: de provider. Dit is de applicatie die de API implementeert. Ik laat je zien hoe je met Specmatic toetst of jouw applicatie zich houdt aan dezelfde OpenAPI Specification (OAS) als de consumer. Niet om “tests toe te voegen”, maar om zeker te weten dat je API zich gedraagt zoals beloofd.

Het voorbeeld
Om Specmatic’s provider-tests te laten zien, gebruik ik opnieuw het voorbeeld van het winkelmandje van een webshop. Dezelfde casus als in de vorige blog. De API is vastgelegd in CartAPI_v1.yaml en bevat endpoints om een winkelmandje aan te maken, op te vragen en producten toe te voegen. In deze blog ben jij verantwoordelijk voor de backend van deze shop. Je implementeert als provider dus de API en de bijbehorende domeinlogica waar jouw consumers op vertrouwen.

Specmatic is programmeertaal agnostisch. Ik heb de API in dit voorbeeld uitgewerkt met DotNet, een veelgebruikte programmeertaal voor zo’n implementatie. Op GitHub heb ik de voorbeeldcode staan, zodat je zelf met Specmatic kan experimenteren.

De implementatie
Als provider schrijf je een webserver die de endpoints uit de OAS afhandelt. In dit voorbeeld gebeurt dat met ASP.NET Core. In de map Dignitas.Specmatic.Provider.API staat de implementatie:

  • De Services map bevat de kernlogica van de applicatie. De belangrijkste klasse is CartService.cs. Deze klasse implementeert de regels van het domein. Zo zorgt de CartService ervoor dat een product slechts een keer aan een winkelmandje kan worden toegevoegd en dat alleen bekende producten zijn toegestaan.
  • De CartController.cs vormt de koppeling tussen de CartService en de endpoints.
  • De Exceptions en Models  mappen bevatten respectievelijk fouttypes en datamodellen die door de rest van de applicatie worden gebruikt.

Draaien van applicatie en tests
Specmatic verifieert het contract door jouw draaiende applicatie aan te roepen en de reactie met de OAS te vergelijken. Hiervoor moet je applicatie dus lokaal beschikbaar zijn. Dit voorbeeld gebruikt hiervoor Docker, wat ook bij Specmatic zelf aansluit, dat ook in een container draait. Waar in de vorige blog Testcontainers werd gebruikt om Specmatic te configureren, gebruiken we dit keer Docker Compose.

Eerst geef je aan hoe Docker jouw applicatie kan bouwen en draaien. Dat gebeurt in het  Dockerfile bestand, waarin het Docker image wordt vastgelegd. Hierna kan je de applicatie en Specmatic configureren en koppelen. Dit staat in het bestand docker-compose.yaml.

De regels 2-7 configureren jouw applicatie en maken de poort 8080 beschikbaar. De regels 8-16 configureren de Specmatic test container. Hierin zorg je dat Specmatic bij de specmatic.yaml configuratie kan, de voorbeelden in examples/CartAPI_v1 beschikbaar zijn en dat Specmatic de URL naar de applicatie in de tests gebruikt: http://api:8080. De hostnaam api komt overeen met de servicenaam die op regel 2 staat aangegeven voor jouw applicatie.

Opzet van de tests
In de examples/CartAPI_v1 map staan verschillende voorbeelden die je API op specifieke manieren aanroepen. Specmatic voert deze aanroepen uit, vergelijkt de responses met de OAS en bepaalt op basis daarvan of een test slaagt.

Een voorbeeld van zo’n test is addItemToCart.conflict.json:

Deze test doet een POST-aanroep om het product aan het winkelmandje met ID toe te voegen. De verwachte uitkomst is een conflictsituatie, wat met de foutcode 409 (Conflict) staat aangegeven op regel 14. In het contract is vastgelegd dat een quantity verplicht is. In dit voorbeeld ontbreekt dat veld. Op het eerste gezicht voelt dat tegenstrijdig: hoe kan Specmatic dit voorbeeld toch accepteren?

De verklaring zit in het gebruik van Partial Examples. Dit is te herkennen aan het partial-attribuut op regel 2. Met partial examples hoef je alleen de velden te specificeren die relevant zijn voor het scenario dat je test. Ontbrekende velden vult Specmatic automatisch aan op basis van de OAS. Zo kan jij je focussen op de velden die voor de test belangrijk zijn. In dit geval draait de test om het feit dat een winkelmandje al een bepaald product bevat. Daarom zijn alleen het winkelmandje en het product expliciet vastgelegd op regel 5 en 10. De exacte hoeveelheid is hier niet relevant. Specmatic genereert daarvoor een geldige waarde volgens de specificatie.

Testdata en initialiseerstappen
Om de conflictsituatie te testen, moet je applicatie het winkelmandje met ID 0 bevatten waarin het product aanwezig is. Anders treedt de situatie simpelweg niet op. Deze data komt overeen met het voorbeeld. Maar hoe zorg je ervoor dat deze data in jouw applicatie staat?

In dit voorbeeld is dat specifieke winkelmandje vooraf aanwezig in de CartService.cs. Bij het testen van je eigen applicatie is dit een belangrijk aandachtspunt: denk bewust na over hoe je testdata initialiseert voordat je met Specmatic tests uitvoert.

Het resultaat van de tests
Nu kun je met Docker Compose met behulp van Specmatic jouw applicatie testen. Hiervoor gebruik je het volgende commando:

docker compose up –d –-build

Docker bouwt eerst het image van jouw applicatie en start deze. Zodra de API beschikbaar is, start de Specmatic container en voert alle tests uit. De Specmatic container schrijft tijdens het uitvoeren van de testen verschillende berichten op om de voortgang te rapporteren. Nadat de testen zijn uitgevoerd, stopt de Specmatic container en zie je in de berichten van de container een samenvatting van de resultaten:

Onderaan geeft Specmatic aan dat alle testen zijn geslaagd. Er zijn 24 tests succesvol uitgevoerd, terwijl de map examples/CartAPI_v1 maar 7 voorbeelden bevat. Waar komt dit verschil vandaan?

Gegenereerde tests
Specmatic maakt het je graag gemakkelijk. Waar partial examples je al werk uit handen nemen, kan Specmatic ook volledige testcases afleiden uit de specificatie.

In dit voorbeeld genereert Specmatic nog 17 tests aan de hand van de OAS. De docker-compose.yaml zorgt er op regel 14 voor dat Specmatic deze tests uitvoert, door de omgevingsvariabele SPECMATIC_GENERATIVE_TESTS op true te zetten. Deze gegenereerde tests controleren of jouw applicatie ook met ongeldige aanroepen kan omgaan. Denk hierbij aan verkeerde types, ontbrekende verplichte velden of onverwachte waarden.

Een voorbeeld van zo’n gegenereerde test staat in het HTML Report die Specmatic als resultaat meegeeft:

In deze test wordt voor het ID van het winkelmandje de waarde false meegestuurd. Dat is geen geldig nummer. De verwachte reactie is daarom een foutmelding. In de reactie ontvangt de test vanuit je applicatie een foutcode 400 (Bad Request) op. Hiermee geeft je applicatie aan dat de aanroep een fout bevat. Deze gegenereerde testen dekken veel randgevallen af en neemt Specmatic je waar mogelijk werk uit handen. Hierdoor kan jij je focussen of de testgevallen die niet alleen uit de OAS af te leiden zijn.

Wanneer gebruik je Specmatic bij providers?
Specmatic roept je applicatie aan en kijkt of deze volgens het contract reageert. Ook verifieert Specmatic dat jouw applicatie goed omgaat met ongeldige aanroepen. Deze tests kan Specmatic een groot deel zelf genereren. In complexere scenario’s voeg je zelf voorbeelden toe die Specmatic uitvoert. Vaak betekent dit dat je bewust testdata in je applicatie initialiseert om specifieke situaties te kunnen afdwingen.

Specmatic voert per test één aanroep uit. Als je voor een test scenario meer aanroepen nodig hebt of de opzet van data erg complex is, kan hier beter een andere testvorm voor gebruiken. Zorg in dit geval dat deze testvorm en Specmatic elkaar aanvullen. Zo kan je zorgen dat je applicatie volgens het contract communiceert en goed met complexe situaties overweg kan.

Wat rest ons nu?
Met de opzet van deze en de vorige blog kan je zowel consumer- als provider-tests uitvoeren op basis van dezelfde OAS met behulp van Specmatic. Hierdoor kunnen de consumer en provider uiteindelijk probleemloos met elkaar communiceren en integreren. De volgende vraag is waar die OAS leeft en hoe je deze veilig wijzigt zonder consumers of providers te breken. In het laatste deel van deze serie ga ik in op versiebeheer van de OAS en laat ik zien hoe Specmatic helpt bij het gecontroleerd doorvoeren van wijzigingen.

Overzicht blogreeks
19 augustus 2025 – Contract Testing: Integratieproblemen vroeg opgelost
20 oktober 2025 –
Contract Testing voor consumers: aan de slag met Specmatic’s Smart Mocks
23 december 2025 – Contract Testing voor providers; test je API met Specmatic
17 februari 2026 – Beheer van OpenAPI specificaties en veilig wijzigen met Specmatic

Deel dit artikel

Gerelateerde berichten