Începem să scrie teste (dreapta) - Blog
Cum să încep? Cât timp ar trebui să scrie teste? Ce ar trebui să scrie teste? Ceea ce nu are nevoie să scrie testele? Ar trebui să se aplice întotdeauna TDD?
Dacă sunteți interesat în răspunsurile la aceste întrebări, atunci citiți articolul din dreapta. În viața mea, am scris mai mult de o mie de teste de toate tipurile pentru platforme diferite, utilizate în toate domeniile și a pus procesul de testare TDD în echipe, proiecte și chiar companii întregi. Și acum voi încerca să rezuma această experiență și să o împărtășească.
Testarea, precum și o mulțime de programare, a devenit un cult de marfă. În schimb, mișcarea conștientă, dezvoltatorii încearcă să urmeze orbește populare metodologii cred că ceea ce este scris în documentația care acoperă testele de cod 100%. Am fost un martor pentru a șterge un dosar cu testele (40 de mii de linii de cod) pentru motivul că acestea devin imposibil de menținut. O astfel de testare de multe ori duce la efectul opus, dezvoltarea devine mai scump, dar procesul este mai lent, și chiar dacă există un efect pozitiv, acesta este dat prea mult.
Scopul principal al acestui articol - pentru a vă oferi o înțelegere holistică a sensului testului. Înțelegerea esența, va fi mai în măsură să gândească critic și să înțeleagă unde să meargă. Și, desigur, va fi un sfat practic.
Să începem cu cea mai importantă întrebare: de ce avem nevoie pentru a testa?
Pentru a fi siguri în performanța produsului nostru. Observați că nu am scris „funcții“, „modul“, „cod“ sau „proiect“. În cele din urmă, contează doar că produsul final, care este utilizat (nu neapărat utilizatori), funcționează și o face bine. Deși chiar acum poate părea ca căpitănia, dar după cum se va vedea mai târziu, orientarea țintei ne va permite să ia deciziile corecte.
Teza cheie Următoarea nu este o caracteristică a procesului de testare. Sarcinile pot fi împărțite în două tipuri: acestea sunt fie finalizate sau nu, iar finalizarea sarcinii celui de al doilea tip - aceasta este scara, în cazul în care 0 - este „nimic nu a fost făcut“, și 1 - este format din 100%. Și, în care se ocupă cu aceste probleme, soluție de 100%, este de multe ori imposibil de atins din cauza overhead ultra-înaltă.
Aici este un exemplu perfect. Pentru mai multe servicii, un astfel de lucru ca SLA critic sau, mai simplu, disponibilitatea serviciului. De exemplu, pe site-urile de găzduire a scrie ceva în spiritul „noi oferim acces la 99,9% din serverele noastre.“ Să numărăm până cât de multe ore pe an de hosting pot fi disponibile ca parte a SLA sale: 0.001 * 365 * 24 = 8,7. În principiu, o idee bună.
Să presupunem că furnizarea unui astfel de nivel de disponibilitate costurile companiei de 1.000 $. Și cât de mult va costa pentru a adăuga fiecare nou nouari la sfârșitul anului? Asta este, oferind 99.99. 99999 și așa mai departe. Din câte știu, la acest nivel oferă o creștere exponențială (explozivă) a costurilor. Nu vorbesc despre faptul că 100% disponibilitate este fantastic.
Acest exemplu demonstrează clar faptul că problemele cu rezultatul principiului principal de flotant este „rezultate maxime pentru resurse minime“, cu alte cuvinte, a căutat un echilibru în care vom obține un rezultat care satisface părților interesate (părțile interesate), într-un termen rezonabil de buget / cronologie.
Acum, înapoi la testul nostru și descoperim că testele sunt de acest tip de probleme. Adăugarea primului test în proiect, oferă un efect incredibil. Acoperirea 50% (jumătate din codul este invocat în test) poate fi obținut aproape imediat, și în comparație cu nici un test - avem două locuințe față. Apoi, situația începe să se schimbe, iar undeva la nivelul de 70-90%, începe o încetinire puternică a creșterii acoperirii, testele au devenit din ce punct, dragă. Crește complexitatea sprijinul lor, refactorizare.
Acest proces este fără sfârșit. Pentru a realiza o acoperire de 100% este foarte scump și, mai ales, în mod inutil (vezi. Exemplul de mai sus). Mai mult, nu teste nu vă oferă o garanție completă a performanțelor.
În plus față de numărul de teste și a calității acestora la costul de asemenea, afecteaza ce tip de teste folosim. Există mai multe clasificări de tipuri de teste, cum ar fi un „sistem de cunoaștere“, „în funcție de gradul de automatizare“, „la momentul testării.“ În această etapă, ne interesează doar o clasificare „în funcție de gradul de izolare a componentelor“:
- unitate de testare
- testarea integrării
- Testarea sistemului (acceptare)
În realitate, nu există nici o diviziune clară în trei nivele. Chiar dacă sunteți de testare o funcție pur (unitate de testare), se realizează pe un anumit hardware, și potențial, celălalt poate să nu funcționeze conform așteptărilor (de exemplu, este, de asemenea, într-un sens, testarea de integrare).
Deci, există doar gama. Partea mai simplă și mici a sistemului, suntem de testare - mai ieftin decât testele mai complexe (compozite) - cu atât mai dificilă. Și treaba ta ca un profesionist - nu provin de la, în scopul de a satisface propriile lor idei despre tipurile de teste de testare și de scris, astfel încât acestea să acopere în mod ideal, un număr mare de cazuri la un cost redus. Sunt sigur că această frază unii dezvoltatori au înăsprit, în viziunea lor asupra lumii, este necesar să se scrie teste unitare izolate și de acceptare ar trebui să scrie numai testeri. Eu nu am de gând să se reproducă controverse, trebuie doar să spun că aceasta depinde. Există proiecte în care procentul de teste unitare (în sens greu) este o fractiune de procent din toate celelalte teste (ca în Hekslete, hehe), dar sunt cele în care scrie doar testele de recepție (unele testeri).
Acum ești gata și voi încerca să răspundă la întrebările puse de la bun început. Să presupunem că scrieți un program (de comandă instrument de linie), care ia fișierul de intrare și cuvântul pe care doriți să o căutați în acest fișier. Ca rezultat al activității sale, imprimă programul de pe ecran toate liniile din dosar, în care apare cuvântul. Acest utilitar nu există și se numește grep. Cu ea familiar majoritatea dezvoltatorilor.
De obicei, în astfel de programe nu este întotdeauna clar imediat ce va fi arhitectura. Mult depinde de ceea ce va fi adăugată procesului, de exemplu, formatele suportate de ieșire formate de intrare, parcurgeri director (recursiv), cautare fuzzy, și multe altele.
mi-a observat Principalele anti-model în dezvoltarea unor astfel de biblioteci - se testează pentru componentele interne mici. Aceste teste de aceeași unitate. De ce această abordare nu este productiv? Poate că acest lucru nu este evident, dar o astfel de testare, deși, și este modular, dar nu este de calitate ieftin si bun. Dar cum ...?
Am spus deja că arhitectura proiectului nu este încă cunoscută, și, de regulă, diviziunea internă în fișierele / module / clase / funcții modificări cu o viteză cosmică. Într-o oră, tot de mai multe ori poate fi rescris. Dar acum, cu codul pe care trebuie să le modificați în mod constant teste care devine enervant. Programatorul începe să se îndoiască că acestea sunt tot ce are nevoie, și nu rareori se oprește doar să le scrie. Alții continuă să sufere și să le rescrie, deși de multe ori există mai mult. Testele scrise încep să te constrânge, iar creierul trimite comanda „Ai petrecut timp, lăsați totul așa cum este.“ Treptat refactor tot mai greu și lazier. Acest lucru este foarte similar cu situația în care omul de afaceri a investit bani într-o nouă direcție, chiar și în cazul în care afacerea este deja scufunda, atunci ar fi greu să refuze, pentru că a fost cheltuit atât de mult efort și bani (în economie se numește un cost scufundat. - nn ..).
Din moment ce este mai bine să scrie testul? Din fericire, ai devenit deja evident că necesitatea de a găsi un punct destul de mare de intrare în programul nostru, care nu depinde de punerea în aplicare internă, în timp ce efectuează sarcina.
Dacă încercăm să luăm cel mai înalt nivel, și anume, la începutul directă a programului în consolă, este probabil să se confrunte cu o serie de provocări, cum ar fi rularea unui proces separat, citirea fluxului standard si altele. În cazul programului nostru de testare acest lucru poate fi deja numit un sistem, pentru că vom verifica munca la cel mai înalt nivel, toate fără a atinge punerea în aplicare internă. Cu toate că acest test nu este o problemă pentru dezvoltator cu experiență, în general, costul unui astfel de test poate fi numit maxim pentru această bibliotecă.
Nivelul inferior este o funcție care are ca date de intrare calea către fișierul și substringul pentru a căuta, iar ieșirea (nu se imprimă pe ecran!) Dă rezultatul finit, astfel încât să-l imprimați numai. Acest tip de test are cel mai bun echilibru „pentru a vă asigura că totul funcționează / costuri“. Acestea afectează în mod indirect toate utilizate intern, independent de punere în aplicare, este foarte ușor să scrie și foarte ieftine pentru a menține. Ca arhitectura de stabilizare poate fi adăugat Testele de nivel inferior (în cazul în care devine clar că complexitatea sistemului este prea mare).
Tehnica descrisă funcționează bine în special în legătură cu modul de abordare, atunci când testele sunt scrise înaintea codului (cu codul).
Există un mit care numai testele necesare pentru regresie, adică să se asigure că noul cod nu se rupe vechi. Departe de ea. Mai mult decât atât, este o consecință a testelor de scris ca atare. În unele situații, scopul principal al testelor de scriere - se accelerează dezvoltarea. Da, ai auzit bine, scrie teste înainte de cod / cod, în același timp, aceasta duce la o accelerare gravă a dezvoltării. Cele mai multe dintre aceste situații implică faptul că sunt date complexe de intrare, care într-un fel transformate și prokidyval în continuare. Testați mâinile (în timpul dezvoltării), acest cod este foarte dificil, trebuie să pregătiți datele, trebuie să verificați că rezultatul este cum era de așteptat.
Este important să se înțeleagă că accelerația este posibilă numai după ce ați câștiga experiență și de a începe să se simtă confortabil în lumea de testare automată. În plus, există tipuri de teste în cazul în care testele de scris înainte de codul este dificil sau aproape imposibil. Astfel de teste, de exemplu, includ testarea receptor prin intermediul unui browser.
Al doilea avantaj major al TDD este faptul că proiectarea codului, începem să ne gândim, nu despre cat de cool este acum fișierele nasozdaem și le distanțată funcție prin crearea de zeci de abstracțiuni și să înceapă să se gândească la lucrurile cu adevarat importante. Despre modul în care vor fi utilizate biblioteca mea. Surprinzător, începe căutarea dintr-un unghi (așa cum este învățat toate startup-urile, dezvoltarea clienților în toate domeniile) nu este ușor, ne dorim întotdeauna să plonja în lumea minunată a arhitecturii.
Proiectarea api externe sarcină foarte importantă, care ar trebui să aibă cel puțin un pic de timp. Acesta este cel mai mare efect asupra libertății de acțiune în procesarea, veți primi în viitor. Și acest lucru este nivelul cel mai adesea este punctul de la care există un început în formarea planurilor de testare.