Ein E2E-Test dient dazu eine Anwendung “von Vorne bis Hinten” durchzutesten. Dabei sind viele Hürden zu meistern, angefangen von erreichbarer Infrastruktur, über Authentifizierung bis hin zu konstanten Datenbeständen. Das mag in einigen Projekten nur schwer und mit viel Aufwand realisiert bar sein. Ein Unit-Testing in Angular ist hier in vielen Fällen kaum ein ausreichender Ersatz. Also muss ein Mock her, um die Datenschnittstellen abzulösen. Eine praktikable Lösung: json-server
“Get a full fake REST API with zero coding” das ist json-server. Die Grundlage dafür ist ein Node-Projekt: https://github.com/typicode/json-server + in der einfachsten Form eine projektspezifische JSON Datei die unseren Daten enthält. Eine solche Datei “db.json”:
{
"data": [
{
"id": 1,
"message": "Lorem ipsum"
},
{
"id": 3,
"message": "Clita kasd gubergren"
},
{
"id": 4,
"message": "Takimata sanctus est Lorem"
}
],
"demo": {
"message": "Demo Object"
}
}
und der Start von json-Server (Default Port: 4000) :
json-server --watch db.json
Fertig ist unser “backend”. In unserem Beispiel generiert json-server basierend auf unserer json-Datei zwei Rest-Schnittstellen: http://localhost:4000/data und http://localhost:4000/demo die sich direkt Abfragen lassen und die angegebenen Daten liefern. Aber nicht nur das. Auch POST/PUT/DELETE Funktionen werden direkt unterstützt. Sollte die zu simulierende Schnittstelle komplexer sein gibt es die Möglichkeit individuelle Routen anzugeben oder sogar programmatisch auf bestimmte Anfragen zu reagieren.
+ Protractor
Um das zusammen mit Protractor zu nutzen sind folgende Schritte zu implementieren
- für unsere Tests benötigen wir den laufenden JSON-Server. Charmant: wir starten den Server in der prepare Methode von Protractor mittels _child_process_
onPrepare() {
const { spawn } = require('child_process')
const serverPath = require('path').join(__dirname, './json/server.js');
spawn('node', [serverPath]);
...
(protractor.conf.js , wir verwenden hier ein individuelles json-server-Script, um wie bereits angesprochen programmatisch auf einige Anfragen zu reagieren, siehe server.js-Demo + Doku “Module” )
2. wir verwenden eine proxy-Konfiguration um alle Anfragen an bestimmte URLs (unsre Backend) auf unseren json-server um zu leiten:
{
"/api/*": {
"target": "http://localhost:4000",
"secure": false,
"changeOrigin": true,
"logLevel": "debug",
"pathRewrite": {
"^/api/": "/"
}
}
}
alle Anfragen an "http://.../api/... werden umgeleitet auf http://localhost:4000/...
3. eine solche Proxy-Konfiguration lässt sich eigentlich beim serve-Befehl mittels “-proxy-config” übergeben. Leider unterstützt das E2E-Ziel diese Option nicht ( s. github issue ). Stattdessen müssen wir die entsprechende Konfiguration ergänzen die wir dann beim E2E-Target verwenden( angular.json ).
"architect": {
...
"serve": {... },
"serve-e2e": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "ng-json-server:build",
"proxyConfig": "e2e/proxy.conf.json",
"port": 4300
},
....
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "ng-json-server:serve-e2e"
},
"configurations": {
"production": {
"devServerTarget": "ng-json-server:serve-e2e:production"
}
}
}
Vollständiges Beispiel @GitHub
Das war’s. Ein
npm run e2e
Startet nun unseren JSON-Server, konfiguriert den Development Server mit unserem Proxy und lässt alle E2E-Tests Laufen.