End-to-end tests met Cypress

Geschreven door Martijn Spaan op

Cypress is al sinds 2017 beschikbaar en inmiddels uitgegroeid tot een van de preferred frameworks om end-to-end (e2e) testen mee uit te voeren. Hoewel dit, voor ons als .NET experts geen onderdeel is van onze core business, komen wij regelmatig bij projecten waarbij testen onderdeel is van de taken in het team en dit door developers opgepakt wordt. Tijd om dit framework eens goed te testen en naast de alternatieven te leggen.

End-to-end testing

Om te beginnen, wat houd end-to-end testing precies in. Bij software ontwikkeling zijn veel verschillende vormen van testen noodzakelijk voor hoge kwaliteit software. Van unit testen op het kleinste en diepste niveau, naar component en integratie tests op een hoger niveau, tot uiteindelijk het doorlopen van de applicatie zoals ook een gebruiker dit zou doen: de end-to-end tests. Hierbij is het van belang dat de tests zich gedragen als een eind gebruiker, dus muis en keyboard gebruikt voor de input en het doorlopen van de tests, waarna de visuele componenten gebruikt worden voor het asserten van de tests.

Hoewel Cypress eigenlijk wel alle vormen van testen ondersteund, zolang de code maar draait of aan te roepen is vanuit een browser, wordt het framework voornamelijk gebruikt voor het uitvoeren van end-to-end tests.

Een alternatief voor Selenium

Voorheen werd voor e2e tests voornamelijk het Selenium framework gebruikt, welke de mogelijkheid biedt om via een browser driver de flow van de applicatie te doorlopen. Deze drivers zorgden echter regelmatig voor uitdagingen om op de juiste manier zich te gedragen als een gebruiker en waren de tests vaak traag en onvoorspelbaar door de noodzakelijke wait commands en time-outs.

Cypress heeft deze zaken beter op orde door gebruik te maken van een Node.js service die direct draait in de browser, waardoor de tests veel dichter draaien tegen de applicatie code. Ook worden de wait commands en timeouts direct en efficiënt door het framework afgehandeld zodat daar tijdens het ontwikkelen van de tests niet meer over nagedacht hoeft te worden. Dit zorgt voor snellere en betrouwbaardere tests.

Waar Selenium nog voornamelijk in uitblinkt is de support voor veel browser versies en het ontwikkelen in verschillende programmeer talen zoals Java, Python, Ruby, C# en PHP. Cypress moet het daarentegen doen met alleen JavaScript en TypeScript en ondersteund voornamelijk de moderne grotere browsers zoals Chrome en Firefox.

Enter Cypress

Waar Cypress verder nog in uitblinkt is een uitstekende test runner, support voor externe taken en fixtures/stubbing.

Test runner

Cypress komt standaard met een test runner die het een developer zeer eenvoudig maakt om testen te controleren, analyseren en ontwikkelen. Door de test stappen naast een visuele representatie van de website te tonen waarbij de status van elke stap kan worden terug gekeken, krijgt een developer heel veel inzicht in de uitgevoerde tests. Ook beschikt de test runner over een interactieve css selector tool waarmee eenvoudig extra test commands wordt gegenereerd.

Externe taken

Naast custom commands die geconfigureerd kunnen worden om combinaties van browser acties herbruikbaar te maken, is het ook mogelijk om taken buiten de browser uit te voeren, direct op het OS. Dit is mogelijk omdat het Node.js service direct op het OS draait. Een mogelijke externe taak zou kunnen zijn het seeden van een test database zodat je een voorspelbare dataset hebt wat weer zorgt voor betrouwbare tests.

Fixtures/stubbing

Vaak is het niet verstandig om alle tests afhankelijk te maken van de backend server en database. Dit zorgt voor veel onderhoud aan test data sets en resulteerd in tragere test suites omdat elke test connectie maakt met de backend.

Het alternatief is gebruik maken van fixtures en stubbing, waarbij de backend API calls voorspelbare data opleveren en geen trage netwerk calls uitvoeren. Het advies luid dan ook om de happy flow tests direct uit te voeren op de backend en voor de edge cases gebruik maken van subs.

Frontend collaboration

Om de meest betrouwbare test te krijgen is het verstandig om niet uit te gaan van classes, styles en id's voor het refereren naar html elementen aangezien deze nog wel eens willen wijzigen tijdens de ontwikkeling en daardoor de tests gaan falen. Cypress adviseert daarom om html elementen die gerefereerd worden in tests, uit te rusten met een 'data-cy' attribuut, dit heeft een aantal voordelen:

  • Voor ontwikkelaars duidelijk dat dit attribuut voor Cypress gebruikt wordt en wijzigingen direct impact hebben op de e2e tests.
  • Tests zijn niet gevoelig voor veranderingen in class, style en id's.
  • Leesbare element selectors in de tests in plaats van complexe CSS selectors.

Verschillen met Playwright

Een ander opkomend framework is Playwright van Microsoft, dat begin 2020 is geïntroduceerd. Net als Cypress draait deze op Node.js en is de test engine een stuk betrouwbaarder dan Selenium. Bijkomend voordeel is dat meerdere talen ondersteund worden zoals C# en Python.

Conclusie

Voor het uitvoeren van end-to-end tests is ruime keuze qua frameworks. Selenium is alleen nog aan te raden voor maintenance projecten die hier al gebruik van maken aangezien een upgrade vaak een flinke bulk werk met zich mee brengt. Voor greenfield projecten is het zeker aan te raden om voor Cypress te kiezen mits de ontwikkelaars zich prettig voelen bij typescript. Anders is Playwright een volwaardig alternatief waarbij gewoon met C# gewerkt kan worden.

Martijn SpaanMartijn is een .NET expert die streeft naar hoge kwaliteit software o.a. door Test-Driven Design. Momenteel werkt hij als software engineer aan een PWA bodemonderzoek bij TerraIndex.
← Terug
XPRTZ