![]()
Testowanie baz danych z Playwright to kolejny artykuł z serii wpisów dotyczących automatyzacji testów. Przedmiotowy wpis ma za zadanie wdrożyć Was w tematykę wykorzystania Playwrighta wraz z bazami danych.
Wprowadzenie
Testy automatyczne to obecnie standardowy element procesu tworzenia oprogramowania, który znacząco zwiększa jego jakość i stabilność. W praktyce, testy UI, API czy jednostkowe to często za mało, aby mieć pewność, że aplikacja działa poprawnie na wszystkich poziomach. Szczególnie ważne są testy integracyjne, które sprawdzają poprawność działania aplikacji w środowisku z prawdziwymi danymi oraz integrację z zewnętrznymi komponentami, takimi jak bazy danych.
W tym kontekście integracja testów automatycznych z bazą danych jest niezwykle istotna. Pozwala ona na weryfikację, czy aplikacja prawidłowo zapisuje, aktualizuje i odczytuje dane. Zyskujemy dzięki temu pełniejszy obraz jakości produktu oraz większą pewność, że zmiany w kodzie nie wprowadzą regresji.
W niniejszym tekście skupimy się na praktycznej integracji Playwright — popularnego frameworka do testów end-to-end — z dwoma powszechnie stosowanymi bazami danych: Microsoft SQL Server (MSSQL) oraz PostgreSQL. Omówimy konfigurację, przykładowe scenariusze testowe, dobre praktyki oraz sposoby rozwiązywania typowych problemów. W szczególności skupimy się na zagadnieniu testowanie baz danych w Playwright, które zyskuje coraz większą popularność w projektach o wysokich wymaganiach jakościowych.
Rola testów bazodanowych w procesie wytwarzania oprogramowania
Testy automatyczne integrujące się z bazą danych to nie tylko potwierdzenie, że UI działa, ale przede wszystkim potwierdzenie, że dane faktycznie trafiają tam, gdzie powinny, oraz są odpowiednio przetwarzane. Taka warstwa testów pozwala między innymi na:
- Weryfikację poprawności zapisu i odczytu danych — sprawdzamy, czy formularze czy API poprawnie przekazują dane do bazy.
- Testowanie spójności danych — np. czy referencje między tabelami są zachowane.
- Testowanie skomplikowanych zapytań i procedur składowanych — czy działają tak, jak zaplanowano.
- Testowanie zachowania w sytuacjach wyjątkowych — np. co się stanie, jeśli w bazie pojawią się dane niezgodne z oczekiwaniami.
- Zapewnienie, że zmiany w aplikacji lub bazie danych nie wprowadzają regresji.
Bez takich testów łatwo przeoczyć błędy, które ujawnią się dopiero w produkcji, często w krytycznych sytuacjach. To wszystko sprawia, że testowanie baz danych w Playwright staje się nie tylko techniczną możliwością, ale wręcz koniecznością w nowoczesnym cyklu życia aplikacji.
Konfiguracja środowiska testowego
Instalacja Playwright
Playwright to nowoczesny, szybki i wszechstronny framework do testów end-to-end, który pozwala automatyzować przeglądarki Chrome, Firefox i Safari. Aby go zainstalować:
npm install @playwright/test
Instalacja sterowników do baz danych
Dla połączenia z bazą danych MSSQL oraz PostgreSQL potrzebujemy odpowiednich bibliotek:
- MSSQL:
npm install mssql
- PostgreSQL:
npm install pg
Konfiguracja połączeń
Ważne jest, aby bezpiecznie przechowywać dane do połączeń (user, password, host itd.), np. w pliku .env lub menedżerze sekretów.
Przykładowa konfiguracja:
MSSQL:
const sql = require(’mssql’);
const mssqlConfig = {
user: process.env.DB_USER,
password: process.env.DB_PASS,
server: process.env.DB_HOST,
database: process.env.DB_NAME,
options: {
encrypt: true, // Wymagane np w Azure
trustServerCertificate: true // Dla certyfikatów samopodpisanych
}
};
PostgreSQL:
const { Client } = require(’pg’);
const pgConfig = {
user: process.env.DB_USER,
host: process.env.DB_HOST,
database: process.env.DB_NAME,
password: process.env.DB_PASS,
port: Number(process.env.DB_PORT) || 5432,
};
Pisanie testów automatycznych z integracją bazy danych
Przykład testu: zapis danych z formularza do bazy MSSQL
const { test, expect } = require(’@playwright/test’);
const sql = require(’mssql’);
test(’Form data is saved to MSSQL database’, async ({ page }) => {
// Połączenie z bazą MSSQL
await sql.connect(mssqlConfig);
// Wejście na stronę formularza
await page.goto(’http://localhost:3000/form’);
// Wypełnianie formularza
await page.fill(’#name’, 'John Doe’);
await page.fill(’#email’, 'john.doe@example.com’);
await page.click(’#submit’);
// Zapytanie do bazy
const result = await sql.query(`
SELECT * FROM users WHERE email = 'john.doe@example.com’
`);
// Walidacja danych
expect(result.recordset.length).toBeGreaterThan(0);
expect(result.recordset[0].name).toBe(’John Doe’);
// Zamknięcie połączenia
await sql.close();
});
Analogiczny test dla PostgreSQL:
const { test, expect } = require(’@playwright/test’);
const { Client } = require(’pg’);
test(’Form data is saved to PostgreSQL database’, async ({ page }) => {
const client = new Client(pgConfig);
await client.connect();
await page.goto(’http://localhost:3000/form’);
await page.fill(’#name’, 'Jane Doe’);
await page.fill(’#email’, 'jane.doe@example.com’);
await page.click(’#submit’);
const res = await client.query(`
SELECT * FROM users WHERE email = 'jane.doe@example.com’
`);
expect(res.rows.length).toBeGreaterThan(0);
expect(res.rows[0].name).toBe(’Jane Doe’);
await client.end();
});
Testowanie bardziej zaawansowanych operacji na bazie danych
Testowanie procedur składowanych
W wielu systemach logika biznesowa jest ukryta w procedurach składowanych lub funkcjach bazy danych. Ważne jest, aby je również testować.
MSSQL:
const result = await sql.query(`
EXEC GetUserByEmail 'john.doe@example.com’
`);
expect(result.recordset[0].name).toBe(’John Doe’);
PostgreSQL:
const res = await client.query(`
SELECT * FROM get_user_by_email(’jane.doe@example.com’)
`);
expect(res.rows[0].name).toBe(’Jane Doe’);
Przykład złożonych zapytań i agregacji
Często wymagane jest wykonanie zapytań grupujących, filtrujących i agregujących dane.
MSSQL:
const result = await sql.query(`
SELECT department, COUNT(*) AS employee_count
FROM employees
GROUP BY department
HAVING COUNT(*) > 5
`);
expect(result.recordset.length).toBeGreaterThan(0);
PostgreSQL:
const res = await client.query(`
SELECT department, COUNT(*) AS employee_count
FROM employees
GROUP BY department
HAVING COUNT(*) > 5
`);
expect(res.rows.length).toBeGreaterThan(0);
Dobre praktyki w testach integrujących się z bazą danych
Izolacja testów
Testy powinny być niezależne od siebie, aby wyniki jednego testu nie wpływały na wyniki innych. Można to osiągnąć przez:
- Uruchamianie testów na osobnych, tymczasowych bazach danych.
- Używanie transakcji z rollbackiem po teście, by odwrócić zmiany.
- Resetowanie bazy do stanu początkowego przed każdym testem.
Transakcje i rollback
Przykład użycia transakcji w testach MSSQL:
const transaction = new sql.Transaction();
await transaction.begin();
try {
// wykonaj operacje testowe w kontekście transakcji
await transaction.rollback(); // Cofnij zmiany
} catch (error) {
await transaction.rollback();
throw error;
}
Podobnie w PostgreSQL:
await client.query(’BEGIN’);
try {
// operacje testowe
await client.query(’ROLLBACK’); // cofnięcie zmian
} catch (e) {
await client.query(’ROLLBACK’);
throw e;
}
Mockowanie i stubowanie
W testach jednostkowych, gdzie testujemy logikę niezależną od bazy danych, warto stosować mocki (udawanie odpowiedzi bazy) i stuby, aby testy były szybkie i nie zależały od środowiska bazodanowego.
Automatyzacja przygotowania danych testowych
Dane testowe powinny być łatwo odtwarzalne i spójne. Dlatego dobrze jest mieć:
- Skrypty do tworzenia schematu bazy i wstawiania danych testowych.
- Możliwość szybkiego czyszczenia i resetowania bazy.
- Testowe migracje, które pozwalają kontrolować stan bazy podczas testów.
Monitorowanie i logowanie w testach
Rejestrowanie działań testów, błędów i wyników zapytań jest niezbędne do diagnozowania problemów. Dobrym rozwiązaniem jest:
- Zapisywanie logów do plików.
- Korzystanie z frameworków do raportowania testów.
- Zbieranie i analizowanie metryk wykonania testów.
Rozwiązywanie problemów i przydatne wskazówki
- Timeouty i asynchroniczność: Bazy danych mogą odpowiadać wolniej niż UI, zadbaj o odpowiednie timeouty i retry.
- Problemy z połączeniem: Sprawdź konfigurację sieci, firewalli i uprawnień.
- Problemy ze sterownikami: Używaj wersji kompatybilnych z wersją bazy.
- Bezpieczeństwo: Nie przechowuj danych uwierzytelniających w repozytorium — używaj zmiennych środowiskowych.
Podsumowanie
Integracja testów automatycznych z bazą danych MSSQL i PostgreSQL umożliwia tworzenie bardziej wiarygodnych i kompleksowych scenariuszy testowych. Playwright, w połączeniu z bibliotekami do komunikacji z bazą, daje duże możliwości testowania aplikacji na wielu poziomach — od UI, przez API, aż po bazę danych.
Dzięki temu możemy wcześnie wykrywać błędy, zapobiegać regresjom i dostarczać użytkownikom bardziej stabilne oprogramowanie. Pamiętajmy o dobrych praktykach, takich jak izolacja testów, automatyzacja przygotowania danych oraz monitorowanie testów — to klucz do skutecznego wdrożenia testów bazodanowych.
Na koniec warto podkreślić, że testowanie baz danych w Playwright nie wymaga ogromnego nakładu pracy — wystarczy dobra organizacja i znajomość narzędzi, aby osiągnąć znaczące korzyści jakościowe.
BIO
Michał Banaszyk – Tester automatyzujący oraz lider techniczny w obszarze testów automatycznych, związany głównie z branżą bankową. Specjalizuje się w projektowaniu i rozwoju testów automatycznych, przede wszystkim z wykorzystaniem frameworka Playwright.
Prywatnie pasjonat kinematografii, filozofii oraz sportu. Z dużym zainteresowaniem śledzi rozwój sztucznej inteligencji i jej praktyczne zastosowania w biznesie — zwłaszcza tam, gdzie może usprawniać procesy i zwiększać efektywność.
