O mare salvare ruptă este o dovadă, nu o explicație
Atunci când o salvare nu reușește să se încarce, o căutare dispare, sau o migrare încalcă o regulă de joc, primul artefact poate fi enorm: sute de câmpuri, colecții cu cuiburi, o lungă istorie de acțiune, un instantaneu de conținut, și un mediu care nu mai există. Acest artefact este valoros pentru că reproduce problema. Este dificil pentru că oferă unui dezvoltator mult mai multe informații decât pot argumenta într-o dată. Citirea-l linie cu linie produce adesea presupuneri, mai degrabă decât o explicație.
Delta depanare schimbă obiectivul. În loc de a cere unei persoane să localizeze o valoare relevantă, întrebați un predicat determinist dacă un candidat încă demonstrează eșecul. Apoi eliminați sau simplificați părți ale statului în timp ce predicate rămâne adevărat. Rezultatul final este un caz minim de regresie: suficient de mic pentru a revizui, suficient de stabil pentru a replay-ul, și explicit despre invariant care rămâne rupt.
Minimal nu înseamnă vizual mic sau universal mic. Scopul util este un contraexemplu redus material sub un cost limitat. Un reductor se poate opri atunci când nici un grup întreg nu poate fi eliminat, atunci când un buget de execuție este epuizat, sau atunci când dispozitivul este suficient de ușor de înțeles pentru a deveni un test de regresie. Proprietatea conservată contează mai mult decât un optim abstract.
Stabilirea reproductibilității înainte de reducere
Reducerea funcţionează doar atunci când eşecul este repetabil. În primul rând capturaţi predicate precise: nu curent încărcător arunca o eroare clasificate, nu o inversare invariat, nu o stare rezultat diferă semantic de rezultatul aşteptat, sau nu o secvenţă de acţiune produce o subvenţie invalidă? Evitaţi folosind un vag predicate, cum ar fi jocul arata gresit. bază Predicate trebuie să returneze acelaşi răspuns pentru aceleaşi intrări, sau reductor va urmări zgomot.
Inregistreaza mediul alaturi de candidat: construieste sau comite aplicatii, versiunea migratiei, versiunea adaptorului, continutul si configuratia instantaneua, semintele deterministice, presupunerile platformei si hashul de pornire. Daca un ceas live, o sursa aleatoare, un dispozitiv de configurare la distanta sau un muncitor de fundal poate schimba rezultatul, il poate inlocui cu o limita de test deterministica sau il poate inregistra ca limita explicita. Reducatorul nu trebuie sa testeze in secret un nou mediu pe fiecare incercare.
Pentru eșecuri de acțiune-secvență, păstrați starea inițială și acțiunile comandate separat. O stare finală poate ascunde operațiunea care a produs-o. O linie de secvență poate exprima pornirea de la acest profil, efectua aceste șapte cereri, apoi invariant eșuează. bază de separare care permite reductor să micșoreze câmpuri, colecții, și acțiuni fără a confunda un fel de dovezi pentru altul.
Reduceţi câmpurile şi colecţiile în partiţii
Începeți cu partiții grosolane. Divideți salvarea de nivel superior în grupuri de teren, eliminați un grup dintr-o copie de lucru, și executați predicate. Dacă eșecul persistă, păstrați îndepărtarea; în cazul în care dispare, restabiliți grupul și subdivideți-l. Acest lucru este mai eficient decât ștergerea unui câmp la un moment dat de la un obiect mare. Continuați în înregistrări cuibărite și colecții odată ce o regiune relevantă este identificată.
Colecțiile au nevoie de îngrijire specială. Elemente de inventar, înregistrări de căutare, contoare, și istoria evenimentelor se pot referi la fiecare alte. Îndepărtarea unei intrări poate modifica indexurile listei, regulile capacității, sau solduri agregate. Normaliza comanda în cazul în care ordinea nu este semnificativă, păstra identificatori stabile în cazul în care acestea necesită referințe, și precizează dacă un element lipsă ar trebui să fie absent, nul, sau reprezentat printr-un retrograd moștenitor explicit. Un reductor nu ar trebui să transforme un defect de migrare reală într-o eroare parser cauzate de intrare de testare malformate.
Utilizați scăderea valorii după reducerea structurală. Mutați numărul întreg spre zero sau o limită importantă, scurtați siruri de caractere, înlocuiți un identificator lung cu un identificator de test sigur, și reduceți timp de ștampile la o epocă stabilă numai atunci când valoarea lor exactă nu este condiția în curs de testare. Fiecare simplificare trebuie să păstreze predicate adevărat. Acest lucru arată adesea că un aparent complex profil bug este într-adevăr o piesă retras ID plus un inventar complet sau un contor negativ după o versiune omisă.

