Jak wykryć zmiany schematu API, zanim umkną moim testom?
Test sprawdzający kod statusu i kilka pól nadal przechodzi, gdy API dodaje pole, usuwa takie, którego test nie sprawdza, lub zamienia liczbę na ciąg znaków. Nexus Studio zapisuje strukturę każdej odpowiedzi API, nazwy i typy pól, ale nigdy ich wartości, porównuje ją z poprzednim uruchomieniem i zgłasza API_DRIFTED, gdy się zmieni. Przy ustawieniu NEXUS_API_DRIFT_STRICT=true ta sama zmiana powoduje niepowodzenie zestawu testów.
Autorzy: zespół Nexus Studio, Verdict System LLC. 27 października 2026.
Czym jest dryf schematu API?
Dryf schematu to zmiana struktury odpowiedzi między uruchomieniami: dodanie pola, usunięcie pola lub zmiana jego typu. API może ewoluować. Problem pojawia się wtedy, gdy korzystające z niego aplikacje dowiadują się o tym dopiero na produkcji, bo żaden test w zestawie nie zasygnalizował zmiany.
Dlaczego test kontraktowy przechodzi mimo takiej zmiany?
Ponieważ sprawdza tylko to, co przewidział jego autor. Reguła taka jak validate(res, { status: 200, hasFields: ['id'] }) nadal przechodzi, gdy price zmienia się z liczby w ciąg znaków, ponieważ price nie jest objęte regułą. Awarii ulega dopiero aplikacja kliencka sumująca ceny.
Czy mogę zobaczyć to na przykładzie, który da się uruchomić?
Zapisz ten kod jako server.mjs. Obsługuje on jeden punkt końcowy, a zmienna SHAPE określa, co ten punkt zwraca: cenę jako liczbę lub cenę jako ciąg znaków z nowym polem 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');
Zapisz ten test API jako APIT900_drift_demo.api.js w folderze api-tests/rest swojego obszaru roboczego. Sprawdza on status i jedno pole, podobnie jak wiele rzeczywistych zestawów testów.
// 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'] });
},
}]);
Uruchom serwer w jednym oknie PowerShell, a test w drugim. Przy pierwszym uruchomieniu nie ma z czym porównywać, więc test zapisuje strukturę i przechodzi.
$env:SHAPE = "v1"; node server.mjs
$env:API_BASE_URL = "http://127.0.0.1:4010"; nexus api APIT900 --no-app
Zatrzymaj serwer, uruchom go ponownie z ustawieniem $env:SHAPE = "v2" i uruchom ten sam test. Nadal przechodzi, ale uruchomienie nie ma już statusu API_SECURE. Oto wynik skrócony do istotnych wierszy:
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
Czy dryf może spowodować niepowodzenie kompilacji?
Tak, jeśli tak ustawisz. Domyślnie API_DRIFTED oznacza zaliczenie testu i zakończenie z kodem 0, ponieważ zmiana API jest informacją, a nie usterką. Komunikat jest wyświetlany w osobnym wierszu i zapisywany wraz z różnicą w materiale dowodowym z uruchomienia, więc wynik nigdy nie jest przedstawiany jako zaliczenie bez zastrzeżeń. Ustaw NEXUS_API_DRIFT_STRICT=true, a ta sama zmiana spowoduje zakończenie z kodem 1. Aby to zobaczyć, uruchom test raz dla v1 i raz dla v2 z ustawioną tą zmienną.
Punktem odniesienia jest zawsze poprzednie uruchomienie. Po uruchomieniu, które wykryło dryf, nowa struktura staje się punktem odniesienia, więc kolejne uruchomienie dla tej samej odpowiedzi nie zgłasza dryfu.
Jakie są ograniczenia?
- Pierwsze uruchomienie testu jedynie zapisuje strukturę. Nie ma jeszcze punktu odniesienia do wykrywania dryfu.
- Struktura obejmuje nazwy i typy, a nie znaczenie. Jeśli
pricepozostaje liczbą, ale zmienia się z dolarów na centy, nie zostanie wykryta żadna zmiana. - Porównanie dotyczy poprzedniego uruchomienia, a nie uzgodnionego kontraktu. Informuje o tym, że coś się zmieniło, a nie o tym, czy zmiana była dozwolona.
- Każdy przypadek testowy przechowuje jedną strukturę, pobraną z treści ostatniego żądania. Lista jest opisywana na podstawie pierwszego elementu, obiekt na podstawie maksymalnie 200 kluczy, a zagnieżdżenie jest uwzględniane do sześciu poziomów.
Gdzie mogę to zobaczyć?
Przewodnik po werdyktach omawia werdykty testów, a strona materiałów dowodowych wymienia pliki pozostawiane na dysku po uruchomieniu. 30-dniowa wersja próbna pozwala używać tego samego silnika do własnych testów API.