Bazele AntiPatterns Testele Rails

Acest articol este o introducere în apele avansate ale testelor AntiPatterns in Rails. Dacă sunteți un om de treabă destul de nou pentru dezvoltare și doriți să luați câteva bune practici valoroase, acest articol a fost scris exact pentru dvs..

Subiecte

  • Lăsa
  • Oaspeții misteriali
  • Teste obscure 
  • Teste rapide
  • Programe
  • Încercări delicate
  • Atribute de date

Lăsa

descrie Misiunea nu da (: james_bond) build_studbed (: agent, nume: 'James Bond', nr: '007') let (: mission) build_stubbed (: mission, title: 'Moonraker')

lăsa metoda helper în RSpec este foarte frecvent utilizată pentru crearea de variabile de instanță care sunt disponibile între mai multe teste. În calitate de student îndelungat al practicii TDD, probabil că ați scris o parte echitabilă din acestea, dar această practică poate duce cu ușurință la a avea o mulțime de oaspeți misterioși care apar în continuare - ceea ce nu este cu siguranță ceva ce trebuie să ne prăbușim! 

Acest efect secundar particular al lăsa a câștigat un pic de reputație pentru eventual provocând o întreținere mai mare a testelor și o lizibilitate inferioară în întreaga suită de testare. lăsa sunetul sunete este atrăgător pentru că este leneș evaluat și ajutoarele aderând la conceptul de defect zero, de obicei, al DRY și al tuturor. Prin urmare, pare prea bine să nu utilizați în mod regulat. Verișorul ei apropiat subiect ar trebui, de asemenea, să fie evitată de cele mai multe ori.

Se înrăutățește când începi să cuiți aceste lucruri. lăsa declarații tencuite peste tot imbricate descrie blocuri sunt un favorit de toate timpurile. Cred că nu este nedrept să numiți această rețetă pentru a vă agăța - repede. Obiectul mai limitat este, în general, mai ușor de înțeles și de urmat. 

Nu vrem să construim o casă de cărți cu dispozitive semi-globale care să le permită înțelegerea și să sporească șansele de a rupe testele conexe. Șansele de a crea codul de calitate sunt stivuite împotriva noastră cu o astfel de abordare. Extragerea setării obișnuite a obiectului este, de asemenea, mai ușor de făcut prin metode vechi rubinii vechi sau chiar clase, dacă este necesar.

Acest lăsa creatura este o structură comună pe scară largă, care va trebui adesea descifrată mai întâi înainte de a ști exact ce afacere are acest obiect în testele tale. De asemenea, mergând înainte și înapoi pentru a înțelege de ce sunt făcute și despre relațiile pe care le au prin asociații poate fi o durere care consumă mult timp. 

Claritatea acestor detalii în configurația dvs. de testare ajută de obicei foarte mult să spună celorlalți dezvoltatori tot ce au nevoie pentru a lucra cu fiecare parte a suitei dvs. de testare - nu uitați de sinele dvs. viitor! Într-o lume în care niciodată nu trebuie să revizuiți anumite teste și niciodată niciodată părți refactorizate din suita dvs. de testare, aceasta ar putea să nu conteze atât de mult - dar asta este un vis de conducte pentru acum!

Vrem să avem cât mai puțini colaboratori și cât mai puține date posibil pentru fiecare test. lăsa lucrează împotriva ta și pe acest front. Aceste dispozitive de fixare pot acumula o mulțime de atribute și metode care le fac prea mari. 

Dacă începeți să mergeți pe drumul rutier, veți sfârși adesea cu obiecte destul de grase care încearcă să facă multe încercări fericite în același timp. Sigur că puteți crea o mulțime de variații ale acestora lăsa lucruri, dar asta face ca întreaga idee despre ele să fie puțin irelevantă, cred. De ce nu mergeți cu un pas mai departe, evitați să lăsați și să vă bazați pe Ruby fără magia RSpec DSL?