Reduceți secvențele de acțiune fără a-și schimba sensul
Unele eșecuri apar doar după timp: o rejudecare a achiziției după o reconectare, o salvare după o actualizare a configurației, sau o migrare după un tutorial întrerupt. Aplicați aceeași idee de partiționare la acțiuni. Eliminați o jumătate contiguă a secvenței, replay-ul, și păstrați eliminarea în cazul în care invariantul încă nu. Apoi subdivide. Păstrați acțiunile de configurare necesare, dar provocarea navigației accidentale, citiri repetate, și mutații conexe.
Acţiunile ar trebui să aibă parametri stabili şi aşteptări de rezultat. Un reductor care înlocuieşte fiecare cerere cu un nou ID de tranzacţie aleator nu mai testează semantica originală. Un reductor care elimină sarcina iniţială de funcţionare-flag poate modifica contextul configuraţiei. Înregistraţi identitatea acţiunii, intrările relevante, sursa de încredere versus neîncredere, şi punctul în care invariantul este verificat. Aceasta face ca secvenţa finală să fie utilă atât pentru dezvoltatori cât şi pentru QA.
În cazul în care o secvenţă depinde de contract, alege un program determinist. Înregistraţi ordinea în care lucrătorii sau clienţii simulate atinge limite critice. Dacă eşecul apare doar în cadrul unei curse, un test poate avea nevoie de o barieră controlată mai degrabă decât apeluri de somn dependente de sincronizare. Scopul nu este de a pretinde convaility este simplu; este de a face observat interleaving suficient pentru a raţiona despre.
Păstrați invariant încălcat în artefact final
Un mic dispozitiv fără o afirmaţie devine un alt fişier misterios. Păstraţi invariant încălcat în afară de dispozitivul în termeni clari: dreptul duplicat pentru o identitate tranzacţională, referinţă catalog necunoscut după migrare, monedă negativă, inaccesibil completat căutare, sau nepotrivire semantică după o călătorie dus-întors. Include clasificarea aşteptată şi cel observat. Fixarea ar trebui să eşueze pentru un motiv, nu doar pentru că o funcţie se întoarce fals.
Comparați înainte și după semantic de stat. Un diff brut poate conține ștampile de timp rescrise, array-uri reordonate, ID-uri generate, sau formatare serializare. Un diff semantic evidențiază valori care afectează invariant. Se poate raporta că un element schimbat de la o rezervă moștenire validă la un ID necunoscut, sau că un echilibru a fost incrementat de două ori pentru aceeași cheie registru. Păstrați normalizator îngust și documentate; un normalizator larg poate șterge foarte defect reductorul este menit să păstreze.
Scrie un manifest de reluare cu calea de fixare, hash sursă, hash redus, amprenta de mediu, semințe deterministe, secvența de acțiune, dacă există, predicate nume, și rezultatul preconizat. Acest manifest permite o altă persoană rerun cazul fără acces la starea originală supradimensionată. De asemenea, face dispozitivul potrivit pentru CI, în cazul în care un caz minimizat ar trebui să fie rapid și clar, mai degrabă decât dependent de o mașină locală privată.
Stiti cand trebuie sa incetati reducerea
Fiecare predicate costurile de rulare de timp. Unele migraţii sunt lente; unele scenarii au nevoie de adaptoare de serviciu; unele condiţii de eşec sunt fulg până când un mediu este fixat. Setaţi bugete pentru încercări, timp de perete, şi conte artefact. Opriţi atunci când dispozitivul este suficient de mic pentru a explica problema, atunci când nici o partiţie nu poate fi eliminat fără a pierde eşecul, sau atunci când munca rămasă necesită judecata domeniu, mai degrabă decât reducerea mecanică.
Reducerea are limite. Nu se poate decide dacă un element moștenitor ar trebui să cartografieze un înlocuitor, dacă o căutare în retragere are nevoie de compensare, sau dacă o valoare salvată este legală într-o economie reproiectată. Acestea sunt decizii de produs. De asemenea, nu poate reduce în siguranță datele criptate sau sensibile prin copierea-l în instrumente largi. În aceste cazuri, creați un echivalent sintetic care păstrează condiția structurală, sau păstrați ancheta limitată în limita de acces corespunzătoare.
Nu publica o stare de jucător brut ca element de regresie. Nume de benzi, informații de contact, date de primire, identificatori de dispozitiv, jetoane de acces, și orice câmp nu este necesar pentru predicate. Un dispozitiv minim este o oportunitate de a îmbunătăți confidențialitatea, precum și diagnosticabilitatea. Artifactul final ar trebui să fie sigur pentru a include în proiectul de test corpus și suficient de util pentru a preveni recurența.
Lista de verificare practică
- Defineşte un eşec determinist înainte de a îndepărta orice stare.
- Înregistrați aplicarea, adaptorul, conținutul, configurația, semințele și mediul de fixare.
- Păstrați starea inițială și secvența de acțiune separate atunci când comportamentul se desfășoară în timp.
- Reduceți mai întâi grupurile de nivel superior, apoi câmpurile cuibărite, colecțiile și valorile.
- Păstrați referințele și valabilitatea structurală în timp ce provocarea relevanței semantice.
- Utilizați un program de convalescență controlat în loc de retries dependente de sincronizare.
- Păstrați invariant încălcate, clasificarea așteptată, diff semantic, și reluarea manifest cu rezultatul.
- Opriți la un contraexemplu util limitat; nu optimizați pe termen nelimitat minimalitatea teoretică.
- Redactează sau sintetizează datele sensibile înainte ca un dispozitiv să intre în testele de rutină.
Întrebări frecvente
Depanarea delta este doar pentru accidente?
Nu. Predicate poate fi un accident, dar poate fi, de asemenea, un joc invariant încălcat, un număr greșit dreptul, un eșec de salvare-încărcare dus-întors, o clasificare de migrare respinsă, sau o neconcordanță între starea așteptată și cea observată. Este cel mai util ori de câte ori o intrare complexă produce în mod fiabil un rezultat care nu ar trebui să apară.
Ce se întâmplă dacă eșecul este intermitent?
În primul rând reduce nondeterminismul. Fixa semințe, configurare captura, timpul de izolare și limitele de rețea, și de control convaility. În cazul în care rezultatul rămâne probabilistic, utilizați un prag-based predicate numai cu grijă și să înregistreze că limitarea. Un scenariu mai mic stabil este, de obicei, mai valoros decât un dispozitiv mare fulg.
Poate un reductor să ruleze împotriva datelor de producție?
Reducerea de rutină nu ar trebui. Utilizați dispozitive sintetice sau redactate și un mediu controlat. O anchetă incident restricționat poate avea nevoie de dovezi protejate, dar că este un proces operațional separat, cu controale de acces, reguli de reținere, și revizuire. Nu face suita de regresie o copie a datelor jucătorului.
Ce pretinde Persistium aici?
Persistium este în dezvoltare ca o familie de produse de fiabilitate local-primul. Această notă prezintă un flux de lucru de reducere în general util și nu susține că un produs public diagnostichează automat economii arbitrare, a observat eșecuri ale clienților, sau operează un serviciu de analiză găzduit.







