Plan de testare preproducție pentru un API de contabilitate
Un manual de fiabilitate pentru echipele de inginerie: scrieri duplicate, reutilizarea idempotenței, semnături pentru webhook-uri, evenimente în ordine inversă, sume zecimale, permisiuni (scopes), blocări de perioadă și recuperare.
Un răspuns 201 Created din partea unui API de contabilitate nu spune aproape nimic. El confirmă doar că serverul a răspuns. Nu confirmă însă că există exact o singură factură, că debitul este egal cu creditul, că numărul de document a fost alocat o singură dată sau că o reîncercare (retry) după o conexiune întreruptă nu va înregistra o a doua copie. Cele mai multe duplicate contabile în producție provin din această discrepanță: o mutație care s-a comis pe server în timp ce clientul a rămas cu un rezultat necunoscut și a reîncercat silențios cu o cheie nouă.
Acest plan se adresează echipelor care evaluează un API de contabilitate înainte de a-l integra în registrele contabile reale. Planul se concentrează pe comportamentul în caz de eșec, nu pe scenariile ideale (happy paths). Fiecare secțiune de mai jos descrie ce trebuie testat, ce trebuie asigurat prin aserțiuni și ce anume reprezintă trecerea cu succes a testului. Contextul de implementare de aici este Nordlet, al cărui API utilizează chei purtătoare cu permisiuni (scoped bearer keys), sume sub formă de șiruri zecimale (decimal-string amounts), chei de idempotență și webhook-uri semnate. Pentru sintaxa exactă a endpoint-urilor și contractele de răspuns, consultați paginile Convenții API și Noțiuni de bază în loc să vă bazați pe presupuneri.
Ce înseamnă cu adevărat „succesul” unui test
Un test dovedește că o integrare contabilă este sigură doar atunci când verifică semantica, nu codurile de stare. Pentru fiecare scenariu, suita de teste trebuie să confirme că:
- Efectul secundar debusiness: există exact un singur client, o singură factură, o singură înregistrare în jurnal, o singură alocare de număr sau o singură tranziție de plată.
- Integritatea contabilă: debitele sunt egale cu creditele, iar precizia monetară supraviețuiește serializării.
- Comportamentul de repriză (replay): o reîncercare returnează rezultatul original în loc să creeze o nouă înregistrare.
- Durabilitatea: înregistrările de audit și evenimentele webhook există imediat ce operațiunea a fost comisă.
- Eșecuri fără efecte secundare: cererile respinse nu consumă numere de document și nu scriu linii parțiale în registrul contabil.
- Recuperarea: o eroare tranzitorie poate fi reîncercată fără duplicare sau pierdere permanentă.
Ghidul API al Google trasează o linie clară: doar operațiunile a căror execuție repetată lasă aceeași stare finală sunt sigure pentru reîncercare, iar un API trebuie să indice care operațiuni sunt idempotente, în loc să reîncerce orbește orice eșec.
Configurarea unui mediu de test izolat și observabil
Folosiți o companie sandbox, nu registrele reale din producție. O companie sandbox în Nordlet folosește aceleași module și comportamente API ca o companie reală și este marcată drept date de test, ceea ce o face sigură pentru teste de volum ridicat cu duplicate și erori. Acest marcaj este imutabil după creare, astfel încât registrele reale nu pot fi reclasificate ulterior drept date de test. Rețineți că utilizarea sandbox-ului este contorizată și facturată exact la fel ca utilizarea într-o companie reală, așa că dimensionați testele de volum în funcție de planul de prețuri pe care vă aflați.
Înainte de a scrie orice test, pregătiți:
- O companie sandbox dedicată, cu
isSandbox: true. - O cheie API de test restricționată doar la modulele supuse testării.
- Un endpoint webhook sau un tunel local care păstrează corpul brut al cererii (raw request body).
- Clienți și furnizori preinserați și un plan de conturi cunoscut.
- Cel puțin două perioade contabile: una deschisă și una blocată.
- Un ceas de test (test clock) sau un set de date fixe (date fixture), dacă implementarea acceptă acest lucru.
- O bază de date locală care înregistrează fiecare încercare de cerere, cheie de idempotență, amprentă (hash) de răspuns, livrare de webhook și rezultat de reconciliere.
Nu rulați teste de duplicate pe date de staging partajate. Un client sau o factură rătăcită dintr-o rulare anterioară va face ca aserțiunile ulterioare să fie ambigue.
Macheta (fixture) pentru fiecare mutație trebuie să surprindă metoda, endpoint-ul, corpul complet, cheia de idempotență, domeniul cheii (scope), un ID de corelație al clientului, marcajele de timp pentru începere și finalizare, starea răspunsului, anteturile (headers), corpul, ID-ul cererii și dacă conexiunea s-a întrerupt înainte ca răspunsul să sosească. Folosiți șiruri zecimale fixe, cum ar fi "75.0000", pentru sume. Nordlet reprezintă valorile monetare ca șiruri zecimale cu până la patru zecimale, iar factura sa exemplificativă folosește acest format.
Cealaltă componentă a configurării este injectarea de erori. Setul de instrumente (harness) ar trebui să poată întârzia un răspuns, să închidă o conexiune TCP după ce serverul a primit cererea, să returneze răspunsuri sintetice de tip 429/500/502/503/504, să returneze un cod diferit de 2xx din receptorul de webhook, să livreze același webhook de două ori, să reordoneze evenimentele, să corupă un singur octet dintr-un corp de webhook, să modifice payload-ul unei chei de idempotență păstrând însă cheia, să ruleze simultan două cereri identice și să blocheze o perioadă între configurare și înregistrare (posting). Aceste scenarii valorează mai mult decât o sută de exemple de cazuri ideale.
Blocarea contractului înainte de a scrie logica de reîncercare
Generați sau preluați schema OpenAPI și comparați-o cu clientul dumneavoastră. Nordlet își publică specificația OpenAPI în referința API și își generează SDK-urile tipizate pe baza aceleiași specificații, așa că testele bazate pe schemă sunt superioare presupunerilor scrise de mână.
Verificați câmpurile și tipurile obligatorii, câmpurile de tip șir zecimal, formatele pentru date și marcaje de timp (timestamps), acțiunile și permisiunile permise, structura plicului de eroare, schemele evenimentelor webhook, ce mutații acceptă o cheie de idempotență și ce câmpuri de răspuns identifică obiectul creat.
Criterii de trecere. Clientul respinge local payload-urile invalide pe care schema nu le permite. Răspunsurile serverului corespund schemei documentate. Zecimalele invalide, datele calendaristice incorecte și câmpurile obligatorii lipsă generează erori de validare structurate. Nu se încearcă nicio reîncercare pentru un eșec de validare determinist.
Mod de eșec de detectat. Un client parsează "121.0000" într-un număr virgulă mobilă binar (binary float) și serializa ulterior o sumă ușor diferită. Numerele întregi trec testul, dar liniile de TVA și cantitățile fracționare eșuează. Testați sumele monetare ca șiruri de caractere de la un capăt la celălalt (end to end).
Autorizare și izolare între chiriași (tenant isolation)
Folosiți chei separate pentru citire și scriere. Apoi testați întreaga matrice: cheie lipsă, cheie invalidă, cheie validă cu permisiuni insuficiente pentru modul, cheie validă cu permisiunile corecte, o cheie aparținând altei companii și o încercare de a citi un obiect dintr-o altă companie.
Aserțiuni:
- Credențialele lipsă sau invalide returnează
401. - O cheie validă fără permisiunea necesară returnează
403. - Nu se creează niciun efect secundar contabil pentru niciunul dintre eșecuri.
- O cerere reușită nu poate citi sau modifica înregistrările altei companii.
- Eșecurile de securitate nu sunt niciodată reîncercate automat.
Criteriu de trecere. Puteți demonstra atât corectitudinea autorizării, cât și izolarea între chiriași prin citiri efectuate după test, nu doar prin codurile de stare.
Validarea unei tranzacții curate
Rulați un flux mic și determinist: creați sau găsiți un client de test, creați o factură cu sume reprezentate ca șiruri zecimale, emiteți-o, citiți factura și efectul său contabil, citiți înregistrarea de audit și recepționați webhook-ul. Exemplul de pornire din Nordlet arată cum emiterea unei facturi alocă un număr secvențial fără întreruperi, verifică dacă perioada este deschisă și înregistrează o notă contabilă (journal entry) echilibrată în aceeași tranzacție.
Asigurați-va prin aserțiuni că factura ajunge în starea așteptată, numărul de document este alocat exact o dată, debitele sunt egale cu creditele, TVA-ul și totalurile liniilor corespund calculului așteptat prin rotunjire la jumătate în sus (half-up calculation), înregistrarea de audit menționează actorul și modificarea, webhook-ul este livrat în cele din urmă, iar răspunsul API și o citire ulterioară sunt de acord cu ID-ul și starea facturii.
O distincție pe care merită să o rețineți: sosirea unui webhook nu este o dovadă că mutația a fost comisă. Răspunsul API împreună cu o citire ulterioară reprezintă aserțiunile dumneavoastră principale pentru tranzacție. Webhook-ul dovedește notificarea în aval și este testat separat.
Idemotența: aceeași cheie, același corp
Generați o singură cheie per operațiune de business logică, nu o singură cheie per încercare de rețea. Trimiteți mutația cu cheia K și corpul B, salvați ID-ul creat, apoi trimiteți din nou exact aceeași cerere.
Asigurați-va prin aserțiuni că al doilea răspuns reprezintă aceeași operațiune, ID-ul obiectului este identic și că există un singur obiect de business, o singură înregistrare contabilă, un singur numér de document și un singur efect financiar. Răspunsul repetat trebuie să conțină antetul de repriză documentat – x-idempotent-replay: true în cazul Nordlet – iar istoricul de audit nu trebuie să indice nicio a doua mutație.
Două reguli de stocare modifică ceea ce ar trebui să se aștepte bucla de reîncercare, așa că testați-le direct: un cod 4xx stocat este reîntors (replayed) ca orice alt răspuns, în timp ce un cod 5xx nu este stocat deloc, astfel încât o reîncercare după o eroare de server reexecută operațiunea în loc să o redea din cache. De asemenea, cheile expiră (în Nordlet după 24 de ore), ceea ce limitează perioada în care o repriză este disponibilă.
Documentația Nordlet promite că adăugarea unui antet Idempotency-Key împiedică o cerere reîncercată să creeze duplicate, iar convențiile sale API definesc antetul exact de repriză și cerința de răspuns identic octet cu octet. Principiul se potrivește cu modelul publicat de Stripe: o cheie identifică operațiunea logică, repetările returnează rezultatul stocat, iar o cheie reutilizată cu parametri diferiți este respinsă în loc să fie modificată silențios.
Criteriu de trecere. Există exact o singură tranziție a stării financiare, indiferent de câte ori clientul trimite aceeași cerere în fereastra de repriză.
Idemotența: aceeași cheie, corp modificat
Trimiteți cererea originală cu cheia K și corpul B1, apoi o a doua cerere cu cheia K și corpul B2, unde cel puțin o sumă, un client, o dată sau o linie diferă.
Rezultatul aşteptat: cererea este respinsă cu eroarea documentată de reutilizare a cheii – Nordlet returnează 422 idempotency_key_reuse – înregistrarea originală rămâne neatinsă, nu apare nicio a doua înregistrare, niciun număr nou și nicio modificare de audit, iar clientul nu „repară” situația generând o cheie nouă. Acceptarea silențioasă a corpului B2 ar face ca cheile de reîncercare să fie nesigure.
Cereri duplicate concurente
Lansați simultan două cereri identice cu aceeași cheie. În funcție de comportamentul documentat, una se execută în timp ce cealaltă primește un conflict de tip în curs de desfășurare – Nordlet returnează 409 idempotency_in_progress – sau ambele observă în cele din urmă același rezultat.
Asigurați-va prin aserțiuni că ambele apeluri nu pot crea efecte financiare independente, că se alocă cel mult un număr de document, că un conflict temporar este reîncercat cu aceeași cheie în loc de una nouă, că resursa finală este completă și citibilă și că înregistrarea de idempotență nu rămâne blocată permanent.
Mod de eșec. O bibliotecă de reîncercare care generează un UUID nou la fiecare încercare transformă o singură operațiune logică în mai multe scrieri independente și anulează complet idempotența.
Rezultatul incert după o conexiune întreruptă
Aceasta este cea mai importantă simulare de producție. Trimiteți o mutație cu cheia K, lăsați serverul să o înregistreze (commit), întrerupeți conexiunea înainte ca răspunsul să sosească, marcați rezultatul ca necunoscut, apoi reîncercați cu aceeași cheie K și reconciliați citind resursa și datele de audit.
Asigurați-va prin aserțiuni că reîncercarea returnează răspunsul original sau cel de repriză documentat, că există exact un singur efect secundar financiar, că clientul marchează operațiunea ca fiind completă doar după o repriză reușită sau o citire de reconciliere și că nu este generată nicio cheie nouă. O expirare a timpului de așteptare (timeout) nu înseamnă că „nu s-a întâmplat nimic”. Stripe descrie idempotența tocmai ca o protecție împotriva erorilor de conexiune în care serverul ar fi putut procesa o mutație înainte ca clientul să poată primi răspunsul.
O politică conservatoare de reîncercare
Deciziile de reîncercare depind atât de eroare, cât și de faptul că operațiunea este idempotentă, nu doar de metoda HTTP în sine.
De regulă reîncercabile, cu păstrarea aceleiași chei: resetarea conexiunii sau expirarea timpului de așteptare (timeout) după o mutație idempotentă, 408, 429 după respectarea duratei din retry-after, precum și 502/503/504. Un răspuns de idempotență în curs de desfășurare documentat poate fi reîncercat după o scurtă întârziere.
Nereîncercabile fără reconciliere: erori de validare 400/422, eșecuri de autentificare 401/403, 404 pentru o resursă lipsă, conflicte de business 409 care nu au legătură cu o cheie în curs de execuție, un payload modificat pentru o cheie existentă și o respingere din cauza perioadei blocate.
Asigurați-va prin aserțiuni aplicarea unui backoff exponențial delimitat cu factor de aleatoriu (jitter), număr maxim explicit de încercări și timp scurs, respectarea antetului retry-after pentru limitele de rată (rate limits), păstrarea aceleiași chei la reîncercările aceleiași operațiuni, utilizarea unei chei noi pentru fiecare operațiune nouă și jurnale (logs) care separă încercarea originală de reîncercări.
Testați limitarea ratei (rate limiting) separat. Depășiți pragul documentat – Nordlet permite în mod implicit 300 de cereri pe minut per cheie API, iar unele endpoint-uri neautentificate au limite proprii mai scăzute per adresă – apoi confirmați că serverul returnează răspunsul de limitare a ratei, că clientul parsează retry-after ca pe o întârziere și nu ca pe o eroare, că acesta ia o pauză în loc să bombardeze serverul și că o reîncercare a mutației limitate reutilizează cheia originală. Anteturile x-ratelimit-* raportează bugetul rămas, ceea ce constituie o bună pre-aserțiune. Păstrați teste de limitare a ratei la distanță de aserțiunile financiare, cu excepția cazului în care setul de date poate distinge o încercare limitată de una comisă efectiv.
Verificarea semnăturii webhook-urilor
Construiți un receptor care păstrează octeții bruți. Pentru fiecare eveniment: capturați corpul brut, citiți antetul x-nordlet-signature, calculați valoarea HMAC-SHA256 aşteptată folosind secretul abonamentului, comparați utilizând o funcție cu timp constant, parsați JSON-ul doar după verificare, înregistrați livrarea și returnați rapid un cod 2xx după acceptarea durabilă. Nordlet semnează un cod HMAC aplicat corpului brut, îl trimite sub forma sha256=<hex> și reîncearcă livrările cu backoff exponențial. Ghidul de webhook-uri al Stripe subliniază importanța verificării corpului brut nemodificat printr-o comparație cu timp constant.
Rulați teste negative: corp și secret corecte, corp corect cu secret greșit, o modificare de un octet în corp, JSON reserializat cu spații albe alterate, un antet lipsă, o semnătură malformată, o livrare veche repetată dacă schema include o marcă temporală și o semnătură validă livrată la un abonament greșit.
Criterii de trecere. Doar corpul brut și secretul corecte sunt acceptate. Semnăturile invalide primesc un cod diferit de 2xx. Payload-urile invalide nu intră niciodată în coada contabilă. Secretele rămân în afara jurnalelor obișnuite. Handlerul confirmă primirea doar după ce evenimentul este înregistrat în mod durabil.
Webhook-uri duplicate și livrate în ordine inversă
Fiabilitatea livrării este o problemă separată de idempotența API, iar receptorul trebuie să fie la rândul său idempotent. Livrați același eveniment de două ori, livrați un eveniment sale_invoice.paid înainte de un eveniment sale_invoice.issued, returnați un cod 500 după persistență dar înainte de răspuns și retransmiteți un eveniment pe care consumatorul l-a procesat deja.
Asigurați-va prin aserțiuni că livrările duplicate nu duplică plățile, modificările de stare sau acțiunile din jurnal, că cheia de deduplicare folosește ID-ul de livrare sau de eveniment al furnizorului atunci când acesta există (sau o cheie compusă documentată, niciodată o marcă temporală arbitrară), că evenimentele primite în ordine inversă nu suprascriu niciodată o stare mai nouă cu una mai veche, că consumatorul poate prelua starea actuală din API atunci când ordinea este insuficientă și că încercările eșuate ale consumatorului sunt rutate printr-o coadă sau o rută de mesaje nereușite (dead-letter). Stripe avertizează în mod explicit că ordinea livrării nu este garantată și recomandă stocarea ID-urilor de evenimente procesate.
Mențineți endpoint-ul simplu: validați structura, verificați semnătura, salvați sau adăugați în coadă, confirmați primirea, returnați 2xx. Reconcilierea și notificările aparțin procesării asincrone. Testați acest lucru punând operațiunea din aval să aștepte (sleep) dincolo de timpul de expirare al livrării; un receptor corect confirmă în continuare primirea după ce a plasat mesajul într-o coadă durabilă.
Perioade contabile deschise și blocate
Nordlet aplică blocări de perioadă în momentul înregistrării (posting) în jurnalele manuale, fluxurile de documente și importuri, așa că testați acest control în mai multe locuri. Creați documente echivalente datate într-o perioadă deschisă, într-o perioadă blocată, la limită chiar înainte de blocare, în prima zi a perioadei deschise următoare și cu o dată de document validă dar o dată de înregistrare invalidă, dacă API-ul le separă pe cele două.
Pentru cazul perioadei blocate, asigurați-va prin aserțiuni că cererea este respinsă cu eroarea documentată de blocare a perioadei – un conflict 409 în Nordlet – și că nu sunt scrise linii în jurnal, nu este consumat niciun număr de document, niciun document nu trece în starea înregistrat și nu se declanșează niciun webhook de succes. Varianta cu perioada deschisă ar trebui să reușească folosind aceleași valori financiare.
Test de concurență (Race test). Porniți o înregistrare într-o perioadă deschisă, blocați perioada în timpul cererii și confirmați că operațiunea de comitere (commit) nu poate ocoli blocarea. Condiția critică de trecere: o înregistrare comisă nu ajunge niciodată într-o perioadă care a fost blocată înainte ca tranzacția să fie finalizată.
Auditabilitate și reconciliere
Pentru fiecare mutație reușită, confirmați că obiectul de business există, că înregistrarea contabilă există cu debitele egale cu creditele, că înregistrarea de audit există, că evenimentul webhook există sau poate fi preluat și că înregistrarea operațiunii dumneavoastră indică ID-ul obiectului de la furnizor, reîncercările făcând referire la aceeași operațiune logică.
Pentru fiecare mutație respinsă, confirmați că nu există niciun document parțial, că nu s-a consumat niciun număr decât dacă contractul permite rezervarea, că nu există nicio înregistrare în registru, că nu există niciun webhook de succes și că eroarea conține un ID de cerere pentru diagnosticare. Convențiile Nordlet descriu auditabilitatea mutațiilor și înregistrările echilibrate ca pe niște garanții ale platformei, echilibrul fiind impus de un declanșator de BDD (database trigger) amânat în momentul comiterii, nu doar de codul aplicației. Transformați aceste garanții în interogări de reconciliere efectuate după test, în loc să vă bazați orbește pe răspunsul HTTP.
Matricea principală de testare
| Zonă | Acțiune de testare | Aserțiune aşteptată | Criteriu de trecere |
|---|---|---|---|
| Autentificare | Fără cheie, cheie invalidă, permisiuni insuficiente | 401/403 structurat; fără efect secundar |
Toate încercările respinse nu creează nicio înregistrare contabilă |
| Schemă și sume | Zecimală invalidă, dată invalidă, câmp obligatoriu | Eroare de validare la nivel de câmp | Nu se produc reîncercări sau scrieri parțiale |
| Înregistrare normală | Crearea și emiterea unei facturi într-o perioadă deschisă | Un document, un jurnal echilibrat, o înregistrare de audit | Starea citită și registrul corespund |
| Repriză cu aceeași cheie | Repetarea unei mutații identice, aceeași cheie și corp | Rezultatul original este redat; fără duplicate | ID-ul obiectului, numărul, efectul în jurnal, auditul rămân unice |
| Corp modificat, aceeași cheie | Reutilizarea cheii cu o sumă diferită | Respingere documentată pentru reutilizarea cheii | Înregistrarea originală rămâne neschimbată; nu se scrie nimic nou |
| Conexiune întreruptă | Comitere, întrerupere, reîncercare cu aceeași cheie | Rezultat redat (replayed) | Exact un singur efect secundar financiar |
| Perioadă blocată | Înregistrarea unui document datat într-o perioadă blocată | Respingere din cauza perioadei blocate | Fără jurnal, fără număr, fără webhook de succes |
| Semnătură webhook | Secret greșit, corp alterat | Răspuns diferit de 2xx de la receptor | Doar corpul brut și secretul corecte sunt acceptate |
Cu ce aș începe
Dacă timpul este scurt, rulați testele în ordinea care detectează cele mai costisitoare erori. Începeți cu reîncercarea în caz de conexiune întreruptă, deoarece acest singur scenariu produce cele mai multe duplicate reale. Apoi treceți la perechea de idempotență cu aceeași cheie și corp modificat. Urmează perioadele blocate, deoarece o înregistrare într-o lună închisă este o problemă de audit care iese la iveală târziu. Verificarea semnăturilor și webhook-urile sosite în ordine inversă vin în continuare, iar schema completă și matricea de autorizare pot rula continuu în CI odată ce clientul se stabilizează.
Tot restul din acest plan sprijină aceste cinci aspecte. Aduceți-le în starea verde pe o companie sandbox, cu citiri de reconciliere care confirmă efectele secundare, și veți ști că integrarea este sigură înainte de a atinge un singur registru real. Puteți crea o companie sandbox și o cheie de test restricționată în câteva minute din secțiunea Noțiuni de bază și puteți verifica modulele de care aveți nevoie consultând lista de funcționalități.
FAQ
Este suficient un răspuns 2xx pentru a confirma că o scriere contabilă a reușit?
Nu. Un cod de stare confirmă că serverul a răspuns, nu că există exact un singur document, o singură alocare de număr și o singură înregistrare contabilă echilibrată. Fiecare test de mutație ar trebui să fie urmat de o citire a obiectului, a efectului său contabil și a înregistrării de audit. Cazul periculos este direcția opusă: o operațiune care s-a comis în timp ce clientul nu a primit deloc răspunsul.
Ar trebui să generez o nouă cheie de idempotență atunci când o cerere expiră (timeout)?
Nu, aceasta este greșeala care cauzează cele mai multe duplicate în producție. Cheia identifică operațiunea de business logică, nu încercarea de rețea. Reîncercați cu aceeași cheie, apoi reconciliați citind resursa. O bibliotecă de reîncercare care generează un UUID nou la fiecare încercare transformă o factură intenționată în mai multe scrieri independente.
Ce se întâmplă dacă reutilizez o cheie de idempotență cu un alt payload?
Un API corect o va respinge în loc să aplice în mod silențios noul corp. Nordlet returnează 422 idempotency_key_reuse și lasă înregistrarea originală neatinsă. Clientul dumneavoastră ar trebui să trateze acest lucru ca pe o eroare de programare care trebuie corectată, nu ca pe o condiție care poate fi ocolită prin generarea unei chei noi.
Sunt webhook-urile un substitut pentru citirea obiectului creat?
Nu. Livrarea unui webhook dovedește notificarea în aval, nu că tranzacția a fost comisă așa cum vă așteptați, iar ordinea livrării nu este garantată. Verificați semnătura pe corpul brut, faceți deduplicarea pe baza ID-ului de livrare sau de eveniment și preluați starea actuală din API ori de câte ori ordinea evenimentelor nu este suficientă pentru a decide ce s-a schimbat.
Cum testez înregistrarea într-o perioadă contabilă blocată?
Creați documente equivalente într-o perioadă deschisă și într-una blocată, și asigurați-va prin aserțiuni că cazul blocat este respins fără linii de jurnal, fără număr de document consumat, fără tranziție de stare și fără webhook de succes. Apoi rulați versiunea de concurență: porniți o înregistrare într-o perioadă deschisă și blocați perioada în timpul cererii. O înregistrare comisă nu trebuie să ajungă niciodată într-o perioadă care a fost blocată înainte ca tranzacția să se fi finalizat.
Pot rula teste de volum ridicat cu duplicate într-o companie sandbox?
Da. O companie sandbox se comportă ca una reală, este marcată drept date de test și se șterge imediat în loc să treacă prin fereastra de reținere, așa că este locul potrivit pentru testarea distructivă și a duplicatelor. Utilizarea sandbox-ului este totuși contorizată și facturată ca utilizarea reală, așa că planificați volumul în loc să rulați bucle la infinit.