Sunt mai mult în tabără de a fi în partea de cod de configurare repetate pentru fiecare test decât să fiu prea uscat, obscur sau criptic în suita mea de testare. Intotdeauna mi-am dorit mai multa citire. Metoda de testare trebuie să clarifice cauza și efectul pieselor sale implicate - utilizarea colaboratorilor de obiecte care sunt eventual definiți departe de exercițiul de testare nu este în interesul dumneavoastră. Dacă aveți nevoie să extrageți chestii, utilizați metode expresive care încapsulează acele cunoștințe. 

Acestea sunt aproape întotdeauna un pariu sigur. În acest fel, puteți furniza configurația de care aveți de fapt nevoie pentru fiecare test și nu provoca teste lente deoarece aveți date inutile implicate. Vechile variabile vechi, metode și clase sunt adesea tot ceea ce aveți nevoie pentru a oferi teste mai rapide și mai stabile, care sunt mai ușor de citit. 

Oaspeții misteriali

Pasionații de mister sunt RSpec DSL-uri, într-adevăr. Pentru o vreme, diferitele obiecte definite prin RSpec DSL lăsa nu sunt atât de greu de ținut sub control, dar curând, când suita de testare crește, invitați o mulțime de oaspeți misterioși în specificațiile dvs. Acest lucru vă oferă sinele dvs. viitoare și altora care nu necesită puzzle-uri de context pentru a le rezolva. 

Rezultatul va fi un test obscur care vă cere să intrați în modul Sherlock Holmes complet. Cred că sună mult mai distractiv decât este. Linia de fund, este o pierdere a timpului tuturor.

Vizitatorii Mystery prezintă două întrebări problematice:

  • De unde vine acest obiect?
  • Din ce este compus?
