API-schema-afwijkingen vinden voor tests ze missen
Een test die de statuscode en een paar velden controleert, blijft slagen wanneer de API een veld toevoegt, een niet-gecontroleerd veld verwijdert of een getal omzet in een tekenreeks. Nexus Studio slaat de structuur van elke API-respons op, met veldnamen en typen maar nooit waarden, vergelijkt die met de vorige uitvoering en meldt API_DRIFTED wanneer die verandert. Met NEXUS_API_DRIFT_STRICT=true laat dezelfde wijziging de testsuite mislukken.
Door het Nexus Studio-team, Verdict System LLC. 27 oktober 2026.
Wat is API-schemadrift?
Schemadrift is een verandering in de structuur van een respons tussen uitvoeringen: een toegevoegd veld, een verwijderd veld of een veld waarvan het type is gewijzigd. Een API mag zich ontwikkelen. Het probleem ontstaat wanneer de afnemers dat pas in productie ontdekken, omdat niets in de testsuite aangaf dat er iets was veranderd.
Waarom mist een geslaagde contracttest dit?
Omdat die alleen controleert waar de auteur aan heeft gedacht. Een regel zoals validate(res, { status: 200, hasFields: ['id'] }) blijft slagen wanneer price van een getal in een tekenreeks verandert, omdat price niet in de regel staat. De client die prijzen optelt, is degene die vastloopt.
Kan ik dit zien gebeuren met een uitvoerbaar voorbeeld?
Sla dit op als server.mjs. Het beantwoordt verzoeken aan één eindpunt en de variabele SHAPE bepaalt wat het eindpunt teruggeeft: een prijs als getal of een prijs als tekenreeks met een nieuw veld currency.
import http from 'node:http';
// SHAPE=v1 answers {id, price: 9.99}; SHAPE=v2 answers {id, price: "9.99", currency: "USD"}.
const v2 = process.env.SHAPE === 'v2';
http.createServer((req, res) => {
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(v2 ? { id: 7, price: '9.99', currency: 'USD' } : { id: 7, price: 9.99 }));
}).listen(4010, '127.0.0.1');
Sla deze API-test op als APIT900_drift_demo.api.js in de map api-tests/rest van je werkruimte. De test controleert de status en één veld, net als veel echte testsuites.
// type: rest
import { runApiSuite } from '../../utils/base-api-fixture.js';
await runApiSuite([{
id: 'APIT900-1',
name: 'GET /product/7 returns 200 with an id',
fn: async ({ request, validate }) => {
const res = await request({ method: 'GET', url: '/product/7' });
validate(res, { status: 200, hasFields: ['id'] });
},
}]);
Start de server in één PowerShell-venster en voer de test uit in een ander venster. Bij de eerste uitvoering is er niets om mee te vergelijken, dus wordt de structuur vastgelegd en slaagt de test.
$env:SHAPE = "v1"; node server.mjs
$env:API_BASE_URL = "http://127.0.0.1:4010"; nexus api APIT900 --no-app
Stop de server, start die opnieuw met $env:SHAPE = "v2" en voer dezelfde test uit. De test slaagt nog steeds, maar de uitvoering is niet langer API_SECURE. Dit is de uitvoer, ingekort tot de relevante regels:
schema drift: +1 field, 1 type change
+ currency
~ price: number → string
API_DRIFTED 7ms
1/1 passed
1 endpoint changed shape since the last run, set NEXUS_API_DRIFT_STRICT=true to fail the suite on it
Kan drift de build laten mislukken?
Ja, als je dat instelt. Standaard telt API_DRIFTED als geslaagd en eindigt de uitvoering met afsluitcode 0, omdat een veranderende API informatie is en geen fout. De melding staat op een eigen regel en wordt samen met het verschil vastgelegd in het bewijsmateriaal van de uitvoering, zodat het resultaat nooit als onvoorwaardelijk geslaagd wordt opgevat. Stel NEXUS_API_DRIFT_STRICT=true in en dezelfde wijziging levert afsluitcode 1 op. Om dit te zien, voer je de test met die variabele ingesteld eenmaal uit tegen v1 en eenmaal tegen v2.
De referentie is altijd de vorige uitvoering. Na een uitvoering met drift wordt de nieuwe structuur de referentie, zodat de volgende uitvoering met dezelfde respons geen drift meldt.
Wat zijn de beperkingen?
- De eerste uitvoering van een test legt alleen een structuur vast. Er is nog geen referentie om van af te wijken.
- De structuur bestaat uit namen en typen, niet uit betekenis. Als
priceeen getal blijft maar van dollars naar centen verandert, verandert er niets aan de structuur. - De vergelijking is met de vorige uitvoering, niet met een overeengekomen contract. Je ziet dat er iets is veranderd, niet of de wijziging was toegestaan.
- Elke testcase bewaart één structuur, afkomstig uit de berichtinhoud van het laatste verzoek. Een lijst wordt beschreven aan de hand van het eerste element, een object aan de hand van maximaal 200 sleutels en de nesting stopt na zes niveaus.
Waar kan ik het zien?
De gids voor testoordelen behandelt de testoordelen en de pagina Bewijsmateriaal vermeldt welke bestanden een uitvoering op je schijf achterlaat. De proefversie van 30 dagen gebruikt dezelfde engine voor je eigen API-tests.