Skip to content

Commit 27c4002

Browse files
nilshartmann96ArneLimburg
authored andcommitted
test: Add wiremock
1 parent 211dbec commit 27c4002

7 files changed

Lines changed: 167 additions & 24 deletions

File tree

.github/workflows/build.yaml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,56 @@ jobs:
3131
- name: Build
3232
run: npm run build
3333

34+
test-client:
35+
runs-on: ubuntu-latest
36+
needs: build-client
37+
defaults:
38+
run:
39+
working-directory: customer-client
40+
steps:
41+
- name: Checkout
42+
uses: actions/checkout@v5
43+
44+
- name: Set up Node.js
45+
uses: actions/setup-node@v4
46+
with:
47+
node-version: '22'
48+
cache: npm
49+
cache-dependency-path: customer-client/package-lock.json
50+
51+
- name: Install dependencies
52+
run: npm ci
53+
54+
- name: Start WireMock
55+
run: docker compose up -d wiremock
56+
working-directory: .
57+
58+
- name: Wait for WireMock
59+
run: |
60+
until curl -sf http://localhost:8080/__admin/health > /dev/null; do
61+
echo "Waiting for WireMock..."
62+
sleep 2
63+
done
64+
working-directory: .
65+
66+
- name: Install Playwright browsers
67+
run: npx playwright install --with-deps chromium
68+
69+
- name: Run Playwright tests with WireMock
70+
run: npm run test:wiremock
71+
72+
- name: Upload Playwright report
73+
uses: actions/upload-artifact@v4
74+
if: failure()
75+
with:
76+
name: playwright-report-wiremock
77+
path: customer-client/playwright-report/
78+
79+
- name: Stop WireMock
80+
if: always()
81+
run: docker compose down
82+
working-directory: .
83+
3484
build:
3585
runs-on: ubuntu-latest
3686
needs: build-client

README.md

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,64 @@
1-
# Workshop API Design
1+
# Workshop Consumer-Driven Contract Testing
22

3-
Herzlich willkommen zum Workshop API Design.
3+
Herzlich willkommen zum Workshop Consumer-Driven Contract Testing.
44

5-
## Übungen
5+
## Übung: Playwright Tests mit WireMock
66

7-
### API Design
7+
In dieser Übung werden die Playwright-Tests so angepasst, dass sie nicht mehr gegen den echten Backend-Service laufen, sondern alle HTTP-Requests über WireMock gemockt werden.
88

