CI-klare e2e-tests voor Angular met Cypress en TypeScript in minder dan 60 minuten

In dit artikel wordt beschreven hoe je end-to-end-tests voor Angular kunt opzetten met Cypress inclusief TypeScript. U zult uw allereerste e2e-tests schrijven en deze klaarmaken om te draaien op een CircleCI als een continu integratiesysteem bij elke update van uw repository.

End-to-end (kort e2e) testen is een type softwaretesten dat het softwaresysteem valideert samen met de integratie met externe interfaces. Het doel van end-to-end-tests is het oefenen van een volledig productieachtig scenario.

Bron: https://www.guru99.com/end-to-end-testing.html.

Overzicht

  • Wat is Cypress?
  • Voorvereisten
  • Cypress instellen
  • Een aantal tests schrijven
  • Continu Integratie instellen
  • Conclusie en referenties

Ik heb een frontend-ontwikkelachtergrond in Microsoft’s .NET & WPF en herinner me de tijden waarin we dure frameworks evalueerden om end-to-end tests voor onze projecten te schrijven. Na veel evaluaties en weken, zelfs maanden van aangepaste lijmcode en ontwikkeling van testinfrastructuren bovenop bestaande tools, kregen we eindelijk een aantal e2e tests aan de praat. Ze waren broos, faalden vaak door handmatige aanpassingen die we moesten doen of problemen met flaky runners in de continuous integration pipeline.

Enige jaren later met Angular en Protractor als standaard voor e2e tests, waren we nog steeds gebaseerd op pagina objecten, Selenium Web Driver en de tests bleven vrij onbetrouwbaar. Er waren geen dure commerciële frameworks en aangepaste infrastructuur nodig. Maar was het leuk om e2e tests te schrijven? Nee.

Maar we zijn nu in 2020 en de tijd is gekomen voor nieuwe helden om op te staan. 🚀

Wat is Cypress?

Cypress belooft snel, gemakkelijk en betrouwbaar testen voor alles wat in een browser draait. Het is niet gebaseerd op Selenium Web Driver die gebruik maakt van netwerkverbindingen om te communiceren met uw browser. In plaats daarvan is Cypress een test runner die in je browser naast je web applicatie draait en er dus directe controle over heeft.

Zonder in alle details te treden, dit maakt Cypress niet alleen sneller en betrouwbaarder, het opent ook de deur voor een heleboel andere interessante functies, zoals

  • time travel debugging,
  • easy snapshotting and recording,
  • automatic waitings.

Bovenop alle functies, Cypress heeft een ontwikkelaar ervaring (DX) die bijna ongeëvenaard is. Heb je ooit een bericht gezien in de error logs van je mislukte build dat je precies vertelt wat je fout hebt gedaan, je wijst op de juiste dependencies om toe te voegen en ook linkt naar een verklarende documentatie site die het probleem beschrijft? Dit is hoe Cypress aanvoelt. Het is gebouwd door ontwikkelaars voor ontwikkelaars.

Cypress-fout op de build-server vertelt u hoe u het kunt oplossen

Hierna zullen we Cypress installeren voor een vers Angular-project dat is gemaakt met de CLI. We schrijven een aantal e2e-tests en sluiten af met het uitvoeren van deze tests door een geautomatiseerd build-systeem. Al deze stappen zouden niet meer dan 60 minuten mogen duren. We proberen de stappen zo kort mogelijk te houden, door gebruik te maken van bestaande tools zoals Angular schema’s, bibliotheken en gemeenschappelijke templates.

Vereisten

Deze gids gaat ervan uit dat je een standaard Angular 9 app project hebt. Zo niet, dan kunt u er een maken zoals u normaal zou doen met de Angular CLI. Als u de CLI niet globaal hebt geïnstalleerd, kunt u gebruikmaken van het npx-commando dat deze tijdelijk on the fly installeert:

npx @angular/cli new <app-name>

Cypress instellen

Om Cypress samen met TypeScript zo snel mogelijk in te stellen, maken we gebruik van een bestaand schema dat is ontwikkeld door BrieBug.

In de root van uw Angular-project kunt u de terminal openen en het volgende commando invoeren:

ng add @briebug/cypress-schematic --addCypressTestScripts

Als de CLI niet globaal is geïnstalleerd, is het ng-commando mogelijk niet direct beschikbaar. U kunt het gebruik van de lokale ng afdwingen vanuit de package.json:

npm run ng -- add @briebug/cypress-schematic # In case 'ng' could not be found

We kunnen Protractor veilig verwijderen omdat het volledig zal worden vervangen. Tijdens de installatie zijn enkele binaries gedownload omdat Cypress wordt geleverd met een Electron-gebundelde UI als interactieve testrunner.

