Cum să alegeți corect un nume pentru depășirea stivei de testare a unității în limba rusă

A fost o zi obișnuită, am început să scriu un alt test obișnuit, dar când scriam titlul testului, ceva a mers prost:

Aproximativ în mijloc, am început să-mi dau seama că ceva nu merge bine, dar nu m-am oprit și am adăugat numele testului până la sfârșit. Colegii nu au apreciat un nume atât de lung pentru test, dar îmi place. Acum este folosit ceva de genul testCorrectChangeCustomerRedirectUrl. și detaliile a ceea ce testele de testare sunt ascunse în cadrul testului.







Nu pot să înțeleg asta, sau sunt obosit seara.

Întrebare: Care sunt criteriile pentru alegerea unui nume de test bun?

UPD: Vă rugăm să denumiți testele din proiectele dumneavoastră.

Din nou, măcelarii au fugit. Domnilor, să includem și capul. Dacă întrebarea vă pare neînțelesă doar pentru că nu sunteți în acest subiect, aceasta nu înseamnă că aceasta este o întrebare inutilă. În plus, după cum am scris deja, programarea are o serie de domenii în care este practic imposibil să se dea un răspuns clar, dar acestea sunt domenii importante. Cel mai evident exemplu este designul de software. - andreycha 2 decembrie '15 la 17:13

Numele testelor nu trebuie ales frumos. Numele ar trebui să fie ales funcțional și cât mai scurt posibil - astfel încât, prin numărul minim de caractere, să fie clar ce și în ce condiții este testat și, de asemenea, să se facă distincția între un anumit test și alte mii de alte.

Modelele comune de numire sunt:

  • TestClass_TestMethod_ConditionAndExpectedResult (pentru teste unitare)
  • TestMethod_Condition_ExpectedResult (pentru testele unității)
  • ConditionAndExpectedResult (pentru testele de integrare care testează întregi blocuri de funcționalitate prin intermediul unui punct de intrare)

În acest caz, dacă aveți piese de Stare / ExpectedResult prea mulți termeni diferiți / rezultate, grupate în funcție de „I“, atunci trebuie să-și reconsidere fie obiectivul principal al testului (se testează) sau principala condiție care distinge testul de celălalt, și rupe-l pentru mai multe teste separate.

Ma lupt in primul rand pentru ca numele sa fie informativ, dar in acelasi timp cat mai scurt posibil. Aici, la fel ca și în restul codului - cu cât codul este mai mic, cu atât mai puțin timp trebuie să îl înțelegi, cu atât este mai ușor să o rezolvi. Judecând după numele dvs., acesta nu este un test simplu de unitate mic, ci ceva mai mult, deci nu puteți face fără un nume foarte scurt. În cazul tău, dacă ai deja o clasă de testare pentru client. M-aș limita la numele SelectLastTransactionProcess_CreateRecurringProfile_RedirectUrlShouldContainConfirmation. În titlul dvs. există multe repetări ale cuvintelor: tranzacție, adresă URL, profil recurent, etc. Sunt redundante.

Trebuie să existe un echilibru între lungimea și caracterul informativ al numelui. Este suficient ca numele să fie ușor de înțeles pentru dezvoltatorii din cadrul proiectului, care au deja contextul și care sunt capabili să înțeleagă ce este vorba despre acest test. Și dacă pentru asta trebuie să faceți lungimea titlului nu 30 de caractere, ci 40, fă-o. Dar nu trebuie să vă străduiți să vă asigurați că numele sunt clare pentru toată lumea pe care o întâlniți, de-a lungul drumului vorbește despre întregul sistem, deoarece acest lucru duce la un nume de kilometru care este greu de înțeles. Uită-te la codul obișnuit, uita-te la numele metodelor. Nu descrieți în numele metodei fiecare detaliu, fiecare linie? Descrieți ceva important, iar restul este ascuns în interior. În același mod cu metodele de testare.

Poate cineva să spună ce să facă cu numele testelor de integrare,> unde sunt 100500 condiții diferite?

De exemplu, facturarea se bazează pe 5-10 tipuri de liste de prețuri și, în funcție de combinațiile și combinațiile parametrilor lor (de asemenea, aproximativ 5-10), trebuie să emită sume diferite pentru producție. Containerul trimis la facturare are nevoie

30 de linii. În cazul în care stilul de post numit de testare se va testPayoutDebtorToGateOntopGateTransactionAmountGateToCreditorFlatPayinDebtorTo GateOntopTotalTransactionAmountGateToCreditorOntopTransactionAmount. și nu cu contextul complet.

Este necesar să se calculeze suma totală pe presupunerea că listele de prețuri pot fi configurate după cum urmează: tipul de comision de tip listă de prețuri de tranzacție de bază - în interiorul / total, 0,1% cverhu 0.5rub + Comisie, calculul cifrei de afaceri de plumb. Cea de-a doua listă de prețuri pentru comisioane pe platformă / poartă. încă în același stil o dată pe 10 și câteva dependențe implicite ale listelor de prețuri una de cealaltă.