9-
- [OpenAPI](https://github.com/openknowledge/workshop-api-design/tree/openapi)
10-
- [Mocking](https://github.com/openknowledge/workshop-api-design/tree/wiremock)
11-
- [AsyncAPI](https://github.com/openknowledge/workshop-api-design/tree/asyncapi)
9+
### Ausgangssituation
1210

13-
### API Testing
11+
Im Verzeichnis `customer-client/test/` befinden sich drei Testdateien:
1412

15-
- [Pact](https://github.com/openknowledge/workshop-api-design/tree/pact-mock-server)
16-
- [Pact Pipeline](https://github.com/openknowledge/workshop-api-design/tree/pact)
13+
- `customer-list.spec.ts` – Tests für die Kundenliste
14+
- `customer-detail.spec.ts` – Tests für die Kundendetailseite (Adressen anlegen und bearbeiten)
15+
- `create-customer.spec.ts` – Tests für das Anlegen neuer Kunden
1716

18-
### API Security
17+
Die Tests laufen aktuell gegen den echten Backend-Service (`http://localhost:8181`).
18+
Im Verzeichnis `wiremock/mappings/` liegen bereits zwei WireMock-Mappings:
1919

20-
- [JWT](https://github.com/openknowledge/workshop-api-design/tree/jwt)
21-
- [OAuth2](https://github.com/openknowledge/workshop-api-design/tree/oauth2)
22-
- [OAuth2 mit PKCE](https://github.com/openknowledge/workshop-api-design/tree/oauth2-pkce)
20+
- `get-customers.json` – Mockt `GET /customers/`
21+
- `options-customers.json` – Mockt `OPTIONS /customers/`
2322

24-
### API Governance
23+
WireMock wird per Docker Compose gestartet und ist auf Port `8080` erreichbar:
2524

26-
- [Linting](https://github.com/openknowledge/workshop-api-design/tree/linting)
25+
```bash
26+
docker compose up wiremock
27+
```
2728

28-
### API Management
29+
### Ziel
2930

30-
- [Rate Limiting](https://github.com/openknowledge/workshop-api-design/tree/rate-limiting)
31-
- [Backstage](https://github.com/openknowledge/workshop-api-design/tree/backstage)
31+
Alle HTTP-Requests in den Playwright-Tests sollen durch WireMock-Mappings ersetzt werden, sodass der echte Backend-Service für die Tests nicht mehr benötigt wird.
3232

33-
### API Operation
33+
### Aufgaben
3434

35-
- [Observability](https://github.com/openknowledge/workshop-api-design/tree/observability)
35+
1. **Playwright auf WireMock umstellen**
36+
Ändere in `customer-client/playwright.config.ts` die `VITE_API_URL` so, dass sie auf den WireMock-Server (`http://localhost:8080`) zeigt.
3637

37-
### API Evolution
38+
2. **WireMock-Mappings für die Kundendetailseite anlegen**
39+
Für die Tests in `customer-detail.spec.ts` werden Kundendaten für `0815` (Max Mustermann) und `007` (James Bond) benötigt. Lege entsprechende Mappings an:
40+
- `GET /customers/0815` – Max Mustermann mit Rechnungs- und Lieferadresse
41+
- `GET /customers/007` – James Bond ohne Adressen
42+
- `PUT /customers/0815/billing-address` – Rechnungsadresse speichern
43+
- `PUT /customers/0815/delivery-address` – Lieferadresse speichern
44+
- Adressvalidierung (PLZ-Prüfung) für die entsprechenden Testszenarien
3845

39-
- [Versioning](https://github.com/openknowledge/workshop-api-design/tree/versioning)
46+
3. **WireMock-Mapping für das Anlegen neuer Kunden anlegen**
47+
Für `create-customer.spec.ts` wird ein `POST /customers/` benötigt, der einen neuen Kunden anlegt.
48+
49+
4. **Alle Tests erfolgreich ausführen**
50+
Starte WireMock per Docker Compose und führe die Tests aus:
51+
```bash
52+
docker compose up wiremock
53+
cd customer-client
54+
npm test
55+
```
56+
Alternativ kann auch `npm test:ui` verwendet werden, um sich die UI-Interaktionen in der Playwright UI anzusehen.
57+
58+
### Tipps
59+
60+
- WireMock-Mappings liegen als JSON-Dateien in `wiremock/mappings/`. WireMock lädt diese Dateien beim Start automatisch.
61+
- Die bestehenden Mappings (`get-customers.json`, `options-customers.json`) können als Vorlage für neue Mappings genutzt werden.
62+
- Für das Laden neuer Mappings ohne Neustart kann die WireMock Admin API unter `http://localhost:8080/__admin/mappings` genutzt – oder der WireMock-Container einfach neu gestartet werden.
63+
- Bei einem `GET`, `POST`- oder `PUT`-Request muss ggf. auch der entsprechende `OPTIONS`-Preflight-Request gemockt werden (CORS).
64+
- Die Adressvalidierung in `customer-detail.spec.ts` erwartet spezifische Fehlermeldungen – die Responses im Mapping müssen die exakten Fehlertexte aus den Tests zurückliefern.

customer-client/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
"format:check": "prettier --check .",
1212
"preview": "vite preview",
1313
"test": "playwright test",
14-
"test:ui": "playwright test --ui"
14+
"test:ui": "playwright test --ui",
15+
"test:wiremock": "playwright test --config=playwright.wiremock.config.ts"
1516
},
1617
"dependencies": {
1718
"@tanstack/react-form": "^1.28.0",
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { defineConfig, devices } from '@playwright/test';
2+
3+
process.env.VITE_API_URL = 'http://localhost:8080';
4+
5+
export default defineConfig({
6+
testDir: './test',
7+
testMatch: 'customer-list.spec.ts',
8+
fullyParallel: false,
9+
forbidOnly: !!process.env.CI,
10+
retries: process.env.CI ? 2 : 0,
11+
workers: 1,
12+
reporter: 'html',
13+
use: {
14+
baseURL: 'http://localhost:5173',
15+
trace: 'on-first-retry',
16+
},
17+
projects: [
18+
{
19+
name: 'chromium',
20+
use: { ...devices['Desktop Chrome'] },
21+
},
22+
],
23+
webServer: {
24+
command: 'npm run dev',
25+
url: 'http://localhost:5173',
26+
reuseExistingServer: !process.env.CI,
27+
},
28+
});

docker-compose.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,10 @@ services:
3737
- "3000:80"
3838
depends_on:
3939
- customer-service
40+
41+
wiremock:
42+
image: wiremock/wiremock:3.5.4
43+
ports:
44+
- "8080:8080"
45+
volumes:
46+
- "./wiremock:/home/wiremock"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"request": {
3+
"method": "GET",
4+
"url": "/customers/"
5+
},
6+
"response": {
7+
"status": 200,
8+
"headers": {
9+
"Content-Type": "application/json",
10+
"Access-Control-Allow-Origin": "*"
11+
},
12+
"jsonBody": [
13+
{ "number": "0815", "name": "Max Mustermann" },
14+
{ "number": "0816", "name": "Erika Mustermann" },
15+
{ "number": "007", "name": "James Bond" }
16+
]
17+
}
18+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"request": {
3+
"method": "OPTIONS",
4+
"url": "/customers/"
5+
},
6+
"response": {
7+
"status": 204,
8+
"headers": {
9+
"Access-Control-Allow-Origin": "*",
10+
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
11+
"Access-Control-Allow-Headers": "Content-Type, Accept-Language"
12+
}
13+
}
14+
}

0 commit comments

Comments
 (0)