Logo Light
Published on

Playwright (3. díl) - Testování API - Úvod

1. Úvod

Playwright je známý především jako nástroj pro automatizaci UI testů. Poskytuje ale i nástroje pro API testování. V rámci jednoho frameworku tak můžeme např.:

  • kombinovat API a UI testy (např. vytvořit data přes API a zkontrolovat je v UI)
  • sdílet autentizaci a kontext mezi různými testy
  • psát testy, které přímo ověřují funkčnost API

Výhody testování API v Playwrightu oproti Postmanu

  • jeden framework pro UI i API testy
  • Snadná integrace do CI/CD (stejný test runner, stejné reporty)
  • využití programovacího jazyka (v Postmanu je omezené)
  • snadnější údržba testů (subjektivní názor :)

Výhody testování API v Postmanu oproti Playwrightu

  • jednoduchost a přehlednost
  • snadná spolupráce v týmu
  • integrované mockování

2. Základní koncept API testů v Playwrightu

Pro API testování Playwright poskytuje request fixture, která umožňuje posílat HTTP požadavky.

Hlavní metody pro CRUD jsou:

  • request.get(url)
  • request.post(url, { data })
  • request.put(url, { data })
  • request.delete(url)

Každý požadavek vrací objekt APIResponse, ze kterého můžeme získat:

  • status() – HTTP status kód
  • ok() – boolean, zda odpovědělo 2xx
  • json() – parsovaný JSON
  • text() – odpověď jako text

4. Praktické příklady API testů

4.1 GET požadavek

import { test, expect } from '@playwright/test'

test('GET /users vrací seznam uživatelů', async ({ request }) => {
  const response = await request.get('/users')

  // Očekáváme HTTP 200
  expect(response.status()).toBe(200)

  // Parsujeme JSON odpověď
  const users = await response.json()

  // Zkontrolujeme, že se vrátilo pole, a že není prázdné
  expect(Array.isArray(users)).toBeTruthy()
  expect(users.length).toBeGreaterThan(0)
})

4.2 POST požadavek

test('POST /users vytvoří nový záznam', async ({ request }) => {
  const newUser = {
    name: 'John',
    email: 'john@icanbreakit.eu',
  }

  const response = await request.post('/users', {
    data: newUser,
  })

  expect(response.status()).toBe(201) // Created

  const savedUser = await response.json()
  expect(savedUser.name).toBe(newUser.name)
  expect(savedUser.id).toBeDefined() // databáze vytvořila id uživatele
})

4.3 PUT požadavek

test('PUT /users/1 změní záznam', async ({ request }) => {
  const changes = {
    name: 'Johnny',
  }

  const response = await request.put('/users/1', { data: changes })
  expect(response.status()).toBe(200)
  const changedUser = await response.json()
  expect(changedUser.name).toBe(changes.name)
})

4.4 DELETE požadavek

test('DELETE /users/1 smaže záznam', async ({ request }) => {
  const response = await request.delete('/users/1')
  expect(response.status()).toBe(200)
})

5. Nejčastěji používané asserty v Playwright API testech

toBe()

expect(response.status()).toBe(200) // kontrola konkrétního HTTP kódu
expect(value).toBe(value) /* porovnává hodnotu s očekávanou hodnotou voláním
                             metody `Object.is`, tzn. porovnává referenci na objekty,
                             nikoliv jen jejich obsah. Chová se podobně jako `===` */

toContain()

expect('some string').toContain('substring') // ověření, že string obsahuje daný substring
expect([1, 2, 3]).toContain(2) // ověření, že pole (nebo množina) obsahuje očekávanou hodnotu

toContainEqual()

expect(await response.json()).toContainEqual({ example: 1 })
// odpověď je pole (nebo množina) a obsahuje daný objekt

objectContaining()

expect(await response.json()).toContainEqual(expect.objectContaining({ example: 1 }))
// odpověď je pole a obsahuje objekt, který obsahuje uvedené dvojice `klíč: hodnota`

toHaveProperty()

expect(object).toHaveProperty('id') // objekt obsahuje daný klíč

toBeTruthy()

expect(response.ok()).toBeTruthy() // ověření, že odpověď je 2xx
expect(Array.isArray(data)).toBeTruthy() // ověření, že odpověď je pole

toBeGreaterThan()

expect(data.length).toBeGreaterThan(0) // ověření, že pole není prázdné

toBeDefined()

expect(value).toBeDefined() // kontrola existence hodnot

toBeNull()

expect(value).toBeNull() // kontrola null hodnoty