Frontendtesting in de praktijk

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • OB1
  • Registratie: April 2014
  • Laatst online: 21:23
Dag allemaal,

Nu de laatste jaren Javascript frontend frameworks zoals Angular, React en Vue steeds meer gebruikt worden en websites ook veel functionaliteit hebben, is het ook verstandig om deze functionaliteit te testen.

In mijn geval heb ik een Angular frontend die communiceert met een REST API.

Ik wil de frontend, specifieker de UI, óók gaan testen. Denk hierbij aan testen of opgehaalde data ook daadwerkelijk gerenderd wordt en testen of redirects bij bijvoorbeeld het opsturen van een form correct uitgevoerd worden. Om maar eens twee voorbeelden te noemen.

Nu is het testen zelf wel iets waar ik uit ga komen.

Echter, bijna elke pagina is afhankelijk van de backend om data op te halen. Mock servers zijn geen uitkomst; de response van een endpoint is tijdens het draaien van de api niet meer aan te passen. Ik kan daardoor geen error responses of unauthorized responses simuleren.

Mock frameworks werken in Protractor slechts tot AngularJS en zijn dus niet meer geschikt.

Ik had als idee om de backend te seeden met mock data. Is dit wellicht verstandiger?

(hoe) wordt dit in de praktijk toegepast? Wat is jullie kijk hierop?

AMD 2700x @ 4.15 GHz | Vega 56 (Vega 64 BIOS) | 32 GB DDR4 | MSI X470 Gaming Plus | Intel 600P 1TB | Corsair RM550X


Acties:
  • +1 Henk 'm!

  • armageddon_2k1
  • Registratie: September 2001
  • Laatst online: 27-07 10:18
OB1 schreef op zaterdag 23 maart 2019 @ 15:33:
Echter, bijna elke pagina is afhankelijk van de backend om data op te halen. Mock servers zijn geen uitkomst; de response van een endpoint is tijdens het draaien van de api niet meer aan te passen. Ik kan daardoor geen error responses of unauthorized responses simuleren.
Deze snap ik niet helemaal, tekstueel en inhoudelijk zeg maar. Kan je hem wat beter uitleggen?

Het hele idee van unit en integratie-testen is volgens mij dat je juist wel de mogelijkheid heb mock servers en mock data te gebruiken danwel te simuleren. Als je 'code-under-test' hier niet goed mee om kan gaan, dan heb je sowieso een lastige situatie gecreëerd lijkt me.

Je voorstel om mock-data in je backend te seeden is een, mijn inziens, ranzig alternatief. In ieder geval, als het je live backend is.

Hoe wij het doen is als volgt:
- db + server-api + client zijn als compleet docker-compose set te initieren en te seeded met mock data
- de server-api draait z'n jUnit test-suite, de client z'n mocha tests
- de client tests connecten soms met de server-api en soms met een nep-api die foutieve responses stuurt

We hebben ook interactieve canvas-dingen in de client zitten en daar zijn we nog niet helemaal uit. Proberen nu Puppeteer te gebruiken, maar ook erg lastig.

Engineering is like Tetris. Succes disappears and errors accumulate.


Acties:
  • 0 Henk 'm!

  • OB1
  • Registratie: April 2014
  • Laatst online: 21:23
Bedankt voor je reactie!
Deze snap ik niet helemaal, tekstueel en inhoudelijk zeg maar. Kan je hem wat beter uitleggen?
Mijn uitleg hierin was niet helemaal duidelijk inderdaad.

Er zijn bepaalde mock-api's (bijvoorbeeld in Postman), hierin kunnen per endpoint standaard responses worden ingesteld. Echter, deze responses zijn altijd hetzelfde. Hierdoor kan ik niet ervoor kiezen om in de ene test bij endpoint X een 200 terug te sturen en bij de andere test een 401 terug te sturen. Ik zou echter wel graag beide scenario's willen testen.
Hoe wij het doen is als volgt:
- db + server-api + client zijn als compleet docker-compose set te initieren en te seeded met mock data
- de server-api draait z'n jUnit test-suite, de client z'n mocha tests
- de client tests connecten soms met de server-api en soms met een nep-api die foutieve responses stuurt
Hoe jullie het doen klinkt vrij haalbaar en niet al te lastig te implementeren. Ik wacht even de andere reacties af! :)

AMD 2700x @ 4.15 GHz | Vega 56 (Vega 64 BIOS) | 32 GB DDR4 | MSI X470 Gaming Plus | Intel 600P 1TB | Corsair RM550X


Acties:
  • +1 Henk 'm!

  • n9iels
  • Registratie: November 2017
  • Niet online
Bekend probleem wat je omschrijft. De scheiding tussen de klassieke back-end en front-end is er eigenlijk niet meer. De code van de "front-end" is net zo complex als de code van de back-end en heeft testen nodig.