Met behulp van de vlag --addCypressTestScripts zijn twee handige npm-scripts toegevoegd om het werken met Cypress aangenamer te maken. Een om e2e tests headless uit te voeren en het andere script om de tests uit te voeren met de Cypress UI runner:

 // package.json scripts "cy:run": "cypress run", "cy:open": "cypress open"

Als je een van deze scripts standalone zou uitvoeren, zou de test mislukken omdat het probeert te routeren naar http://localhost:4200 waar op dit moment niets wordt geserveerd. Om dit op te lossen, moeten we een tweede terminal openen en onze Angular applicatie van tevoren serveren met npm start.

Gelukkig heeft het schema het e2e commando aangepast, zodat dit automatisch voor je wordt gedaan door de CLI builder. U kunt de applicatie serveren en de e2e test starten door het volgende commando te gebruiken:

npm run e2e

Cypress zal detecteren dat we het voor de eerste keer hebben gestart. Het controleert de installatie en voegt een aantal voorbeeldbestanden toe. Nadat de UI is geopend, zien we een test die al voor ons is gemaakt.

Cypress UI na cy:open

Door de test te selecteren, wordt deze uitgevoerd. In eerste instantie zal de test mislukken omdat we iets niet goed hebben getest. We zullen dit nu oplossen.

Falen test die nog niet is geïmplementeerd

Een aantal tests schrijven

Als allereerste stap, zoals voorgesteld door de Cypress best practices, stellen we onze globale baseUrl in, zodat we deze niet bij elke testuitvoering hoeven te dupliceren. Voeg het volgende toe aan de configuratie cypress.json:

// cypress.json{ "baseUrl": "http://localhost:4200"}

Daarna schrijven we onze allereerste rooktest die alleen controleert of de standaard app titel is ingesteld op de Angular startpagina. Verander daarom de inhoud van de spec.ts in de volgende inhoud:

// spec.tsit('smoke test', () => { cy.visit('/'); cy.contains('cypress-e2e-testing-angular app is running!');});

De test begint met het routeren naar onze baseUrl en gaat verder met het bevragen van elk element dat de tekst cypress-e2e-testing-angular app is running!.

Testing User Flows

Deze test zou al moeten werken, maar laten we eens wat meer interactieve tests schrijven. Omdat e2e inherent langzamer zijn dan unit tests, is het helemaal prima om e2e tests te hebben die de hele user flow voor een functie modelleren.

Voorbeeld, we willen controleren of sommige karakteristieken van de startpagina geldig zijn: Onze pagina moet standaard de titel en de ng generate-tekst in de terminal bevatten, maar wanneer de gebruikers op de Angular Material-knop klikken, willen we ervoor zorgen dat de juiste ng add-opdracht wordt weergegeven in de terminalweergave eronder.

U kunt de inhoud van uw testbestand vervangen door deze:

// spec.tsdescribe('When Angular starting page is loaded', () => { beforeEach(() => { cy.visit('/'); }); it('has app title, shows proper command by default and reacts on command changes', () => { cy.contains('cypress-e2e-testing-angular'); cy.contains('.terminal', 'ng generate component xyz'); cy.contains('Angular Material').click(); cy.contains('.terminal', 'ng add @angular/material'); });});

We hebben onze testsuite gerefactored door een describe-blok toe te voegen om alle tests vast te leggen die worden uitgevoerd wanneer de startpagina wordt geladen. Omdat we elke keer de baseUrl bezoeken, hebben we deze verplaatst naar de beforeEach-oproep. Als laatste hebben we de basis rooktesten gecombineerd met de test voor de terminal view op de startpagina.

Het is belangrijk om te weten dat je de query resultaten van Cypress niet in variabelen moet opslaan, maar in plaats daarvan met closures moet werken. Bovendien hebben we elementen geselecteerd aan de hand van CSS klassen en tekstinhoud, wat te broos kan zijn. Het is aan te raden om data- attributen te gebruiken voor het selecteren van elementen.

Cypress heeft een heleboel geweldige functies en mogelijkheden. We zullen ze niet allemaal behandelen omdat ons doel is om ons te richten op het allereerste beginpunt. De officiële documentatie is erg goed en behandelt alles over de interactie met elementen.

Als je deze testsuite opnieuw uitvoert, zou je de UI door elk scenario moeten zien klikken en alle drie de tests zouden deze keer moeten slagen. ✔✔✔

Het succesvol uitvoeren van onze eerste Cypress-testsuite

Opzetten van continue integratie

Nu onze tests lokaal worden uitgevoerd, kunnen we beginnen met het opzetten van een kleine CI-pijplijn (continue integratie). Een goede manier om dit voor te bereiden, is om npm scripts te maken en ze te combineren zodat het build systeem een enkel script kan gebruiken als entry point. Door deze methode te volgen, kun je de CI stappen lokaal uitproberen voordat je ze online zet. Bovendien zijn npm scripts tamelijk onafhankelijk van een echt build systeem.

