Codineers Rosenheim Meetup, 2. November 2023 (Dominik Haas, QAware)
Wer kennt es nicht: Langsame, instabile und wartungsintensive Tests von Frontends und die Schmerzen damit.
Aber in den letzten Jahren und Monaten hat sich hier viel getan und Playwright ist der vielversprechende neue Stern der Web-Automatisierung.
Ich werde in meinem Talk über das Testen von Frontends sprechen und speziell auf Playwright als spannendes Werkzeug eingehen.
Neben der praktischen Einführung möchte ich auch mit Euch über Best Practices sprechen und einen Versuch wagen die Testpyramide zu töten (oder sie zumindest etwas zu beschädigen).
4. Beim Frontend-Testing* automatisieren wir den
Browser und simulieren unseren Benutzer.
4
*aka E2E-Testing
Vorteile
■ So nah am Nutzer wie möglich
■ Testet alle Bestandteile unseres Codes
Nachteile
■ Langsamer
■ Unzuverlässiger
■ Schwieriger zu schreiben (Kosten?)
■ Wartungsintensiver (Kosten?)
Frontend Service DB
Service
TEST
5. Wegen Aufwand, Zeit und Kosten hat sich die
Testpyramide etabliert.
5
Quelle: https://en.wikipedia.org/wiki/Test_automation
Wenig Frontend-Tests
Unit-Tests als breite Basis,
Großteil der fachlichen Absicherung
8. Playwright - die wichtigsten Kriterien
■ Cross-browser (& cross-platform)
■ Verschiedene Programmiersprachen (TypeScript, .NET, Java…)
■ Wichtigste Features
– Auto-wait (SPAs)
– Steuern den Browser von außen #NotCypress
– Promises oder synchrones Programmiermodell #NotCypress
■ Bietet in paar interessante Werkzeuge
– Inspector
– Trace Viewer
– Codegen - generiere Code
■ Backed by Microsoft
8
9. Playwright - los gehts
#setup a new project
npm init playwright@latest
#run tests and show browser
npx playwright test --headed
#open in Visual Studio Code (there is an extension available)
code .
11. Code Generierung
Das Tooling ist vielfältig (und unübersichtlich)
Tests ausführen & Debugging Testergebnisse
Playwright Inspector
Visual Studio Code
Chrome Recorder +
Extension
Jetbrains Aqua
CLI
IDEs
Videos
Test Reports
Traces
Codegen
Playwright UI
Playwright
3rd Party
12. Code Generierung
Das Tooling ist vielfältig (und unübersichtlich)
Tests ausführen & Debugging Testergebnisse
Playwright Inspector
Visual Studio Code
Chrome Recorder +
Extension
Jetbrains Aqua
CLI
IDEs
Videos
Test Reports
Traces
Codegen
Playwright UI
Playwright
3rd Party
● Playwright setzt auf eigene GUIs
& Visual Studio Code (?)
● Das Recording von Tests ist
okayish
● Traces sind cool
13. Tests lassen sich einfach ausführen und erzeugen
einen Test-Report
■ Tests können per CLI ausgeführt
werden
npx playwright test
■ Dabei wird ein Test Report erstellt
13
14. Traces bieten eine Timeline mit ihren Aktionen
und viel Metainformationen
15. Playwright bietet eine Extension für Visual
Studio Code an
15
■ Ausführung und Debugging von Tests
■ Konfiguration von Playwright in der
IDE
■ Visualisierung und übernahme von
Locator
(leider keine Auswahlmöglichkeit)
16. Playwright bietet einen UI-Mode (ähnlich zu
Cypress)
■ Start mit
npx playwright test --ui
■ Alle Tests mit Ausführung &
Watch-Mode
■ Anzeige von Traces auf der
rechten Seite
■ In Traces hat man den Zugriff
auf den DOM (inspect)
16
18. Beispiel für einen einfachen Test
import { test, expect } from '@playwright/test';
test('test', async ({ page }) => {
await page.goto('https://duckduckgo.com/');
await page.getByPlaceholder('Search the web without being tracked').click();
await page.getByPlaceholder('Search the web without being tracked').fill('test');
await page.getByLabel('Search', { exact: true }).click();
await page.waitForURL('https://duckduckgo.com/?**');
const searchResultsLocator = page.getByTestId("result");
expect(await searchResultsLocator.count()).toBeGreaterThanOrEqual(10);
});
19. Beispiel für einen einfachen Test
import { test, expect } from '@playwright/test';
test('test', async ({ page }) => {
await page.goto('https://duckduckgo.com/');
await page.getByPlaceholder('Search the web without being tracked').click();
await page.getByPlaceholder('Search the web without being tracked').fill('test');
await page.getByLabel('Search', { exact: true }).click();
await page.waitForURL('https://duckduckgo.com/?**');
const searchResultsLocator = page.getByTestId("result");
expect(await searchResultsLocator.count()).toBeGreaterThanOrEqual(10);
});
await funktioniert - yeah!
locators & interactions
assertions
Playwright Testing (!= Playwright Library)
20. Mit einem Locator wähle ich Elemente auf der
Seite aus
20
//recommended locators (samples)
page.getByPlaceholder("Search the web")
page.getByTestId("result")
page.getByLabel("Search")
//other locators
page.locator("[name = 'q']")
page.locator(".myClass")
page.locator("h3")
■ von Playwright empfohlene Locator
– getByRole
– getByText
– getByLabel
– getByPlaceholder
– getByAltText
– getByTitle
– getByTestId
■ Sonstige
– locator
(für CSS- oder Xpath-Selektoren)
21. Mit Navigation & Actions steuere ich den
Browser
21
//navigation
page.goto("https://google.de");
//sample interactions
let input = page.getByPlaceholder("Do");
await input.click()
await input.fill("Search")
await input.press("Enter")
■ Navigation
■ Interaktion
– Suche ein Element per Locator
– Führe eine Aktion auf dem Element
aus, zum Beispiel: click, fill, send
22. Mit Assertions prüfe ich die Ergebnisse
22
//auto-retrying assertions
await expect(locator).toBeVisible()
await expect(locator).toContainText('test')
await expect(locator).toBeEnabled()
//non-retrying assertions
expect(value).toBe(1)
expect(value).toBeLessThan(10)
expect(value).toBeTruthy()
■ Auto-retrying assertions für Elemente
auf der Seite
■ Non-retrying assertions für einfache
Checks
23. Tests können mit Playwright auch aufgenommen
werden
■ Es gibt verschiedene Recorder
– Codegen
– Visual Studio Code
– Jetbrains Aqua
– Chrome Developer Tools + Extension
■ Als Startpunkt ok, aber noch nicht richtig gut
23
27. Erzeuge mit dem Page Object Pattern eine API
für dein Frontend!
■ Code Reuse
■ Locator müssen nur
an einer Stelle
geändert werden
■ Tests werden
einfach und
übersichtlich
27
export class GooglePage {
constructor(private readonly page: Page) {
}
async goto() {
await this.page.goto('https://google.de');
}
async search(query: string) {
let queryInput = this.page.locator("[name = 'q']");
await queryInput.fill(query);
await queryInput.press('Enter');
await this.page.waitForURL('**/search**');
}
...
}
28. Fixtures helfen, die Page Objects für die Tests zu
erzeugen.
28
//usage
import {test} from './my-test'
import {expect} from '@playwright/test'
test('basic search', async ({ googlePage }) => {
await googlePage.search('test');
const results = await googlePage.getSearchResults();
expect(results.length).toBeGreaterThan(4);
});
//custom fixture
export const test = base.extend<MyFixtures>({
googlePage: async({page}, use) => {
const googlePage = new GooglePage(page);
await use(googlePage);
//potential clean up
}
})
30. Wegen Aufwand, Zeit und Kosten hat sich die
Testpyramide etabliert.
30
Quelle: https://en.wikipedia.org/wiki/Test_automation
Wenig Frontend-Tests
Unit-Tests als breite Basis,
Großteil der fachlichen Absicherung
31. 31
Mit Playwright & Best Practices lassen sich gute Tests
schreiben, die:
- stabil laufen
- weniger wartungsintensiv sind
- viel auf einmal abdecken
Hinterfragt mal Euren “Aufwand / Umfang Absicherung”
Created with: ChatGPT
32. Vielleicht mal den Testing-Quader?
Frontend Test
API Test
Unit
Test der “wichtigen” Klassen.
Algorithmen, Regeln, Logik
(Unit, inklusive Integrationstests)
Breite fachliche Absicherung
inklusive Frontend
Breite fachliche Absicherung
der APIs (zum Beispiel REST)