Aș spune că aveți nevoie de un test parametric. Acesta este un test care testează diferite seturi de date cu același cod. De exemplu, în ceea ce privește cadrul de testare xUnit, testul parametric al metodei Calculator.Add () ar putea arăta astfel:

Cu ajutorul testelor parametrice, nu este necesar să enumerați toate condițiile din nume - numele conține numai esența testului, exact ceea ce este testat, un caz particular. În cazul tău, este vorba de calcularea valorii valorii principalei oferte adiționale (în limba engleză o vei traduce singur, vei înțelege mai mult zona). Metoda dvs. de testare poate arăta astfel (în timp ce datele din testul xUnit pot fi înlocuite cu proprietatea și chiar cu un obiect separat):

Cred că în multe cadre de testare este posibil să se creeze teste parametrice. Metoda de setare a parametrilor poate diferi, dar esența va rămâne aceeași: datele sunt transferate la secțiunea cu datele, în numele testului există doar numele cazului.

Mai multe informații despre testele parametrice pot fi găsite în blogul lui Serghei Teplyakov.

Înainte de primul test "modular"

Trebuie să fie de acord cu el însuși sau cu echipa despre ce să ia în considerare un "test modular"?







De exemplu, în cartea lui Roy (vezi secțiunea "Literatura recomandată"), este dată o definiție clară a "unității" și este destul de convenabilă pentru programator.

Fără o înțelegere clară și încrezătoare a ceea ce "unitatea" de a scrie teste unitate puternic nu recomandăm. Chiar dacă înțelegerea dvs. cu privire la ceea ce este un test de unitate diferit de ceea ce spune Roy este oricum, ar trebui să fie unificat și stabil pentru tine sau echipa ta. Care necesită un acord.

Înțelegerea testului "Unit Test" de la Roy:

Roy, în opinia mea, oferă cea mai convenabilă și practică schemă de denumire:

Unde: unitatea de lucru este exact ceea ce înțelegeți prin "unitate" sau ceea ce ați fost de acord cu echipa. scenariul este o acțiune specifică asupra obiectului testat așteptat-rezultat sau comportament - așteptările dvs. despre ceea ce se va întâmpla

Este imediat evident că parserul documentului json este verificat pe un fișier cu o extensie nevalidă a fișierului și prin urmare ar trebui aruncat InvalidLogFileException.

Se poate observa că atunci când octetul este optimizat, -1 va fi returnat dacă se produce o instrucțiune necunoscută

Scrierea testelor de unitate cu condiții complexe

  1. Aceasta este o chestiune complet diferită
  2. Dacă pentru scurt timp, într-un test modular, verificați ONE. În cazul în care condiția este dificilă, atunci există mai multe în condițiile și apoi trebuie să luați și să rupă în mai multe verificări - teste de unitate
  3. În orice test nu ar trebui să existe nici o logică condițională. Dacă există două ramuri în codul de producție, unul în parte, altul în altă parte. Înseamnă că scrieți două teste unitare.

și așa mai departe. și altele asemenea. Dar toate acestea sunt subiectul unei alte discuții

Ceea ce este greșit, în opinia mea, în testul dvs.:

Vă recomandăm foarte des descărcarea, și este mai bine să cumpărați cartea Art of Unit Testing. Chiar dacă Dintr-o dată nu scrieți la C #. Cunoștințele sunt utile!

Un nume foarte lung pentru test poate fi considerat un semnal de diagnosticare. Astfel de semnale pot fi văzute din diferite puncte de vedere, dar, în orice caz, de regulă, ele indică prezența sau posibila apariție a unei probleme. Opțiuni minim posibile:

  • Codul testat implementează o arhitectură greșită
  • Acesta nu este un test modular, dar eventual un test de integrare
  • Implementarea incorectă a modulului real de testare
  • Dezvoltatorul nu a avut suficient somn și (sau) a folosit orice transformator al conștiinței în cantități excesive

Din moment ce ați dat un exemplu, să ne uităm la ea. În primul rând, voi încerca să extrag din numele englez al testului dvs. sensul rusesc:

"Asigurați-vă că URL-ul la care clientul este redirecționat după procesarea ultimei tranzacții trebuie să conțină adresa URL corespunzătoare profilului de returnare a paginii, dacă tipul de tranzacție implementează profilul de returnare".

Să presupunem cum poate arăta corpul unui astfel de test:

În prima aproximare, totul pare să fie scurt, drăguț și ușor de citit. Să presupunem cum poate arăta testul, ceea ce dovedește contrariul:

Firește, presupunem că toate lucrările pregătitoare înainte de testare se fac din testele reale:

Cum numesc testele? Aproximativ astfel (din proiectul de lucru):

Numele clasei de test se referă la numele clasei testate din cod. Iar numele metodelor de testare denotă numele metodelor testate în clasa de testare și încercați să raportați pe scurt condițiile de testare pentru fiecare metodă particulară.

Nomenclatorul regulilor este într-un fel Tao sau Kung Fu. Este necesar să se respecte echilibrul. Dacă un nume de metodă de testare este mai lung decât codul în sine, conținut în metoda de testare, dezvoltator care refactor metoda, poate fi citit și de a înțelege codul de mai rapid și mai ușor decât prima Wade prin meandrele titluri literare în limba engleză.

