Inventory: stan magazynu, historia zmian i właściwy poziom testów
Co oznacza dostępna ilość?
Inventory odpowiada na pytanie, ile sztuk produktu można jeszcze sprzedać.
W analizowanej aplikacji availableQuantity jest tym samym stanem, który produkt
udostępnia jako stockQuantity. Koszyk nie jest rezerwacją: dwie osoby mogą
umieścić tę samą ostatnią sztukę w swoich koszykach. Ostateczne sprawdzenie
odbywa się podczas tworzenia zamówienia, a backend musi wtedy zapobiec sprzedaży
większej liczby sztuk niż dostępna.
Zapas jest zmniejszany już dla nowego zamówienia PENDING, przed płatnością. Anulowanie zamówienia w dozwolonym stanie przywraca ilość. Dlatego testy powinny posługiwać się nowymi produktami i zamówieniami, a cleanup powinien uwzględniać zmianę zapasu, zamiast jedynie usuwać konta użytkowników.
Korekta jest różnicą, a requestId chroni przed powtórzeniem
Dla stanu 5 żądanie z delta: 3 oznacza wynik 8, a nie ustawienie ilości na 3.
Ujemna delta usuwa sztuki. Próba zejścia poniżej zera jest konfliktem biznesowym,
a nie poprawną korektą do ujemnego magazynu.
Wyobraź sobie, że backend zapisał korektę, ale klient nie odebrał odpowiedzi. Klient nie wie, czy ponowienie jest bezpieczne. Idempotencyjny requestId pozwala ponowić to samo żądanie dla produktu bez drugiego zapisu. Przy ponowieniu trzeba zachować także delta i reason. Nowa operacja biznesowa powinna dostać nowy UUID.
Dobry test nie kończy się na kodzie 201. Sprawdza, czy ponowienie zwróciło tę samą zmianę, zapas wzrósł tylko raz, a historia nie zawiera duplikatu. W tej aplikacji identyczne ponowienie także zwraca 201, mimo że nowy rekord nie powstał.
Historia daje drugi sposób sprawdzenia skutku
Zmiana zapasu ma ślad w historii: INITIAL_STOCK, ADMIN_ADJUSTMENT, ORDER_DEDUCTED lub ORDER_RESTORED. Pola delta i quantityAfter opisują wpływ zmiany, a orderId łączy zdarzenie z zamówieniem. Historia jest zwracana od najnowszych wpisów.
Kontrola stanu oraz historii daje więcej niż odczyt pojedynczego komunikatu. Dla odrzuconej korekty biznesowej warto potwierdzić zarówno niezmienioną ilość, jak i brak dodatkowego ruchu magazynowego. Używaj własnych danych, aby obcy test lub użytkownik nie zmienił obserwowanego produktu między żądaniami.
Co testować przez API, a co w backendzie?
Zdalne testy API pokazują, czy faktycznie wdrożone komponenty współpracują: autoryzacja przepuszcza administratora, zapis trafia do bazy, historia odpowiada stanowi, a zamówienie poprawnie zmniejsza i przywraca zapas. Te przepływy warto zachować nawet wtedy, gdy ich poszczególne reguły mają testy jednostkowe.
Szczegółowe kombinacje długości tekstu, brakujących pól, granic liczbowych i parametrów paginacji zwykle taniej sprawdzić w backendzie. Jeden reprezentatywny 400 na poziomie API potwierdza jednak, że walidacja jest podłączona do kontrolera i mapowana na odpowiedź HTTP. Nie trzeba wybierać między wszystkimi walidacjami a całkowitym pominięciem błędnego wejścia.
Przeniesienie odpowiedzialności wymaga dowodu. W tej sesji znaleziono backendowe testy granic zapasu, retry, przywracania i konkurencji. Nie znaleziono natomiast każdego szczegółowego testu DTO. Usunięte przypadki oznaczono więc częściowo jako zalecane uzupełnienia backendu. Adnotacja NotBlank ani instrukcja if w serwisie nie są testem i nie zastępują kontroli pokrycia.
Czytelność kodu generowanego przez agenta
Dla kursowego zestawu ważna jest możliwość przeczytania pojedynczego testu bez przeskakiwania między fabryką przypadków i helperami. Przy niewielkiej liczbie scenariuszy jawne testy są rozsądnym wyborem, nawet jeśli powtarzają kilka linii:
// when
const response = await inventoryClient.getItem(productId, adminToken);
// then
expect(response.status()).toBe(200);
expectJsonResponse(response);
expectNoStoreCaching(response);
const body = (await response.json()) as InventoryItemResponse;
expect(body.availableQuantity).toBe(5);
Przykład pokazuje wzorzec asercji; productId, adminToken i klient pochodzą z przygotowania testu. Parametryzacja nie jest z definicji błędem, ale powinna zmniejszać koszt czytania i utrzymania. Zielony wynik wszystkich przypadków nie uzasadnia sam w sobie wprowadzenia odmiennego stylu do jednego katalogu.
Jak korzystać z materiałów?
Rzeczywista sesja Codex zawiera trzy oryginalne prompty oraz wyniki przed i po review. Raport kontraktu opisuje brakujące odpowiedzi Swaggera i kroki odtworzenia.
Sesja była realizowana w ait2api1-api-ai/l19. Rozwiązanie znajduje się w ait2api1-api-ai/l20,
a ait2api1-api-ai/l19 zachowuje stan początkowy ze 170 testami. Katalogi są niezależne: zainstaluj
zależności, skonfiguruj własne zmienne według .env.example, a następnie uruchom
najpierw testy zmienianego endpointa i dopiero po ich sukcesie pełny zestaw.
Pełna konfiguracja znajduje się w README checkpointu.
W finalnym zestawie są 20 testów inventory i 190 testów łącznie. Wszystkie cztery
operacje mają pokrycie sukcesu i uprawnień, ale nie oznacza to kompletnego
pokrycia każdej reguły biznesowej. Wartości pokrycia należy zawsze czytać razem
z audytem api-test-plan.md.