descrie Misiunea nu da (: agent_01) build_stubbed (: agent, nume: 'James Bond', nr: '007') let (: agent_02) build_stubbed (agent, nume: 'Moneypenny'  let (: title) 'Moonraker' let (: misiune) build_stubbed (: misiune, titlu: titlu) mission.agents << agent_01 << agent_02… #lots of other tests describe '#top_agent' do it 'returns highest ranking agent associated to a mission' do expect(mission.top_agent).to eq('James Bond') end end end

Acest bloc descrie #top_agent lipsa clarității și a contextului. Care agent este implicat și despre ce misiune vorbim aici? Aceasta îi obligă pe dezvoltatori să meargă la vânătoare de obiecte care apar brusc în testele tale. 

Exemplul clasic al unui oaspete de mister. Când avem multe coduri între testul relevant și originea acestor obiecte, creșteți șansele de a observa ce se întâmplă în testele noastre.

Soluția este destul de ușoară: aveți nevoie de programe "proaspete" și construiți versiuni locale ale obiectelor cu exact datele de care aveți nevoie - și nu mai mult decât atât! Factory Factory este o alegere bună pentru manipularea acestui lucru. 

Această abordare poate fi considerată mai verbală și este posibil să copiați uneori chestii extragând într-o metodă este adesea o idee bună - dar este mult mai expresivă și menține testele concentrate în timp ce furnizează contextul.

descrieți Misiunea # # # # # # # # multe alte teste descriu '#top_agent' face 'returnează o listă a tuturor agenților asociați unei misiuni' agent_01 = build_stubbed (: agent, nume: 'James Bond' 007 ') agent_02 = build_stubbed (: agent, nume:' Moneypenny ', numărul' 243 ') mission = build_stubbed (: mission, title:' Moonraker ') mission.agents << agent_01 << agent_02 expect(mission.top_agent).to eq('James Bond') end end end

Exemplul de mai sus construiește toate obiectele necesare pentru testele noastre în cazul real de testare și oferă tot contextul dorit. Dezvoltatorul poate rămâne concentrat pe un anumit caz de testare și nu are nevoie să "descarce" un alt caz de testare, eventual complet independent, pentru a face față situației la îndemână. Fără obscuritate!

Da, aveți dreptate, această abordare înseamnă că nu atingem cel mai scăzut nivel de duplicare posibil, dar claritatea în aceste cazuri este mult mai importantă pentru calitatea suitei dvs. de testare și, prin urmare, pentru robustețea proiectului dvs. Viteza în care puteți aplica efectiv modificările testelor dvs. joacă, de asemenea, un rol în această privință. 

Un alt aspect important al testării este că suita dvs. de testare nu numai că poate funcționa ca documentație, dar trebuie absolut! Duplicarea zero nu este un obiectiv care are un efect pozitiv asupra specificațiilor care documentează aplicația dvs. Menținerea dublării inutile în cadrul controlului este, cu toate acestea, un obiectiv important de a ține evidența echilibrului!  

Teste obscure

Mai jos este un alt exemplu care încearcă să stabilească tot ceea ce aveți nevoie la nivel local în test, dar nu reușește, deoarece nu ne spune povestea completă.

... context "starea agentului" face "returnează starea agentului misiunii" face dublu_o_seven = build_stubbed (: agent) misiune = build_stubbed (: mission, agent: double_o_seven) sfârșitul final

Creăm un agent generic. De unde știm că e 007? De asemenea, testează pentru statutul agentului, dar nici nicăieri nu se găsește - nici în configurație, nici explicit în timpul fazei de verificare din aştepta afirmație. Relația dintre double_o_seven.status iar statutul misiunii ar putea fi confuz, de vreme ce vine din nicăieri într-adevăr. Putem face mai bine:

... context "starea agentului" face "returnează starea agentului misiunii" face dublu_o_seven = build_stubbed (: agent, nume: 'James Bond', status: 'Missing in action' double_o_seven) așteptați (mission.agent_status). la eq ("James Bond: Missing in action") final

Din nou, aici avem tot ce avem nevoie pentru a spune o poveste. Toate datele de care avem nevoie sunt chiar în fața noastră.

Teste rapide

Deci, ați început să intrați în Test-Driven-Development și ați început să apreciați ce oferă. Kudos, e grozav! Sunt sigur că nici decizia de a face acest lucru, nici curba de învățare pentru a ajunge acolo au fost exact o bucată de prăjitură. Dar ceea ce se întâmplă adesea după acest pas inițial este că încerci din greu să ai o acoperire completă a testelor și începi să-ți dai seama că ceva este oprit când viteza specificațiilor tale începe să te enerveze. 

De ce suita de testare devine mai lentă și mai lentă, deși credeți că faceți toate lucrurile potrivite? Simt un pic pedepsit pentru scrierea testelor? Testele lente suge-mare de timp! Există câteva probleme cu ei. Cea mai importantă problemă este că testele lente conduc la depășirea testelor pe termen lung. Odată ce vă aflați într-un punct în care suita dvs. de test durează pentru totdeauna pentru a termina, veți fi mult mai dispuși să vă gândiți la voi înșivă: "Înșurubați-i, îi voi conduce mai târziu! Am mai bine de făcut decât să aștept ca aceste lucruri să se termine. "Și ai dreptate, ai lucruri mai bune de făcut.

Lucrul este că testele lente sunt mai susceptibile de a saluta în compromisuri în ceea ce privește calitatea codului decât ar putea fi evident la început. Testele lentă, de asemenea, alimentează argumentele oamenilor împotriva TDD - nedrept, așa cred, cred. Nici măcar nu vreau să știu ce managerii de produse non-tehnice trebuie să spună dacă trebuie să ieșiți în mod regulat în afara unei pauze de cafea lungi pentru a rula suita de test înainte de a vă putea continua munca.

Să nu mergem pe drumul ăsta! Când aveți nevoie doar de puțin timp pentru a vă exercita testele și, ca rezultat, obțineți cicluri de feedback foarte rapide pentru dezvoltarea fiecărui pas al noilor caracteristici, practica TDD devine mult mai atractivă și mai puțin argumentată. Cu un pic de muncă și de îngrijire de-a lungul drumului, putem evita testele lent-mo destul de eficient. 

Testele lent sunt, de asemenea, un criminal pentru a intra în "zona". Dacă vă scoateți din flux acest lucru frecvent în procesul dvs., calitatea muncii dvs. de ansamblu ar putea suferi, de asemenea, de a aștepta pentru teste lent pentru a reveni dintr-o excursie scumpe scumpe. Vreți să obțineți cât mai mult timp în timpul zonei - testele inutil de lent sunt ucigașii de flux major.

O altă problemă care merită menționată în acest context este că acest lucru ar putea duce la efectuarea de teste care să vă acopere codul, dar pentru că nu veți avea timp să terminați exercițiile întregului suite sau să scrieți teste după fapt, designul aplicațiilor dvs. nu va fi condusă de teste. Dacă nu vă aflați pe trenul Hype Driven by Test, acest lucru nu vă deranjează prea mult, dar pentru TDD, acest aspect este esențial și nu trebuie neglijat. 

Linia de fund, cu cât testele sunt mai rapide, cu atât mai mult veți fi dispuși să le exersați - ceea ce este cel mai bun mod de a proiecta aplicații, precum și de a prinde bug-uri devreme și de multe ori. 

Ce putem face pentru a accelera testele? Există două viteze importante aici:

  • viteza în care testele tale îți pot executa cu adevărat suita
  • viteza de a obține feedback de la suita de testare pentru a proiecta aplicația

Evitați scrierea la baza de date cât mai mult posibil

Asta nu înseamnă că trebuie să eviți toate costurile. Adesea nu este nevoie să scrieți teste care să exercite baza de date și puteți să vă descurcați mult timp pe care trebuie să-l executați testele. Folosind doar nou pentru a instanțiza un obiect este adesea suficient pentru setările de testare. Efectuarea unor obiecte care nu sunt direct testate este o altă opțiune viabilă. 

Crearea de dubluri de testare este o modalitate frumoasă de a face testele mai rapide, păstrând în același timp obiectele colaborative de care aveți nevoie pentru configurarea super-concentrată și ușoară. Factory Factory vă oferă, de asemenea, diferite opțiuni pentru a "crea" inteligent datele dvs. de testare. Dar, uneori, nu există nicio modalitate de salvare în baza de date (ceea ce este mult mai rar decât v-ați putea aștepta), și exact aici trebuie să trasați linia. Oricând altădată, evitați ca și iadul și suita dvs. de testare va rămâne rapidă și agilă. 

În acest sens, ar trebui să urmăriți, de asemenea, o cantitate minimă de dependențe, ceea ce înseamnă cantitatea minimă de obiecte de care aveți nevoie să colaboreze pentru a face trecerile dvs. să treacă - salvând cât mai puțin posibil baza de date de-a lungul drumului. Eliminarea obiectelor - care sunt simple colaboratori și nu sunt direct testate - de multe ori face de asemenea configurarea dvs. mai ușor de digerat și mai simplu de creat. O viteză plăcută, cu un efort foarte mic.

Construiți-vă testele cu piramida de testare în minte

Aceasta înseamnă că doriți să aveți o majoritate de teste unitare în partea de jos a acestei ierarhii - care se concentrează pe părți foarte specifice ale aplicației dvs. în mod izolat - și cel mai mic număr de teste de integrare din partea de sus a acestei piramide. Testele de integrare simulează un utilizator care trece prin sistemul dvs. în timp ce interacționează cu o grămadă de componente care sunt exercitate în jurul aceleiași perioade. 

Ele sunt ușor de scris dar nu atât de ușor de întreținut - iar pierderile de viteză nu merită să meargă pe traseul ușor. Testele de integrare sunt aproape opusul testelor unitare în ceea ce privește nivelul ridicat și sugerea în multe componente pe care trebuie să le configurați în testele dvs. - ceea ce reprezintă un motiv major pentru care acestea sunt mai lent decât testele unitare. 

Cred că acest lucru clarifică de ce ar trebui să fie la vârful piramidei de testare pentru a evita pierderile semnificative de viteză. O altă problemă importantă aici este că doriți să aveți o suprapunere cât mai mică între aceste două categorii de încercări, în mod ideal - doriți, în mod ideal, să testați lucrurile doar o singură dată. Nu vă puteți aștepta la o separare perfectă, dar obiectivul pentru cât mai puțin posibil este un obiectiv rezonabil și realizabil.

În contrast cu testele de unitate, doriți să testați cât mai puține detalii cu ajutorul testelor de integrare. Mecanica interioară ar trebui să fie deja acoperită de teste de unitate extinse. În schimb, concentrați-vă numai asupra părților esențiale pe care interacțiunile trebuie să le poată exercita! Celălalt motiv principal este că un webdriver trebuie să simuleze trecerea printr-un browser și interacțiunea cu o pagină. Această abordare nu produce nimic sau foarte puțin, salvează lucrurile în baza de date și trece prin UI. 

Acesta este și motivul pentru care pot fi numiți teste de acceptare deoarece aceste teste încearcă să simuleze o experiență reală a utilizatorului. Aceasta este o altă lovitură de viteză majoră pe care doriți să o exercitați cât mai puțin posibil. Dacă aveți o tona din aceste teste - cred că mai mult de 10% din numărul total de teste - ar trebui să încetinești și să reduci acest număr la suma minimă posibilă. 

De asemenea, rețineți că, uneori, nu este necesar să exerciți întreaga aplicație - un test de vizualizare mai mic, concentrat, de multe ori face și trucul. Veți fi mult mai rapid dacă vă rescrieți câteva dintre testele de integrare care testează doar un pic de logică care nu necesită un control complet de integrare. Dar nu scrieți nici o tona din ele; ei oferă cel mai puțin bang pentru dolar. Acestea fiind spuse, testele de integrare sunt vitale pentru calitatea suita de testare și trebuie să găsiți un echilibru de a fi prea loviți cu ele și să nu aveți prea multe în jurul lor.

Obțineți feedback din aplicația dvs. și testează rapid

Feedback-ul rapid și ciclurile de repetare rapidă sunt cheia proiectării obiectelor. Odată ce începeți să evitați să executați frecvent aceste teste, pierdeți acest avantaj - ceea ce reprezintă un mare ajutor pentru proiectarea obiectelor. Nu așteptați până când serviciul dvs. de integrare continuă va alege pentru a testa întreaga aplicație. 

Deci, care este un număr magic care ar trebui să ne păstrăm în minte atunci când rulați testele? Diferiți oameni vă vor spune diferite valori de referință pentru acest lucru. Cred că rămânerea sub 30 de secunde este un număr foarte rezonabil, ceea ce face foarte probabil să exercite un test complet în mod regulat. Dacă lăsați acest punct de referință din ce în ce mai mult, unele refactorizări ar putea fi în ordine. Acesta va fi în valoare de ea și vă va face să vă simțiți mult mai confortabil, deoarece vă puteți verifica mai în mod regulat. Probabil că veți merge mult mai repede.

Vrei ca dialogul cu testele tale să fie cât mai rapid posibil. Înăsprirea acestui ciclu de feedback folosind un editor care poate efectua și testele dvs. nu trebuie subestimat. Trecerea înapoi și înapoi între editor și terminal este nu cea mai bună soluție pentru a face față acestei situații. Acest lucru devine foarte vechi foarte repede. 

Dacă vă place să utilizați Vim, aveți încă un motiv să investești ceva timp în a deveni mai eficient în utilizarea editorului. Există o mulțime de instrumente disponibile pentru Vim peeps. Îmi amintesc că textul Sublime oferă, de asemenea, să ruleze teste din interiorul editorului, dar, în afară de asta, trebuie să faci un pic de cercetare pentru a afla ce este posibil editorul dvs. în această privință. Argumentul pe care îl veți auzi frecvent de la entuziaștii TDD este că nu doriți să părăsiți editorul, deoarece în general veți petrece prea mult timp să faceți asta. Vrei să rămâi mult mai mult în zonă și să nu pierzi trenul de gândire atunci când poți face acest tip de lucru printr-o scurtătură rapidă din interiorul editorului de cod. 

Un alt lucru care trebuie luat în considerare este că, de asemenea, doriți să reușiți să tăiați testele pe care doriți să le executați. Dacă nu este nevoie să rulați întregul fișier, este bine să executați un singur test sau un bloc care se concentrează doar asupra a ceea ce aveți nevoie pentru a obține feedback-ul despre acum. Având comenzi rapide care vă ajută să efectuați teste individuale, fișiere unice sau doar ultimul test din nou vă salvează din nou o perioadă de timp și vă menține în zonă - să nu mai vorbim de gradul înalt de confort și senzația de super cool dandy. Este doar uimitor cât de minunate instrumente de codare pot fi uneori.

Un ultim lucru pentru drum. Utilizați un preloader ca Spring. Veți fi surprins de cât de mult timp vă puteți rade atunci când nu trebuie să încărcați Rails pentru fiecare încercare. Aplicația dvs. va rula în fundal și nu are nevoie să se încarce tot timpul. Fă-o!

Programe

Nu sunt sigur dacă programele sunt încă o problemă pentru începătorii care vin pe terenul Ruby / Rails. În cazul în care nimeni nu te-a instruit despre ele, voi încerca să te ridic în viteză într-o clipă pe aceste lucruri temute. 

Seturile de baze de date ActiveRecord sunt exemple excelente de a avea tone de oaspeți Mystery în suita dvs. de testare. În primele zile ale Rails și Ruby TDD, corpurile YAML erau standardul de facto pentru stabilirea datelor de testare în aplicația dvs. Aceștia au jucat un rol important și au contribuit la avansarea industriei. În ziua de azi, au un rău în mod rezonabil rău.

YAML Luminări

Manager de carieră: nume: Q favorite_gadget: Abilități de radio cu burete: inventarea gizmosului și a hacking-ului 00Agent: nume: James Bond favorite_gadget: Abilitățile Lotus Esprit submarin: Obținerea de fete Bond ucise și infiltrarea ascunsă

Structura de tipul hash pare a fi ușor de utilizat și ușor de utilizat. Puteți chiar să faceți referire la alte noduri dacă doriți să simulați asocieri din modelele dvs. Dar acolo se opreste muzica si multi spun ca durerea lor incepe. Pentru seturile de date care sunt puțin mai implicate, dispozitivele YAML sunt greu de întreținut și greu de schimbat fără a afecta alte teste. Vreau să spun, le puteți face să funcționeze, bineînțeles - în cele din urmă, dezvoltatorii le-au folosit mult în trecut - dar tone de dezvoltatori vor fi de acord că prețul care trebuie plătit pentru gestionarea programelor este doar un pic zgârcit.

Un scenariu pe care cu siguranță ne dorim să-l evităm schimbă puțin detalii despre un echipament existent și provoacă eșecuri de teste. Dacă aceste teste eșuate nu au nicio legătură, situația este și mai gravă - un bun exemplu de teste care sunt prea fragile. Pentru a "proteja" testele existente din acest scenariu, acest lucru poate duce și la creșterea setului dvs. de fixare dincolo de orice dimensiune rezonabilă - fiind uscat cu dispozitive de fixare, cel mai probabil nu mai este pe masă la acel moment. 

Pentru a evita ruperea datelor de testare atunci când apar modificările inevitabile, dezvoltatorii au fost bucuroși să adopte strategii mai noi care să ofere o mai mare flexibilitate și comportament dinamic. Aici a intrat Factory Girl și a sărutat la revedere ziua YAML. 

O altă problemă este dependența grea între test și fișierul de fixare. Din moment ce fișierele sunt definite într-un fișier separat .yml, oaspeții misterios sunt, de asemenea, o durere majoră care așteaptă să te muște din cauza faptului că ești obscur. Am menționat că programele sunt importate în baza de date de testare fără a trece prin nici o validare și nu aderă la ciclul de viață Active Record? Da, și asta nu e minunat - din orice unghi pe care vrei să-l privești! 

Factory Factory vă permite să evitați toate acestea prin crearea obiectelor relevante pentru testele inline - și numai cu datele necesare pentru acel caz specific. Motto-ul este, definiți doar minimul din definițiile dvs. din fabrică și adăugați restul pe baza testului. Pe plan local (în testele dvs.) valorile prestabilite definite în fabricile dvs. reprezintă o abordare mult mai bună decât a avea tone de unicornuri de fixare care așteaptă să fie depășite într-un fișier de fixare. 

Această abordare este și mai scalabilă. Factory Factory vă oferă o mulțime de instrumente pentru a crea toate datele de care aveți nevoie - nuanțate după cum doriți - dar vă oferă și tone de muniții pentru a rămâne uscate acolo unde este nevoie. Argumentele pro și contra sunt bine echilibrate cu această bibliotecă, cred. Nu se ocupă de validări, de asemenea, nu mai este un motiv de îngrijorare. Cred că folosirea modelului fabricii pentru datele testului este mai mult decât destul de rezonabil și este unul dintre motivele pentru care Factory Girl a fost atât de bine primit de comunitate. 

Complexitatea este un dușman în creștere rapidă pe care dispozitivele YAML nu mai sunt echipate pentru a le prelua eficient. Într-un fel, mă gândesc la programe ca lăsa pe steroizi. Nu le puneți doar mai departe - fiind într-un fișier separat și toate - de asemenea, este posibil să preîncărcați mai multe programe decât ar fi nevoie de fapt. RIP!

Încercări delicate

Dacă modificările specificațiilor dvs. duc la apariția unor neconcordanțe în alte teste, probabil vă uitați la o suită de testare care a devenit fragilă din cauza cauzelor menționate mai sus. Aceste testări, adesea legate de puzzle-uri, mister-invitați, conduc cu ușurință la o casă instabilă de cărți. 

Atunci când obiectele necesare pentru teste sunt definite "departe" de scenariul real de încercare, nu este greu de trecut cu vederea relațiile pe care aceste obiecte le au cu testele lor. Când codul se șterge, ajustează sau pur și simplu obiectul de configurare în cauză devine accidental suprascris - nu știe cum ar putea influența alte teste în jurul valorii de-testele nu sunt o întâlnire rară. Ele apar ușor ca eșecuri cu totul independente. Cred că este corect să includem astfel de scenarii în categoria codului cuplat strâns.

descrie Misiunea do (): build_stubbed (: agent, nume: 'James Bond', numărul: '007') let (: title) 'Moonraker' : title]) # # # # # # # # multe alte teste descriu '#joint_operation_agent_name' do (: agent) build_stubbed (: agent, nume: 'Felix Leiter' << agent it “returns mission's joint operation's agent name” do expect(mission.joint_operation_agent_name).to eq('Felix Leiter') end end end

În acest scenariu, am modificat în mod clar la nivel local starea unui obiect care a fost definită în configurația noastră. agent în discuție este acum un operativ al CIA și are un nume diferit. misiune vine iarăși din nicăieri. Nimic lucruri, într-adevăr. 

Nu este o surpriză când alte teste care se bazează, eventual, pe o altă versiune agent începe să arunce în aer. Să scăpăm de lăsa prostii și să construim obiectele de care avem nevoie din nou acolo unde le testăm - cu doar atributele de care avem nevoie pentru test, bineînțeles. 

descrie Misiunea nu # # # # # # # #de alte teste descriu '#joint_operation_agent_name' do agent = build_stubbed (: agent, nume: 'Felix Leiter', agency: 'CIA') misiune = build_stubbed << agent it “returns mission's joint operation's agent name” do expect(mission.joint_operation_agent_name).to eq('Felix Leiter') end end end

Este important să înțelegeți modul în care sunt legate obiectele - în mod ideal, cu valoarea minimă a codului de instalare. Nu vrei să trimiți alți dezvoltatori pe o urmărire sălbatică de gâscă pentru a-ți da seama de chestiile astea atunci când se împiedică codul tău. 

Dacă este foarte greu să înțelegi rapid și o nouă caracteristică trebuie implementată ieri, aceste puzzle-uri nu se pot aștepta să primească cea mai mare prioritate. Aceasta, la rândul său, adesea înseamnă că se dezvoltă lucruri noi pe lângă acel context neclar - care este o bază fragilă pentru a merge mai departe și, de asemenea, super-invitând pentru bug-uri pe drum. Lecția pe care trebuie să o luați aici nu este să suprascrieți lucrurile acolo unde este posibil.

Atribute de date

Un sfat util final pentru evitarea testelor fragile este utilizarea atributelor de date în etichetele dvs. HTML. Doar fă-ți o favoare și folosește-le-mi poți mulțumi mai târziu. Acest lucru vă permite să decuplați elementele necesare pentru testare de la informațiile de styling pe care designerii dvs. le-ar putea atinge frecvent fără implicarea dvs.. 

Dacă codificați greu o clasă ca class = „misiune împachetarea“ în testul dvs. și un designer inteligent decide să schimbe acest nume sărac, testul dvs. va fi afectat în mod inutil. Și designerul nu este de vină, desigur. Cum ar ști în lume că acest lucru afectează o parte din suita ta de testare - foarte puțin probabil, cel puțin. 

 

<% = @mission.agent_status %>

...
 context "starea agentului misiunii" face "face ceva cu o misiune" ... așteptați (pagina) .to have_css '[data-role = single-mission]

Ne așteptăm să vedem un element HTML pe o pagină și să-l marchezi cu un date-rol. Designerii nu au nici un motiv să atingă acest lucru, iar dvs. sunteți protejați împotriva testelor fragile care se întâmplă datorită schimbărilor de pe partea de styling a lucrurilor. 

Este o strategie destul de eficientă și utilă care practic nu vă costă nimic în schimb. Singurul lucru care ar putea fi necesar este să aveți o scurtă conversație cu designerii. Bucată de tort!

Gândurile finale

Vrem să evităm distragerea oamenilor care vor citi testele noastre sau, chiar mai rău, să le confunde. Aceasta este deschiderea ușii pentru bug-uri, dar poate fi, de asemenea, costisitoare, deoarece poate costa timp prețios și putere creierului. Când creați testele, încercați din greu să nu suprascrieți lucrurile - nu ajută la crearea clarității. Este mult mai probabil ca aceasta să conducă la bug-uri subtile, care consumă timp și nu va afecta aspectul documentării pozitive a codului. 

Acest lucru creează o povară inutilă pe care o putem evita. Mutând datele de testare mai mult decât absolut necesare este, de asemenea, merită să fie un pic paranoic despre. Păstrați-o cât mai simplă posibil! Acest lucru vă ajută cu adevărat să evitați să trimiteți alți dezvoltatori sau viitoarele dvs. sine în urma urmăririlor de gâscă sălbatică. 

Mai sunt multe de învățat despre lucrurile pe care trebuie să le eviți în timp ce testezi, dar cred că este un început bun. Oamenii care sunt destul de noi pentru toate lucrurile TDD ar trebui să poată trata aceste câteva AntiPatterni imediat înainte de a se scufunda în ape mai avansate.

Cod