In mijn ervaring is Angular in praktijk het meest volwassen is hierin. Met de HttpClientTestingModule kun je nagaan of er daadwerkelijk een request gemaakt wordt, en deze ook afvangen en i.p.v. mockdata terug sturen wat verder door de applicatie gebruikt wordt (zie: https://angular.io/guide/http#testing-http-requests).

Dit is hoe ik het meestal aanpak. De front-end wordt dus volledig los van de back-end getest m.b.v. het onderscheppen en simuleren van calls naar de back-end. Wat ik ook redelijk vaak doe is de communicatie met een API in een aparte class stoppen, een service zoals dit in de Angular wereld heet. Deze class kan dan gewoon met reguliere testing frameworks getest worden.

[ Voor 17% gewijzigd door n9iels op 23-03-2019 17:34 . Reden: Stukje van services toegevoegd ]


Acties:
  • 0 Henk 'm!

  • OB1
  • Registratie: April 2014
  • Laatst online: 21:23
n9iels schreef op zaterdag 23 maart 2019 @ 17:31:
Bekend probleem wat je omschrijft. De scheiding tussen de klassieke back-end en front-end is er eigenlijk niet meer. De code van de "front-end" is net zo complex als de code van de back-end en heeft testen nodig.

In mijn ervaring is Angular in praktijk het meest volwassen is hierin. Met de HttpClientTestingModule kun je nagaan of er daadwerkelijk een request gemaakt wordt, en deze ook afvangen en i.p.v. mockdata terug sturen wat verder door de applicatie gebruikt wordt (zie: https://angular.io/guide/http#testing-http-requests).

Dit is hoe ik het meestal aanpak. De front-end wordt dus volledig los van de back-end getest m.b.v. het onderscheppen en simuleren van calls naar de back-end. Wat ik ook redelijk vaak doe is de communicatie met een API in een aparte class stoppen, een service zoals dit in de Angular wereld heet. Deze class kan dan gewoon met reguliere testing frameworks getest worden.
Ik heb inderdaad de code die de requests maakt in een aparte service layer al staan.

Dat linkje wat je aangeeft zit er wel duidelijk uit, ook tof dat er error meldingen gesimuleerd mee kunnen worden. Ik ga er naar kijken!

AMD 2700x @ 4.15 GHz | Vega 56 (Vega 64 BIOS) | 32 GB DDR4 | MSI X470 Gaming Plus | Intel 600P 1TB | Corsair RM550X


Acties:
  • +1 Henk 'm!

  • Ed Vertijsment
  • Registratie: Juli 2014
  • Laatst online: 05-10 09:29
Zij zien in deze gevallen de front en backend als grotendeels 2 verschillende entiteiten die met een interface (REST api) met elkaar praten. De communicatie van de rest API wordt deels op de backend, deels op de frontend getest.

De backend tests controleren de uitvoer van de API gegeven een bepaalde state en request. Hiervoor maken we gebruik van een test database, dit zit standaard in Django, het framework wat wij gebruiken.

In de frontend controleren we of een bepaalde actie (bijvoorbeeld het laden van een pagina) in een bepaalde (XHR) request resulteerd. Of je nou een fancy HTTP package gebruikt of ruwe requests afschiet, pretty much al deze tools resulteren in een XHR of fetch request die je kunt spy'en. Wij gebruiken een custom REST O(R)M library die op zijn beurt Axios (http client) gebruikt, toch kunnen de gewoon Ajax calls in de gaten houden.

Vervolgens testen we in de frontend of een bepaald antwoord van de server (dat we los in de backend testen) resulteert in bepaalde informatie op je scherm. We werken in deze gevallen vaak met React en gebruiken Enzyme hiervoor.

Een combinatie van deze tests resulteert in:

- Weten dat als de frontend "iets" doet het juiste verzoek wordt gedaan.
- Weten dat een bepaald verzoek resulteert in een bepaald antwoord.
- Weten dat een bepaald antwoord resulteert in de juiste informatie.

Dit geeft aardig wat zekerheid en geeft enige houvast wat waar te testen. Ook hoeven de frontend tests niet perse een backend op te spinnen om mee te werken. Soms, niet altijd moet ik zeggen zijn er integratietests die nog een keer los controleren of de frontend wel echt met de backend overweg kan. Hiermee vangen we details als "praat de frontend wel met de juiste api", of "werkt de configuratie wel".

Acties:
  • +1 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 13:59
OB1 schreef op zaterdag 23 maart 2019 @ 16:59:
Er zijn bepaalde mock-api's (bijvoorbeeld in Postman), hierin kunnen per endpoint standaard responses worden ingesteld. Echter, deze responses zijn altijd hetzelfde. Hierdoor kan ik niet ervoor kiezen om in de ene test bij endpoint X een 200 terug te sturen en bij de andere test een 401 terug te sturen. Ik zou echter wel graag beide scenario's willen testen.
Als je je URLs niet hardcode maar configurabel maakt kant dat prima. Dan laat je een 'gewone' login naar /login gaan en een 401 naar /login401 bijvoorbeeld.

Afgezien daarvan; met Selenium kun je ook Angular/React front-ends prima testen. Het is verder een beetje aan jullie behoeften op welke manier je dat dan doet. Meestal wordt front-end logica en ui componenten via unit-tests gedaan, en de ui flow zelf via volledige end-to-end tests die tegen een echte back-end draaien. Die laatste heb je toch nodig, en daarin kan je meteen de UI meepakken als je dat wil.

[ Voor 24% gewijzigd door Hydra op 25-03-2019 08:28 ]

https://niels.nu


Acties:
  • +1 Henk 'm!

  • OB1
  • Registratie: April 2014
  • Laatst online: 21:23
Bedankt voor jullie inzichten, het heeft mij heel erg geholpen!

Ik heb het nu als volgt toegepast:

Protractor voor e2e en de GUI tests. Deze doorlopen een complete flow in iedere test - van inloggen tot het uitvoeren van de actie zelf. Deze worden lokaal gedraaid net als de API. We hebben een SQL dump die we van te voeren uit voeren om de broodnodige data aanwezig te hebben.

Karma voor de unit tests van de components. Alle services zijn zo opgezet dat ze eenvoudig gemocked kunnen worden.

AMD 2700x @ 4.15 GHz | Vega 56 (Vega 64 BIOS) | 32 GB DDR4 | MSI X470 Gaming Plus | Intel 600P 1TB | Corsair RM550X

Pagina: 1