Op CI, moeten we onze server op de achtergrond starten en wachten tot hij onze applicatie heeft gebundeld, wat een tijdje kan duren. Dan moeten we de Cypress test runner starten, de tests doorlopen en de server afsluiten als de tests klaar zijn. Gelukkig kunnen we dit allemaal doen met een enkel hulpprogramma genaamd start-server-en-test, zoals beschreven in de Cypress docs:

npm install --save-dev start-server-and-test

Nadat dit is geïnstalleerd, gebruiken we de Angular serve die momenteel achter npm start staat en combineren dit met het headless cy:run commando:

 // package.json scripts "start": "ng serve", "cy:run": "cypress run", "e2e:ci": "start-server-and-test start http://localhost:4200 cy:run"

Je kunt zeker een productie build gebruiken of vooraf bouwen en de app serveren met een willekeurige http server. Voor de beknoptheid laat ik deze verbeteringen aan jou over.

Circle CI

Voor ons voorbeeld kiezen we CircleCI omdat het zeer goed integreert met GitHub, daar veel gebruikt wordt en een gratis plan heeft. Je kunt ieder ander CI systeem gebruiken zoals Jenkins of GitLab (waar ik de meeste ervaring mee heb). Na het aanmelden bij CircleCI en het verbinden met onze GitHub account, kun je de repository selecteren en een nieuw project maken via hun dashboard.

Om de pijplijn te configureren, zou je een config.yml kunnen schrijven door een sjabloon te selecteren en aan te passen aan je behoeften en uiteindelijk het e2e script uit te voeren. Gelukkig heeft Cypress kant en klare configuraties (Orbs genaamd) voor CircleCI die al de installatie van afhankelijkheden, caching enzovoort bevatten. Voordat we deze kunnen gebruiken, moeten we naar de Organisatie-instellingen om runners van derden in te schakelen.

# circleci/config.ymlversion: 2.1orbs: # This Orb includes the following: # - checkout current repository # - npm install with caching # - start the server # - wait for the server to respond # - run Cypress tests # - store videos and screenshots as artifacts on CircleCI cypress: cypress-io/cypress@1workflows: build: jobs: - cypress/run: start: npm start wait-on: 'http://localhost:4200' store_artifacts: true

De pijplijn heeft maar één taak: Alle e2e-tests uitvoeren. De pijplijn controleert de huidige tak, installeert alle afhankelijkheden, inclusief caching, start de applicatieserver en voert onze tests uit. Daarnaast worden video’s (standaard opgenomen) en screenshots (voor het geval de tests mislukken) geüpload als CircleCI-artefacten voor verdere inspectie.*

CircleCI Dashboard

Conclusie

De stappen in deze gids zijn vrij minimaal. U kunt uw bestaande Angular-project gebruiken, de configuratie van uw Cypress-testsuites wijzigen en veel zinvollere tests schrijven. Bovendien kan je npm scripts definiëren voor verschillende scenario’s en omgevingen en natuurlijk kan je hele build pipeline uitgebreid worden met linting, unit testing, bouwen en zelfs deployen van je applicatie. Niettemin, dit zou een eerste stap moeten zijn die laat zien hoe snel geautomatiseerde end-to-end tests kunnen worden opgezet in deze tijd.

Wacht tot je echte Cypress tests schrijft voor je applicatie. U zult er veel plezier aan beleven!

Mind blown gif

Ik hoop dat u ook wat aan dit artikel zult hebben. Als u vragen of opmerkingen heeft, laat het me dan weten. Uw feedback is van harte welkom!

U kunt de bronnen voor deze handleiding vinden op GitHub:

MrCube42 / cypress-e2e-testing-angular

Voorbeeld van een Angular 9-app die Cypress gebruikt voor end-to-end tests.

CypressE2eTestingAngular

Dit project is gegenereerd met Angular CLI versie 9.0.6.

Ontwikkelingsserver

Run ng serve voor een dev server. Navigeer naar http://localhost:4200/. De app wordt automatisch opnieuw geladen als u een van de bronbestanden wijzigt.

Code scaffolding

Run ng generate component component-name om een nieuw component te genereren. U kunt ook ng generate directive|pipe|service|class|guard|interface|enum|module.

Build

Run ng build gebruiken om het project te bouwen. De gebouwde artefacten zullen worden opgeslagen in de dist/ directory. Gebruik de --prod vlag voor een productie build.

Uitvoeren unit tests

Run ng test om de unit tests via Karma uit te voeren.

Uitvoeren end-to-end tests

Run npm run e2e om de end-to-end tests via Cypress uit te voeren.

Volgende hulp

Om meer hulp te krijgen over de Angular CLI gebruikt u ng help of kijkt u in de Angular CLI README.

Leave a Reply