Răspunsul a fost făcut în 18 decembrie 15 la 4:21

1. Numele de test trebuie să fie șiruri de caractere

Ar trebui să începeți cu faptul că numele testului este numele funcției. Spre deosebire de funcții, nu solicităm teste de la cod, numele testului este necesar doar pentru a descrie ceea ce testează, astfel încât această descriere să fie apoi înregistrată în jurnalul de testare.

Prin urmare, în unele cadre de testare, numele testelor sunt linii obișnuite.
De exemplu, în Catch (C ++)

Sau Mocha (JS și alte * script)

O excepție interesantă sunt limbile în care identificatorii pot avea orice caractere, cum ar fi în F #

2. Nu vă repetați (principiul DRY)

Dacă cadrul de testare vă permite să grupați testele, atunci acest lucru trebuie utilizat. În loc de a testa ceva "atunci când este vorba". Something_Whenother_VotEth și Something_Whenother_otherNoThis teste pot fi grupate.
Exemplu privind Mocha / JS:

De asemenea, nu este adesea niciun punct în repetarea codului de testare în titlul testului. Este necesar să se descrie ceea ce testul testează, și nu modul în care se face. Prin urmare, în loc de StartButton_WhenPressed_BecomesDisabled, puteți scrie

În mod tipic, testul include condițiile inițiale (partea GIVEN / WHEN) și rezultatele (partea THEN). Dacă există doar o singură încercare pentru unele condiții inițiale, atunci de ce scrieți în titlu ceea ce este verificat în partea THAT. Acest lucru este evident din cod și dacă testul nu reușește, textul testului nereușit va fi scris în jurnal.

Nume de probă de probă

Numele testelor depind de cadrul de testare și de nivelul de testare (unitate / integrare / regresie).

Teste de regresie pe Mocha / JS

Testarea unităților pentru Catch / C ++, când Catch a folosit numele de teste divizate /

Noile teste Catch / C ++, cu etichete

Teste pentru gtest / C ++ (din codul Chromium)

Teste pentru Golang

Dacă numele testului nu poate fi specificat de un șir, utilizarea simultană a CamelCase și a sublinierii oferă o lizibilitate destul de bună. De exemplu, în loc de TEST_CASE ("unele unități") @ Onedev.Link mai corect - aceasta este "un grup de teste pentru test." Un test ar trebui să testeze o caracteristică (un aspect al comportamentului programului), iar pentru o caracteristică pot exista mai multe verificări. Dar este recomandabil să nu puneți mai multe trăsături independente într-un test, cu excepția cazului în care aceste caracteristici sunt foarte mici. De exemplu, aveți posibilitatea să împingeți în 1 test factorial (0) == 1; factorial (1) == 1; factorial (4) == 24; aruncare (factorial (-1)) - nu este nimic de îngrijorat, că toate aceste verificări vor fi în testul cu același nume. - Abyx pe 19 decembrie 15 la 18:32

Opțiunea dvs. aceeași denumire este foarte similar cu aplicarea de mai multe secole în urmă, stilul ornat de a da titluri de cărți, atunci când în titlu descrie aproape întreaga parcelă a cărții. De exemplu, numele complet al lui Robinson Crusoe sună minunat:

„Viața, aventuri extraordinare și surprinzătoare de Robinson Crusoe, un marinar din York, care a trăit 28 de ani în singurătate pe o insulă pustie, în largul coastei Americii, în apropiere de gura de vărsare a râului Orinoco, unde a fost aruncat naufragiu, în timpul căreia toată echipajul, cu excepția pentru el a murit, subliniind lui eliberarea neașteptată a piraților, scrise de el însuși "

răspunsul este dat 2 decembrie 15 la 15:03

@ Onedev.Link sunteți angajat în perfecționism în cea mai proastă manifestare. Urca în testele pentru a determina eșecul mai devreme sau mai târziu, și ceva drept atât de teribil în ea nu este (în cele din urmă, cel mai probabil, nu scrie perfectă care să acopere toate testul dintr-o dată), și puteți fi de actualitate, și numele metodei. Chiar dacă sunt atât de fundamental testa descrierea logică este în numele său (necesitate discutabilă), și, astfel, numele obținut monstruos lung, atunci ar trebui să ia în considerare divizarea clasa de test pentru câteva altele noi, fiecare dintre acestea vor fi testate pentru ceva mai specific - DreamChild 18 decembrie '15 la 9:43

Cred că numele testului de unitate ar trebui să fie capabil. Mai ales dacă testul este scris în stil BDD. Mai ales dacă cadrele dvs. de testare știu cum să le pună în rapoarte lizibile.

După părerea mea, nume capace (exemplu):

  • testShouldAlwaysPreparePathsAndConvertThemInToArray
  • testShouldRegisterNamespacesForMultipleDirectories
  • testShouldThrowExceptionIfDbIsMissingOrInvalid
  • testShouldSetOptionsWhenConfigPassedToTheConstructor

În orice cadru decent pentru testare, astfel de nume de metode sunt transformate în ceva de genul acesta (exemplu):







Articole similare

Trimiteți-le prietenilor: