O călătorie de testare E2E Partea 2: WebdriverIO la Cypress
Publicat: 2019-11-21Notă: aceasta este o postare de la #frontend@twiliosendgrid. Pentru alte postări de inginerie, accesați lista blogului tehnic.
În toate aplicațiile noastre frontend, am avut și avem în continuare următorul obiectiv: să oferim o modalitate de a scrie teste de automatizare E2E consistente, depanabile, care pot fi întreținute și valoroase pentru aplicațiile noastre frontend și să ne integrăm cu CICD (integrare continuă). și desfășurare continuă).
Pentru a ajunge la starea pe care o avem astăzi în care sute de teste E2E sunt posibil declanșate sau rulează într-un program în toate echipele noastre de front-end din SendGrid, a trebuit să cercetăm și să experimentăm o mulțime de soluții potențiale de-a lungul drumului până când am îndeplinit acel principal poartă.
Am încercat să lansăm propria noastră soluție personalizată Ruby Selenium dezvoltată de ingineri de testare dedicați, numită SiteTestUI aka STUI, în care toate echipele ar putea contribui la un singur repo și să ruleze teste de automatizare între browsere. Din păcate, a cedat în fața unor teste lente, nerezolvate, alarme false, lipsă de context între repoziții și limbi, prea multe mâini într-un singur coș, experiențe dureroase de depanare și mai mult timp petrecut pentru întreținere decât pentru a oferi valoare.
Am experimentat apoi cu o altă bibliotecă promițătoare în WebdriverIO pentru a scrie teste în JavaScript colocate cu depozitele de aplicații ale fiecărei echipe. În timp ce acest lucru a rezolvat unele probleme, a împuternicit mai multă conducere a echipei și ne-a permis să integrăm teste cu Buildkite, furnizorul nostru CICD, am avut totuși teste nerezolvate care erau dureroase de depanat și greu de scris, în plus față de problemele și ciudateniile prea asemănătoare ale seleniului. .
Am vrut să evităm un alt STUI 2.0 și am început să explorăm alte opțiuni. Dacă doriți să citiți mai multe despre lecțiile noastre învățate și strategiile descoperite pe parcurs atunci când migrați de la STUI la WebdriverIO, consultați partea 1 a seriei de postări pe blog.
În această parte finală a doua a seriei de postări pe blog, vom acoperi călătoria noastră de la STUI și WebdriverIO la Cypress și cum am trecut prin migrări similare în configurarea infrastructurii generale, scrierea de teste E2E organizate, integrarea cu conductele noastre Buildkite și scalarea la alte echipe de front-end din organizație.
TLDR: Am adoptat Cypress peste STUI și WebdriverIO și ne-am îndeplinit toate obiectivele de a scrie teste E2E valoroase pentru a le integra cu CICD. Multe din munca noastră și lecțiile învățate de la WebdriverIO și STUI au fost transmise frumos în modul în care folosim și integrăm testele Cypress astăzi.
Cuprins
Explorarea și aterizarea pe Cypress
Trecerea de la STUI și WebdriverIO la Cypress
Pasul 1: Instalarea dependențelor pentru Cypress
Pasul 2: Configurații de mediu și scripturi
Prima trecere a Configurațiilor și Scripturilor de mediu
Evoluția configurațiilor și scripturilor de mediu
Pasul 3: Implementarea testelor E2E la nivel local
Pasul 4: Dockerizarea testelor
Pasul 5: Integrarea cu CICD
Pasul 6: Compararea Cypress cu WebdriverIO/STUI
Pasul 7: Scalare la alte echipe front-end
Ce așteptăm cu nerăbdare cu Cypress
Adoptarea Cypress în viitor
Explorarea și aterizarea pe Cypress
Când am căutat alternative la WebdriverIO, am văzut și alte pachete Selenium, cum ar fi Protractor și Nightwatch, cu o caracteristică similară cu WebdriverIO, dar am simțit că cel mai probabil ne vom confrunta cu setări lungi, teste nerezolvate și depanare și întreținere plictisitoare pe drum.
Din fericire, am dat peste un nou cadru de testare E2E numit Cypress, care a prezentat setări rapide, teste rapide și de depanare efectuate în browser, blocarea solicitărilor de nivel de rețea și, cel mai important, nu folosirea Selenium sub capotă.
Ne-am minunat de funcții extraordinare, cum ar fi înregistrările video, interfața Cypress GUI, serviciul de tablou de bord plătit și paralelizarea pentru a le încerca. Am fost dispuși să facem compromisuri în ceea ce privește compatibilitatea între browsere în favoarea testelor valoroase care trec în mod constant împotriva Chrome, cu un repertoriu de instrumente la dispoziție pentru a implementa, depana și menține testele pentru dezvoltatorii și QA-urile noștri.
De asemenea, am apreciat cadrele de testare, bibliotecile de afirmații și toate celelalte instrumente alese pentru a avea o abordare mai standardizată a testelor în toate echipele noastre de front-end. Mai jos, am oferit o captură de ecran a diferențelor dintre o soluție precum WebdriverIO și Cypress și dacă doriți să vedeți mai multe dintre diferențele dintre soluțiile Cypress și Selenium, puteți consulta documentația lor despre cum funcționează.
Având în vedere acest lucru, ne-am angajat să testăm Cypress ca o altă soluție pentru scrierea de teste E2E rapide, consistente și depanabile, care să fie eventual integrate cu Buildkite în timpul CICD. De asemenea, ne-am stabilit în mod deliberat un alt obiectiv de a compara Cypress cu soluțiile anterioare bazate pe seleniu pentru a determina în cele din urmă prin puncte de date dacă ar trebui să continuăm să căutăm sau să construim suitele noastre de testare cu Cypress în viitor. Am plănuit să convertim testele WebdriverIO existente și orice alte teste cu prioritate ridicată încă în STUI în teste Cypress și să comparăm experiențele dezvoltatorilor, viteza, stabilitatea, timpul de rulare a testelor și întreținerea testelor.
Trecerea de la STUI și WebdriverIO la Cypress
La trecerea de la STUI și WebdriverIO la Cypress, am abordat-o sistematic prin aceeași strategie de nivel înalt pe care am folosit-o atunci când am încercat migrarea de la STUI la WebdriverIO în depozitele noastre de aplicații frontend. Pentru mai multe detalii despre cum am realizat astfel de pași pentru WebdriverIO, vă rugăm să consultați partea 1 a seriei de postări pe blog. Pașii generali pentru tranziția la Cypress au implicat următorii:
- Instalarea și configurarea dependențelor pentru conectarea cu Cypress
- Stabilirea configurațiilor de mediu și a comenzilor de scripturi
- Implementarea testelor E2E care trec local în diferite medii
- Dockerizarea testelor
- Integrarea testelor Dockerized cu Buildkite, furnizorul nostru CICD
Pentru a ne îndeplini obiectivele secundare, am adăugat și pași suplimentari pentru a compara Cypress cu soluțiile anterioare Selenium și, în cele din urmă, pentru a extinde Cypress în toate echipele de front-end din organizație:
6. Compararea Cypress în ceea ce privește experiențele dezvoltatorilor, viteza și stabilitatea testelor față de WebdriverIO și STUI
7. Scalare la alte echipe de front-end
Pasul 1: Instalarea dependențelor pentru Cypress
Pentru a începe și a funcționa rapid cu Cypress, tot ce trebuia să facem a fost `npm install cypress` în proiectele noastre și să pornim Cypress pentru prima dată, pentru ca acesta să fie așezat automat cu un fișier de configurare `cypress.json` și un folder cypress
. cu instalații de pornire, teste și alte fișiere de configurare pentru comenzi și pluginuri. Am apreciat modul în care Cypress a venit la pachet cu Mocha ca testator, Chai pentru afirmații și Chai-jQuery și Sinon-Chai pentru și mai multe afirmații de folosit și de înlănțuit. Nu mai trebuia să petrecem timp considerabil pentru a cerceta ce biblioteci de testare, reporter, aserțiuni și servicii să instalăm și să folosim, în comparație cu când am început prima dată cu WebdriverIO sau STUI. Am rulat imediat unele dintre testele generate cu interfața lor Cypress și am explorat numeroasele funcții de depanare pe care le avem la dispoziție, cum ar fi depanarea călătoriei în timp, spațiul de joacă pentru selector, videoclipurile înregistrate, capturile de ecran, jurnalele de comandă, instrumentele pentru dezvoltatori de browser etc.
De asemenea, l-am configurat mai târziu cu Eslint și TypeScript pentru verificarea statică a tipului și regulile de formatare de urmat atunci când comitem noul cod de testare Cypress. Am avut inițial unele probleme cu suportul TypeScript și unele fișiere trebuiau să fie fișiere JavaScript, cum ar fi cele centrate în jurul fișierelor plugin-uri, dar în cea mai mare parte am reușit să tastam verificați majoritatea fișierelor noastre pentru testele, obiectele paginii și comenzile noastre.
Iată un exemplu de structură de foldere pe care una dintre echipele noastre de front-end a urmat-o pentru a încorpora obiecte de pagină, pluginuri și comenzi:
Pasul 2: Configurații de mediu și scripturi
După ce am instalat și configurat rapid Cypress pentru a rula local, am avut nevoie de o modalitate prin care testele noastre Cypress să ruleze cu setări diferite pentru fiecare mediu și am vrut să acceptăm aceleași cazuri de utilizare pe care ni le permiteau comenzile noastre WebdriverIO. Iată o listă care ilustrează majoritatea cazurilor de utilizare a modului în care am dorit să executăm aceste teste și de ce am dorit să le susținem:
- Împotriva unui server de dezvoltare Webpack care rulează pe localhost (adică http://localhost:8000) și acel server dev ar fi îndreptat către un anumit mediu API (adică https://testing.api.com sau https://staging.api. com) ca testarea sau montarea în scenă.
De ce? Uneori trebuie să facem modificări aplicației noastre web locale, cum ar fi adăugarea de selectoare mai specifice pentru testele noastre, pentru a interacționa cu elementele într-un mod mai robust sau eram în curs de dezvoltare a unei noi funcții și trebuia să ajustem și să validăm testele de automatizare existente. ar trece la nivel local împotriva noilor noastre modificări de cod. Ori de câte ori codul aplicației s-a schimbat și nu am ajuns încă la mediul implementat, am folosit această comandă pentru a ne rula testele pe aplicația noastră web locală. - Împotriva unei aplicații implementate pentru un anumit mediu (adică https://testing.app.com sau https://staging.app.com), cum ar fi testarea sau staging
De ce? Alteori, codul aplicației nu se schimbă, dar este posibil să fie nevoiți să ne modificăm codul de testare pentru a remedia unele deficiențe sau ne simțim suficient de încrezători pentru a adăuga sau șterge teste cu totul fără a face nicio modificare de front-end. Am folosit această comandă în mod intens pentru a actualiza sau a depana testele la nivel local împotriva aplicației implementate pentru a simula mai îndeaproape modul în care testele noastre rulează în CICD. - Rularea într-un container Docker pe o aplicație implementată pentru un anumit mediu, cum ar fi testarea sau pregătirea
De ce? Acest lucru este destinat CICD, astfel încât să putem declanșa testele E2E care să fie rulate într-un container Docker, de exemplu, împotriva aplicației implementate în staging și să ne asigurăm că acestea trec înainte de implementarea codului în producție sau în rulări de testare programate într-o conductă dedicată. Când am configurat inițial aceste comenzi, am efectuat multe încercări și erori pentru a porni containerele Docker cu diferite valori ale variabilelor de mediu și a testat pentru a vedea testele corecte executate cu succes înainte de a le conecta cu furnizorul nostru CICD, Buildkite.
Prima trecere a Configurațiilor și Scripturilor de mediu
Când am experimentat prima dată cu configurarea Cypress, am făcut-o în repo-ul care acoperă https://app.sendgrid.com, o aplicație web care include pagini cu caracteristici precum Autentificarea expeditorului, Activitatea e-mailului și Validarea e-mailului și inevitabil am împărtășit descoperirile și învățările noastre cu echipele din spatele aplicației noastre web Campanii de marketing, care cuprinde domeniul https://mc.sendgrid.com. Am dorit să rulăm testele noastre E2E în mediul nostru de pregătire și am folosit interfața de linie de comandă a Cypress și opțiuni precum --config
sau --env
pentru a realiza cazurile noastre de utilizare.
Pentru a rula testele Cypress pe aplicația web local, de exemplu, pe http://127.0.0.1:8000
sau împotriva adresei URL a aplicației de instalare implementate, am ajustat indicatorul de configurare baseUrl
în comandă și am adăugat variabile de mediu suplimentare, cum ar fi testEnv
pentru a ajuta încărcați anumite dispozitive sau date de testare specifice mediului în testele noastre Cypress. De exemplu, cheile API utilizate, utilizatorii create și alte resurse pot fi diferite în funcție de mediu. Am folosit testEnv
pentru a comuta acele dispozitive sau pentru a adăuga o logică condiționată specială dacă unele caracteristici nu erau acceptate într-un mediu sau configurarea de testare diferă și am accesa mediul printr-un apel precum Cypress.env(“testEnv”)
în specificațiile noastre.
Am organizat apoi comenzile noastre cypress:open:*
pentru a reprezenta deschiderea interfeței interfața de utilizare Cypress pentru a ne selecta testele pentru a rula prin interfața de utilizare atunci când am dezvoltat local și cypress:run:*
pentru a indica executarea testelor în modul headless, care a fost mai adaptat. pentru rularea într-un container Docker în timpul CICD. Ceea ce a venit după open
sau run
ar fi mediul, astfel încât comenzile noastre s-ar citi cu ușurință ca npm run cypress:open:localhost:staging
pentru a deschide GUI și a rula teste pe un server local de dezvoltare Webpack care indică API-uri de staging sau npm run cypress:run:staging
pentru a rula teste în modul headless împotriva aplicației de staging implementate și a API-ului. Scripturile package.json
Cypress au apărut astfel:
Evoluția configurațiilor și scripturilor de mediu
Într-un alt proiect, ne-am evoluat comenzile și configurațiile Cypress pentru a profita de o anumită logică Node din fișierul cypress/plugins/index.js
pentru a avea un fișier de bază cypress.json
și fișiere de configurare separate care ar fi citite pe baza unei variabile de mediu numite configFile
pentru a încărca un anumit fișier de configurare. Fișierele de configurare încărcate vor fi apoi îmbinate cu fișierul de bază pentru a indica în cele din urmă către un server de backend simulat.
În cazul în care vă întrebați mai multe despre serverul backend simulat, am dezvoltat un server Express cu puncte finale backend care returnează pur și simplu răspunsuri variate de date JSON statice și coduri de stare (adică 200, 4XX, 5XX) în funcție de parametrii de interogare trecuți în solicitări. Acest lucru a deblocat interfața pentru a continua dezvoltarea fluxurilor de pagini cu apeluri de rețea reale către serverul de backend simulat, cu răspunsuri care emulează cum va arăta API-ul real când va fi disponibil în viitor. De asemenea, am putea simula cu ușurință diferite niveluri de succes și răspunsuri de eroare pentru diferitele noastre stări ale interfeței de utilizare, care altfel ar fi greu de reprodus în producție și, deoarece am efectua apeluri de rețea deterministe, testele noastre Cypress ar fi mai puțin nesigure în declanșarea aceleiași rețele. cereri și răspunsuri de fiecare dată.
Aveam un fișier cypress.json
de bază care includea proprietăți partajate pentru timeout-uri generale, ID-ul proiectului pentru a conecta Cypress Dashboard Service despre care vom vorbi mai târziu și alte setări, așa cum se arată mai jos:
Am creat un folder de config
în folderul cypress
pentru a păstra fiecare dintre fișierele noastre de configurare, cum ar fi localhostMock.json
, pentru a rula serverul nostru de dezvoltare Webpack local pe un server API simulat local sau staging.json
pentru a rula pe aplicația și API-ul de staging implementate. Aceste fișiere de configurare care urmează să fie diferite și îmbinate cu configurația de bază arătau astfel:
Fișierele de configurare CICD aveau un fișier JSON și mai simplu, deoarece trebuia să setăm variabilele de mediu în mod dinamic pentru a ține cont de URL-ul de bază de bază al serviciului Docker și de gazdele API de server simulate pe care le vom cerceta mai târziu.
În fișierul nostru cypress/plugins/index.js
, am adăugat o logică pentru a citi o variabilă de mediu numită configFile
set dintr-o comandă Cypress care ar citi în cele din urmă fișierul corespunzător din folderul de config
și l-ar îmbina cu cypress.json
de bază, cum ar fi mai jos:
Pentru a scrie comenzi Cypress sensibile cu variabile de mediu setate pentru cazurile noastre de utilizare, am profitat de un Makefile
care seamănă cu următorul:
Cu aceste comenzi bine aranjate într-un Makefile, am putea face rapid lucruri precum make cypress_open_staging
sau make cypress_run_staging
în scripturile noastre `package.json` npm.
Înainte, obișnuiam să plasăm câteva comenzi într-o singură linie lungă care ar fi dificil de editat fără eroare. Din fericire, Makefile a ajutat la răspândirea mult mai bine a lucrurilor cu interpolarea lizibilă a variabilelor de mediu în comenzile Cypress pe mai multe linii. Am putea seta sau exporta rapid variabile de mediu, cum ar fi configFile
pentru ce fișier de configurare a mediului să încărcăm, BASE_URL
pentru a ne vizita paginile, API_HOST
pentru diferite medii de backend sau SPECS
pentru a determina ce teste să rulăm înainte de a lansa oricare dintre comenzile Makefile.
De asemenea, am folosit comenzi Makefile pentru alte scripturi npm lungi și comenzi Docker, precum construirea activelor noastre Webpack, instalarea dependențelor sau rularea comenzilor concomitent cu altele. În cele din urmă, vom traduce câteva comenzi Makefile în secțiunea de scripturi package.json
, deși acest lucru nu era necesar dacă cineva dorea să folosească doar Makefile și ar arăta astfel:
Am omis în mod intenționat multe dintre comenzile Cypress CICD, deoarece nu erau comenzi care ar fi utilizate în dezvoltarea de zi cu zi și, ca rezultat, au menținut package.json
mai eficient. Cel mai important, am putea vedea dintr-o privire imediat toate comenzile Cypress legate de serverul simulat și serverul de dezvoltare Webpack local față de mediile de realizare și care „deschid” interfața grafică mai degrabă decât „rulează” în modul fără cap.
Pasul 3: Implementarea testelor E2E la nivel local
Când am început să implementăm teste E2E cu Cypress, ne-am referit la testele noastre existente de la WebdriverIO și STUI pentru a converti și am adăugat teste mai noi pentru alte funcții cu prioritate ridicată, de la simple verificări de sănătate la fluxuri complicate de drum fericit. Traducerea obiectelor de pagină existente și a fișierelor de testare din WebdriverIO sau STUI în obiecte de pagină și specificații echivalente în Cypress s-a dovedit a fi o ușoară. De fapt, a rezultat un cod mult mai curat decât înainte, cu o așteptare mai puțin explicită a elementelor și o mai bună înlănțuire a afirmațiilor și a altor comenzi Cypress.
De exemplu, pașii generali ai testelor au rămas aceiași din perspectiva utilizatorului final, așa că munca de conversie a implicat maparea API-ului WebdriverIO sau STUI la API-ul Cypress în următoarele moduri:
- O mulțime de comenzi au apărut și au funcționat în esență similar cu punctul în care aproape doar înlocuiam
$
saubrowser
-ul cucy
sauCypress
, accesând o pagină prin$(“.button”).click()
tocy.get(“.button”).click()
,browser.url()
lacy.visit()
sau$(“.input”).setValue()
lacy.get(“.input”).type()
- Folosind
$
sau$$
, de obicei transformat într-uncy.get(...)
saucy.contains(...)
adică$$(“.multiple-elements-selector”)
sau$(“.single-element-selector”)
transformat încy.get(“.any-element-selector”)
,cy.contains(“text”)
saucy.contains(“.any-selector”)
- Eliminarea apelurilor străine
$(“.selector”).waitForVisible(timeoutInMs)
,$(“.selector”).waitUntil(...)
sau$(“.selector”).waitForExist()
în favoarea permiterii implicite a Cypress gestionați reîncercările și preluarea elementelor din nou și din nou cucy.get('.selector')
șicy.contains(textInElement)
. Dacă am avea nevoie de un timeout mai lung decât cel implicit, am folosicy.get('.selector', { timeout: longTimeoutInMs })
cu totul și apoi, după preluarea elementului, vom înlănțui următoarea comandă de acțiune pentru a face ceva cu elementul, adicăcy.get(“.selector”).click()
. - Comenzi personalizate cu browser.
addCommand('customCommand, () => {})` turned into `Cypress.Commands.add('customCommand', () => {})
și făcând `cy.customCommand()` - Efectuarea cererilor de rețea pentru configurare sau demontare prin API folosind o bibliotecă numită
node-fetch
și împachetarea acesteia înbrowser.call(() => return fetch(...))
și/saubrowser.waitUntil(...)
a condus la efectuarea de solicitări HTTP pe un server Cypress Node princy.request(endpoint)
sau un plugin personalizat pe care l-am definit și efectuat apeluri precumcy.task(taskToHitAPIOrService)
. - Înainte, când trebuia să așteptăm ca o solicitare importantă de rețea să se termine, eventual fără modificări notabile ale UI, a trebuit uneori să recurgem la utilizarea
browser.pause(timeoutInMs)
, dar cu Cypress am îmbunătățit asta cu funcționalitatea de blocare a rețelei și am putut să ascultăm. și așteptați ca cererea specifică să se termine cucy.server()
,cy.route(“method”, “/endpoint/we/are/waiting/for).as(“endpoint”)`, and `cy.wait(“@endpoint”)
înainte de a începe acțiunea care ar declanșa solicitarea.
După ce am tradus o mulțime de sintaxe și comenzi WebdriverIO în comenzi Cypress, am adus același concept de a avea un obiect de pagină de bază pentru funcționalitate comună partajată și obiecte de pagină extinse pentru fiecare pagină pe care am solicitat-o pentru teste. Iată un exemplu de obiect de pagină de bază cu o funcționalitate comună open()
pentru a fi partajat în toate paginile.
Un obiect de pagină extins ar adăuga gettere pentru selectorii de elemente, ar implementa funcționalitatea open()
cu ruta paginii și ar oferi orice funcționalitate de ajutor, așa cum se arată mai jos.
Obiectele noastre reale ale paginii extinse au folosit, de asemenea, o hartă de obiecte simplă pentru a menține toți selectorii CSS de elemente într-un singur loc, pe care le-am conecta la componentele noastre React ca atribute de date, referință în testele unitare și le-am folosi ca selectoare în obiectele paginii Cypress. De asemenea, clasele noastre de obiecte de pagină au variat uneori pentru a profita de constructorul de clasă dacă să spunem că un obiect de pagină a fost reutilizat pentru o grămadă de pagini similare cu aspect și funcționare, cum ar fi paginile noastre Suppressions și am transmite argumente pentru a schimba ruta sau proprietăți specifice.
Ca o notă secundară, echipele nu au trebuit să folosească obiecte de pagină, dar am apreciat consistența modelului pentru păstrarea funcționalității paginii și a referințelor selectorului de elemente DOM împreună cu o structură standard a obiectelor de clasă pentru a partaja funcționalitatea comună în toate paginile. Alte echipe au preferat să creeze multe fișiere diferite, cu funcții de utilitate reduse și fără utilizarea claselor ES6, dar lucrul important de luat a fost să ofere o modalitate organizată, previzibilă de a încapsula totul și de a scrie teste pentru o mai bună eficiență și întreținere a dezvoltatorului.
Am aderat la aceeași strategie generală de testare folosită cu testele noastre mai vechi WebdriverIO, încercând să setăm testul cât mai mult posibil prin API. Am vrut în special să evităm construirea stării noastre de configurare prin interfața de utilizare pentru a nu introduce slăbiciune și timp pierdut pentru piesele pe care nu ne-am propus să le testăm. Cele mai multe teste au implicat această strategie:
- Configurarea sau dezafectarea prin API – Dacă ar fi nevoie să testăm crearea unei entități prin UI, ne-am asigura că ștergem mai întâi entitatea prin API. Indiferent de modul în care testul anterior a avut succes sau eșec, testul trebuia configurat sau desființat corespunzător prin API pentru a se asigura că testul se comportă într-o manieră consecventă și începe cu condițiile potrivite.
- Conectarea la un utilizator de testare dedicat prin API – Am creat utilizatori de testare dedicați pe pagină sau chiar pe test de automatizare, astfel încât testele noastre să fie izolate și să nu calmeze resursele unul altuia atunci când sunt rulate în paralel. Am făcut aceeași solicitare ca pagina noastră de conectare prin API și am stocat cookie-ul înainte de începerea testului, astfel încât să putem vizita direct pagina autentificată și să începem pașii de testare propriu-zis.
- Automatizarea pașilor din perspectiva utilizatorului final – După ce ne-am conectat la utilizator prin intermediul API-ului, am vizitat pagina direct și am automatizat pașii pe care i-ar face utilizatorul final pentru a finaliza un flux de caracteristici și a verifica că utilizatorul vede și interacționează cu lucrurile potrivite pe parcurs.
Pentru a reseta testul înapoi la starea inițială așteptată, ne-am autentifica la un utilizator de testare dedicat prin intermediul API-ului cu o comandă globală cy.login
, ne-am configura un cookie pentru a menține utilizatorul conectat, ne-am face apelurile API necesare pentru a returna utilizator la starea de pornire dorită fie prin cy.request(“endpoint”)
, fie cy.task(“pluginAction”)
și vizitați pagina autentificată pe care am căutat să o testăm direct. Apoi, vom automatiza pașii pentru a realiza un flux de caracteristici utilizator, așa cum se arată în aspectul de testare de mai jos.
Vă amintiți comenzile personalizate despre care am vorbit pentru autentificare, cy.login()
și deconectare, cy.logout()
? Le-am implementat cu ușurință în Cypress în acest fel, astfel încât toate testele noastre să se autentifice la un utilizator prin API în același mod.
În plus, am dorit să automatizăm și să verificăm anumite fluxuri complexe care implică e-mailul pe care nu le puteam face bine înainte cu WebdriverIO sau STUI. Unele exemple au inclus exportarea activității de e-mail într-un CSV, trecerea prin fluxul Trimitere către coleg pentru autentificarea expeditorului sau exportul rezultatelor de validare a e-mailului într-un CSV. Cypress împiedică accesul la mai multe superdomenii într-un singur test, așa că navigarea la un client de e-mail printr-o interfață de utilizare pe care nu o deținem a fost nesigură și nu o opțiune.
În schimb, am dezvoltat pluginuri Cypress prin comenzile lor cy.task(“pluginAction”)
pentru a folosi unele biblioteci din serverul Cypress Node pentru a se conecta la un client/inbox IMAP de e-mail de testare, cum ar fi SquirrelMail, pentru a verifica dacă e-mailurile se potrivesc într-o căsuță de e-mail după solicitarea unei acțiuni. în interfața de utilizare și pentru a urmări linkurile de redirecționare din acele e-mailuri înapoi în domeniul aplicației noastre web pentru a verifica anumite pagini de descărcare care au apărut și au finalizat efectiv un întreg flux de clienți. Am implementat pluginuri care ar aștepta ca e-mailurile să ajungă în căsuța de e-mail SquirrelMail, având în vedere anumite linii de subiect, ștergerea e-mailurilor, trimiterea de e-mailuri, declanșarea evenimentelor de e-mail, sondarea serviciilor de backend și efectuând setări și demontare mult mai utile prin intermediul API-ului pentru testele noastre.
Pentru a oferi mai multe informații despre ceea ce am testat de fapt cu Cypress, am acoperit o multitudine de cazuri de mare valoare, cum ar fi acestea:
- Verificări de sănătate pentru toate paginile noastre, adică vizitarea aplicației – Am vrut să ne asigurăm că paginile încărcate cu conținut din cauza faptului că, uneori, anumite servicii backend sau găzduirea frontală ar fi oprite. De asemenea, am recomandat să faceți mai întâi aceste teste pentru a construi memoria musculară mentală de a construi obiecte de pagină cu selectoare și funcții de ajutor și pentru a obține teste rapide și funcționale care rulează într-un mediu.
- Operațiuni CRUD pe o pagină – Am reseta testele în consecință prin intermediul API-ului întotdeauna și apoi vom testa în mod specific crearea, citirea, actualizarea sau ștergerea în UI. De exemplu, dacă am testat posibilitatea de a crea o autentificare de domeniu prin interfața de utilizare, indiferent de modul în care s-a încheiat ultima rulare de testare, trebuia să ne asigurăm că domeniul pe care urma să îl creăm prin interfața de utilizare a fost la început șters prin API înainte de a continua cu pașii de interfață automată pentru a crea domeniul și a evita coliziunile. Dacă am testat posibilitatea de a șterge o suprimare prin interfața de utilizare, ne-am asigurat că vom crea mai întâi suprimarea prin API și apoi am continuat cu pașii.
- Testarea filtrelor de căutare pe o pagină – Am testat să setăm o mulțime de filtre de căutare avansate cu Activitate de e-mail și am vizitat pagina cu parametrii de interogare pentru a ne asigura că filtrele au fost completate automat. De asemenea, am adăugat date prin API-ul pentru validarea e-mailului și am lansat din nou diferite filtre de căutare și am validat că tabelul se potrivește cu filtrele de căutare din pagina respectivă.
- Accesuri diferite ale utilizatorilor – La Twilio SendGrid, avem conturi părinte care pot avea colegi de echipă cu diferite domenii sau permisiuni de acces sau subutilizatori care au, de asemenea, diferite grade de acces și se comportă oarecum similar cu un cont părinte. Coechipierii cu acces numai citire versus acces administrativ pentru anumite pagini și subutilizatori ar vedea sau nu anumite lucruri pe o pagină și asta a făcut mai ușoară autentificarea la acele tipuri de utilizatori și verificarea a ceea ce văd sau nu în testele Cypress.
- Pachete de utilizator diferite – De asemenea, utilizatorii noștri pot varia în ceea ce privește tipurile de pachete gratuite sau plătite, cum ar fi Essentials, Pro și Premier, iar acele pachete pot vedea sau nu anumite lucruri pe o pagină. Ne-am conecta la utilizatori cu pachete diferite și ne-am verifica rapid caracteristicile, copierea sau paginile la care utilizatorii au avut acces în testele Cypress.
Pasul 4: Dockerizarea testelor
Când executăm fiecare pas de conductă Buildkite pe o nouă mașină AWS în cloud, nu am putea numi pur și simplu npm run cypress:run:staging
, deoarece acele mașini nu au Node, browsere, codul aplicației noastre sau orice alte dependențe pentru a rula Cypress. teste. Când am configurat WebdriverIO înainte, trebuia să asamblam trei servicii separate într-un fișier Docker Compose pentru ca serviciile adecvate de Selenium, Chrome și codul de aplicație să funcționeze împreună pentru a rula teste.
Cu Cypress, a fost mult mai simplu, deoarece am solicitat doar imaginea Cypress de bază Docker, cypress/base
, pentru a configura mediul într-un Dockerfile
și un singur serviciu într-un fișier docker-compose.yml
cu codul aplicației noastre pentru a rula Cypress teste. Vom analiza o modalitate de a face acest lucru, deoarece există alte imagini Cypress Docker de utilizat și alte modalități de a configura testele Cypress în Docker. Vă încurajăm să consultați documentația Cypress pentru alternative
Pentru a aduce un serviciu cu toate aplicațiile și codul nostru de testare necesar pentru a rula testele Cypress, am creat un Dockerfile
numit Dockerfile.cypress
și am instalat toate node_modules
și am copiat codul în directorul de lucru al imaginii într-un mediu Node. Acesta ar fi folosit de serviciul nostru cypress
Docker Compose și am realizat configurarea Dockerfile
în următorul mod:
Cu acest Dockerfile.cypress
, putem integra Cypress pentru a rula specificațiile selectate pe un anumit mediu API și aplicație implementată printr-un serviciu Docker Compose numit cypress
. Tot ce trebuia să facem a fost să interpolăm unele variabile de mediu, cum ar fi SPECS
și BASE_URL
, pentru a rula testele Cypress selectate pe o anumită adresă URL de bază prin comanda npm run cypress:run:cicd:staging
care arată astfel, ”cypress:run:cicd:staging”: “cypress run --record --key --config baseUrl=$BASE_URL --env testEnv=staging”
.
Aceste variabile de mediu ar fi setate fie prin setările/fișierele de configurare ale conductei Buildkite, fie exportate dinamic la declanșarea testelor Cypress pentru a rula din conducta noastră de implementare. Un exemplu de fișier docker-compose.cypress.yml
arăta similar cu acesta:
Mai sunt și alte câteva lucruri de observat. De exemplu, puteți vedea variabila de mediu VERSION
care ne permite să facem referire la o anumită imagine Docker etichetată. Vom demonstra mai târziu cum etichetăm o imagine Docker și apoi tragem în jos aceeași imagine Docker pentru ca acea versiune să ruleze cu codul corect pentru testele Cypress.
În plus, veți observa, de asemenea, BUILDKITE_BUILD_ID
transmis, care vine gratuit împreună cu alte variabile de mediu Buildkite pentru fiecare build pe care o lansăm și steag ci-build-id
. Acest lucru permite caracteristica de paralelizare a lui Cypress și, atunci când setăm un anumit număr de mașini alocate pentru testele Cypress, va ști automat cum să învârtă acele mașini și să ne separe testele pentru a rula pe toate acele noduri de mașini pentru a optimiza și accelera testul. timpii de rulare.
În cele din urmă, am profitat și de montarea volumului și de caracteristica artefactelor Buildkite. Încărcăm videoclipurile și capturile de ecran pentru a fi direct accesibile prin fila „Artefacte” Buildkite UI în cazul în care epuizăm înregistrările de test alocate plătite pentru luna sau nu putem accesa Serviciul Dashboard. Ori de câte ori rulează comanda Cypress „run” în modul fără cap, există rezultate în folderele cypress/videos
și cypress/screenshots
-uri pentru ca cineva să le examineze local și pur și simplu montăm acele foldere și le încărcăm în Buildkite pentru noi ca un sistem de siguranță.
Pasul 5: Integrarea cu CICD
Odată ce am făcut ca testele Cypress să ruleze cu succes într-un container Docker în diferite medii, am început să ne integrăm cu Buildkite, furnizorul nostru CICD. Buildkite a oferit modalități de a executa pași într-un fișier .yml
pe mașinile noastre AWS cu scripturi Bash și variabile de mediu setate fie în cod, fie prin setările pipeline-ului Buildkite ale depozitului în interfața de utilizare web. Buildkite ne-a permis, de asemenea, să declanșăm această conductă de testare din conducta noastră principală de implementare cu variabile de mediu exportate și am reutiliza acești pași de testare pentru alte conducte de testare izolate care ar rula într-un program pentru monitorizarea și examinarea de către QA-urile noastre.
La un nivel înalt, conductele noastre de testare Buildkite pentru Cypress și, de asemenea, conductele noastre anterioare WebdriverIO au împărtășit următorii pași similari:
- Configurați imaginile Docker . Construiți, etichetați și împingeți imaginile Docker necesare pentru teste până în registru, astfel încât să le putem trage în jos într-un pas ulterior.
- Rulați testele pe baza configurațiilor variabilelor de mediu . Trageți în jos imaginile Docker etichetate pentru versiunea specifică și executați comenzile adecvate într-un mediu implementat pentru a rula suitele de testare selectate din variabilele de mediu setate.
Iată un exemplu de fișier pipeline.cypress.yml
care demonstrează configurarea imaginilor Docker în pasul „Build Cypress Docker Image” și rularea testelor în pasul „Run Cypress Tests”:
Un lucru de observat este primul pas, „Build Cypress Docker Image” și modul în care configurează imaginea Docker pentru test. A folosit comanda de compilare Docker Compose pentru a build
serviciul cypress
cu tot codul de testare al aplicației și l-a etichetat cu cea latest
și variabilă de mediu ${VERSION}
, astfel încât să putem derula în cele din urmă aceeași imagine cu eticheta adecvată pentru această versiune. pas viitor. Fiecare pas se poate executa pe o altă mașină din cloudul AWS undeva, astfel încât etichetele identifică în mod unic imaginea pentru rularea Buildkite specifică. După ce am etichetat imaginea, am ridicat cea mai recentă imagine și versiunea etichetată în registrul nostru privat Docker pentru a fi reutilizată.
În pasul „Run Cypress tests”, tragem în jos imaginea pe care am construit-o, am etichetat și am împins în primul pas și pornim serviciul Cypress pentru a executa testele. Pe baza variabilelor de mediu, cum ar fi SPECS
și BASE_URL
, vom rula anumite fișiere de testare pe un anumit mediu de aplicație implementat pentru această versiune Buildkite specifică. Aceste variabile de mediu ar fi setate prin setările conductei Buildkite sau ar fi declanșate dinamic dintr-un script Bash care ar analiza un câmp de selectare Buildkite pentru a determina ce suite de testare să ruleze și în ce mediu.
Când selectăm ce teste să rulăm în timpul conductei noastre de implementare Buildkite CICD și declanșăm o conductă dedicată de teste declanșate cu anumite variabile de mediu exportate, urmează pașii din fișierul pipeline.cypress.yml
pentru a realiza acest lucru. Un exemplu de declanșare a testelor după implementarea unui cod nou într-un mediu de ramificare a caracteristicilor din conducta de implementare arată astfel:
Testele declanșate ar rula într-o conductă separată și, după ce ați urmat linkul „Build #639”, ne-ar duce la pașii de compilare pentru rularea testului declanșat ca mai jos:
Reutilizand același fișier pipeline.cypress.yml
pentru conductele noastre dedicate Cypress Buildkite care rulează conform unui program, avem versiuni precum cea care rulează testele noastre „P1”, cea mai mare prioritate E2E, așa cum se arată în fotografia de mai jos:
Tot ce trebuie să facem este să setăm variabilele de mediu adecvate pentru lucruri, cum ar fi ce specificații să rulăm și ce mediu backend să atingem în setările conductei Buildkite. Apoi, putem configura o versiune programată Cron, care se află și în setările pipeline, pentru a începe la fiecare anumit număr de ore și suntem gata de plecare. We would then create many other separate pipelines for specific feature pages as needed to run on a schedule in a similar way and we would only vary the Cron schedule and environment variables while once again uploading the same `pipeline.cypress.yml` file to execute.
In each of those “Run Cypress tests” steps, we can see the console output with a link to the recorded test run in the paid Dashboard Service, the central place to manage your team's test recordings, billing, and other Cypress stats. Following the Dashboard Service link would take us to a results view for developers and QAs to take a look at the console output, screenshots, video recordings, and other metadata if required such as this:
Step 6: Comparing Cypress vs. WebdriverIO/STUI
After diving into our own custom Ruby Selenium solution in STUI, WebdriverIO, and finally Cypress tests, we recorded our tradeoffs between Cypress and Selenium wrapper solutions.
Pro
- It's not another Selenium wrapper – Our previous solutions came with a lot of Selenium quirks, bugs, and crashes to work around and resolve, whereas Cypress arrived without the same baggage and troubles to deal with in allowing us full access to the browser.
- More resilient selectors – We no longer had to explicitly wait for everything like in WebdriverIO with all the
$(.selector).waitForVisible()
calls and now rely oncy.get(...)
and cy.contains(...)
commands with their default timeout. It will automatically keep on retrying to retrieve the DOM elements and if the test demanded a longer timeout, it is also configurable per command. With less worrying about the waiting logic, our tests became way more readable and easier to chain. - Vastly improved developer experience – Cypress provides a large toolkit with better and more extensive documentation for assertions, commands, and setup. We loved the options of using the Cypress GUI, running in headless mode, executing in the command-line, and chaining more intuitive Cypress commands.
- Significantly better developer efficiency and debugging – When running the Cypress GUI, one has access to all of the browser console to see some helpful output, time travel debug and pause at certain commands in the command log to see before and after screenshots, inspect the DOM with the selector playground, and discern right away at which command the test failed. In WebdriverIO or STUI we struggled with observing the tests run over and over in a browser and then the console errors would not point us toward and would sometimes even lead us astray from where the test really failed in the code. When we opted to run the Cypress tests in headless mode, we got console errors, screenshots, and video recordings. With WebdriverIO we only had some screenshots and confusing console errors. These benefits resulted in us cranking out E2E tests much faster and with less overall time spent wondering why things went wrong. We recorded it took less developers and often around 2 to 3 times less days to write the same level of complicated tests with Cypress than with WebdriverIO or STUI.
- Network stubbing and mocking – With WebdriverIO or STUI, there was no such thing as network stubbing or mocking in comparison to Cypress. Now we can have endpoints return certain values or we can wait for certain endpoints to finish through
cy.server()
andcy.route()
. - Less time to set up locally – With WebdriverIO or STUI, there was a lot of time spent up front researching which reporters, test runners, assertions, and services to use, but with Cypress, it came bundled with everything and started working after just doing an
npm install cypress.
- Less time to set up with Docker – There are a bunch of ways to set up WebdriverIO with Selenium, browser, and application images that took us considerably more time and frustration to figure out in comparison to Cypress's Docker images to use right out of the gate.
- Parallelization with various CICD providers – We were able to configure our Buildkite pipelines to spin up a certain number of AWS machines to run our Cypress tests in parallel to dramatically speed up the overall test run time and uncover any flakiness in tests using the same resources. The Dashboard Service would also recommend to us the optimal number of machines to spin up in parallel for the best test run times.
- Paid Dashboard Service – When we run our Cypress tests in a Docker container in a Buildkite pipeline during CICD, our tests are recorded and stored for us to look at within the past month through a paid Dashboard Service. We have a parent organization for billing and separate projects for each frontend application to check out console output, screenshots, and recordings of all of our test runs.
- Tests are way more consistent and maintainable – Tests passed way more consistently with Cypress in comparison to WebdriverIO and STUI where the tests kept on failing so much to the point where they were often ignored. Cypress tests failing more often signaled actual issues and bugs to look into or suggested better ways to refactor our tests to be less flaky. With WebdriverIO and STUI, we wasted a lot more time in maintaining those tests to be somewhat useful, whereas with Cypress, we would every now and then adjust the tests in response to changes in the backend services or minor changes in the UI.
- Tests are faster – Builds passed way more consistently and overall test run times would be around 2 to 3 times faster when run serially without parallelization. We used to have overall test runs that would take hours with STUI and around 40 minutes with WebdriverIO, but now with way more tests and with the help of parallelization across many machine nodes, we can run over 200 tests in under 5 minutes .
- Room to grow with added features in the future – With a steady open-source presence and dedicated Cypress team working towards releasing way more features and improvements to the Cypress infrastructure, we viewed Cypress as a safer bet to invest in rather than STUI, which would require us to engineer and solve a lot of the headaches ourselves, and WebdriverIO, which appeared to feel more stagnant in new features added but with the same baggage as other Selenium wrappers.
Contra
- Lack of cross-browser support – As of this writing, we can only run our tests against Chrome. With WebdriverIO, we could run tests against Chrome, Firefox, Safari, and Opera. STUI also provided some cross-browser testing, though in a much limited form since we created a custom in-house solution
- Cannot integrate with some third-party services – With WebdriverIO, we had the option to integrate with services like BrowserStack and Sauce Labs for cross-browser and device testing. However, with Cypress there are no such third-party integrations but there are some plugins with services like Applitools for visual regression testing available. STUI, on the other hand, also had some small integrations with TestRail , but as a compromise, we log out the TestRail links in our Cypress tests so we can refer back to them if we needed to.
- Requires workarounds to test with iframes – There are some issues around handling iframes with Cypress. We ended up creating a global Cypress command to wrap how to deal with retrieving an iframe's contents as there is no specific API to deal with iframes like how WebdriverIO does.
To summarize our STUI, WebdriverIO, and Cypress comparison, we analyzed the overall developer experience (related to tools, writing tests, debugging, API, documentation, etc.), test run times, test passing rates, and maintenance as displayed in this table:
Following our analysis of the pros and cons of Cypress versus our previous solutions, it was pretty clear Cypress would be our best bet to accomplish our goal of writing fast, valuable, maintainable, and debuggable E2E tests we could integrate with CICD.
Though Cypress lacked features such as cross-browser testing and other integrations with third-party services that we could have had with STUI or WebdriverIO, we most importantly need tests that work more often than not and with the right tools to confidently fix broken ones. If we ever needed cross-browser testing or other integrations we could always still circle back and use our knowledge from our trials and experiences with WebdriverIO and STUI to still run a subset of tests with those frameworks.
We finally presented our findings to the rest of the frontend organization, engineering management, architects, and product. Upon demoing the Cypress test tools and showcasing our results between WebdriverIO/STUI and Cypress, we eventually received approval to standardize and adopt Cypress as our E2E testing library of choice for our frontend teams.
Step 7: Scaling to Other Frontend Teams
After successfully proving that using Cypress was the way to go for our use cases, we then focused on scaling it across all of our frontend teams' repos. We shared lessons learned and patterns of how to get up and running, how to write consistent, maintainable Cypress tests, and of how to hook those tests up during CICD or in scheduled Cypress Buildkite pipelines.
To promote greater visibility of test runs and gain access to a private monthly history of recordings, we established our own organization to be under one billing method to pay for the Dashboard Service with a certain recorded test run limit and maximum number of users in the organization to suit our needs.
Once we set up an umbrella organization, we invited developers and QAs from different frontend teams and each team would install Cypress, open up the Cypress GUI, and inspect the “Runs” and “Settings” tab to get the “Project ID” to place in their `cypress.json` configuration and “Record Key” to provide in their command options to start recording tests to the Dashboard Service. Finally, upon successfully setting up the project and recording tests to the Dashboard Service for the first time, logging into the Dashboard Service would show that team's repo under the “Projects” tab like this:
When we clicked a project like “mako”, we then had access to all of the test runs for that team's repo with quick access to console output, screenshots, and video recordings per test run upon clicking each row as shown below:
For more insights into our integration, we set up many separate dedicated test pipelines to run specific, crucial page tests on a schedule like say every couple hours to once per day. We also added functionality in our main Buildkite CICD deploy pipeline to select and trigger some tests against our feature branch environment and staging environment.
După cum era de așteptat, acest lucru a trecut rapid prin testele înregistrate alocate pentru luna, mai ales că există mai multe echipe care contribuie și declanșează teste în diferite moduri. Din experiență, vă recomandăm să fiți atenți la câte teste rulează într-un program, cât de des sunt rulate acele teste și ce teste sunt efectuate în timpul CICD. Pot exista unele testări redundante și alte zone care să fie mai frugale, cum ar fi reducerea frecvenței testelor programate sau, eventual, eliminarea completă a unora pentru declanșarea testelor numai în timpul CICD.
Aceeași regulă de a fi cumpătați se aplică pentru adăugarea de utilizatori, deoarece am subliniat oferirea accesului numai dezvoltatorilor și QA din echipele de front-end care vor folosi Serviciul Dashboard în mod intens, mai degrabă decât conducerea superioară și alte persoane din afara acelor echipe pentru a ocupa acele locuri limitate.
Ce așteptăm cu nerăbdare cu Cypress
După cum am menționat anterior, Cypress a demonstrat o mulțime de promisiuni și potențial de creștere în comunitatea open source și cu echipa sa dedicată însărcinată cu furnizarea de funcții mai utile pe care să le folosim cu testele noastre E2E. Multe dintre dezavantajele pe care le-am evidențiat sunt în prezent abordate și așteptăm cu nerăbdare lucruri precum:
- Suport între browsere – Acesta este unul mare, deoarece o mare parte din respingerea de la adoptarea Cypress a venit din utilizarea doar a Chrome, în comparație cu soluțiile bazate pe Selenium, care acceptau browsere precum Firefox, Chrome și Safari. Din fericire, testele mai fiabile, menținute și depanabile au câștigat pentru organizația noastră și sperăm să ne îmbunătățim suitele de testare cu mai multe teste pentru browsere încrucișate în viitor, când echipa Cypress va lansa un astfel de suport pentru browsere încrucișate.
- Rescrierea stratului de rețea – Aceasta este, de asemenea, una uriașă, deoarece avem tendința de a folosi intens API-ul Fetch în zonele noastre mai noi React și în zonele mai vechi de aplicații Backbone/Marionette, am folosit în continuare jQuery AJAX și apeluri normale bazate pe XHR. Putem elimina cu ușurință sau ascultăm cererile în zonele XHR, dar a trebuit să facem niște soluții hacker cu opțiuni de preluare polifill pentru a obține același efect. Rescrierea stratului de rețea ar trebui să ajute la atenuarea acestor dureri.
- Îmbunătățiri suplimentare ale Serviciului Dashboard – Am văzut deja câteva noi modificări ale UI la Serviciul Dashboard recent și sperăm să-l vedem în continuare crescând cu mai multe vizualizări statistice și defalcări ale datelor utile. De asemenea, folosim foarte mult funcția de paralelizare și verificăm des înregistrările noastre de test eșuate în Serviciul Dashboard, astfel încât orice îmbunătățiri iterative ale aspectului și/sau caracteristicilor ar fi plăcut de văzut.
Adoptarea Cypress în viitor
Pentru organizația noastră, am apreciat eficiența dezvoltatorului, depanarea și stabilitatea testelor Cypress atunci când sunt executate în browserul Chrome. Am realizat teste consistente, valoroase, cu mai puțină întreținere pe drum și cu multe instrumente pentru a dezvolta noi teste și a le repara pe cele existente.
În general, documentația, API-ul și instrumentele de care dispunem au depășit cu mult orice contra. După ce am experimentat Cypress GUI și serviciul de tablou de bord plătit, cu siguranță nu am vrut să ne întoarcem la WebdriverIO sau la soluția noastră personalizată Ruby Selenium.
Ne-am conectat testele cu Buildkite și ne-am îndeplinit obiectivul de a oferi o modalitate de a scrie teste de automatizare E2E consistente, depanabile, întreținute și valoroase pentru ca aplicațiile noastre frontend să se integreze cu CICD . Am demonstrat cu dovezi celorlalte echipe de front-end, superiorilor de inginerie și proprietarilor de produse beneficiile adoptării Cypress și renunțării la WebdriverIO și STUI.
Sute de teste mai târziu în cadrul echipelor de front-end din Twilio SendGrid și am detectat multe erori în mediul nostru de pregătire și am reușit să remediam rapid orice test defectuos din partea noastră, cu mult mai multă încredere decât oricând. Dezvoltatorii și QA nu se mai tem să scrie teste E2E, dar acum așteaptă cu nerăbdare să le scrie pentru fiecare funcție nouă pe care o lansăm sau pentru fiecare funcție mai veche care ar putea folosi mai multă acoperire.