Usability Test Post-Its
Adrian, Kiya | 21.03.2024

Clean Database Tests mit Jest

Webentwicklung > Clean Database Tests mit Jest

Wenn Sie Backend-Tests parallel ausführen möchten, stoßen Sie schnell auf das Problem, dass mehrere Tests gleichzeitig auf dieselben Daten zugreifen möchten. Dies kann je nach Textsequenz zu fluktuierenden Tests führen.

Um dieses Problem zu lösen, gibt es verschiedene Ansätze, beispielsweise wird vor jedem Test eine Transaktion eingerichtet, die nach jedem Durchlauf wieder zurückgerollt wird. Dies ist jedoch schwierig mit den JS ORMs umzusetzen, da die beliebten Frameworks wie Prisma oder Typorm auf Callbacks angewiesen sind.

Unser Ansatz besteht darin, vor jedem Test ein neues Schema bereitzustellen und es nach jedem Test wieder abzubauen.

Um dies zu tun, wird eine benutzerdefinierte Jest-Umgebung zu jest.config.ts hinzugefügt: testEnvironment: './jest-custom-env.js',.

Und dies ist die jest-custom-env.js:

1const NodeEnvironment = require('jest-environment-node').TestEnvironment;
2import { Client } from 'pg';
3
4class CustomEnvironment extends NodeEnvironment {
5    constructor(config, context) {
6        const randomId = Math.floor(Math.random() * 100_000_000);
7        process.env.DB_NAME = `test_${randomId}`;
8        super(config, context);
9    }
10
11    async setup() {
12        console.time(`Setup Test Database ${process.env.DB_NAME}`);
13        await super.setup();
14        const db = this.getClient();
15        await db.connect();
16        await db.query(`CREATE DATABASE ${process.env.DB_NAME}`);
17        await db.end();
18        console.timeEnd(`Setup Test Database ${process.env.DB_NAME}`);
19    }
20
21    async teardown() {
22        console.time(`Teardown Test Database ${process.env.DB_NAME}`);
23        const db = this.getClient();
24        await db.connect();
25        await db.query(
26            `SELECT PG_TERMINATE_BACKEND(pg_stat_activity.pid)
27                        FROM pg_stat_activity
28                        WHERE pg_stat_activity.datname = $1::text
29                          AND pid <> PG_BACKEND_PID();
30        `,
31            [process.env.DB_NAME],
32        );
33        await db.query(`DROP DATABASE IF EXISTS ${process.env.DB_NAME}`);
34        await db.end();
35        await super.teardown();
36    }
37
38    getClient() {
39        return new Client({
40            host: process.env.DB_HOST,
41            port: process.env.DB_PORT,
42            user: process.env.DB_USER,
43            password: process.env.DB_PASSWORD,
44            database: 'postgres',
45            ssl: false,
46        });
47    }
48}
49
50module.exports = CustomEnvironment;

Verwenden Sie process.env.DB_NAME in der Verbindung, und jeder Test verbindet sich mit dem korrekten Schema.

Der Nachteil ist, dass Sie die Daten in der Datenbank nach dem Test nicht mehr nachschlagen können.

Dieses Konzept kann auf andere Datenbanken angepasst werden.

#keywords: Softwareentwicklung, Softwareentwicklung, Softwareentwicklung

Inhalt
  • Wie kann man Backend-Tests parallelisieren ohne Datenkonflikte?
  • Wie kann man eine individuelle Jest-Umgebung erstellen, um Datenbanktests zu automatisieren?
  • Welche Vorteile und Nachteile hat diese Methode?
  • Kann diese Methode auf andere Datenbanken angewendet werden?
Adrian Görisch
Adrian (Softwareentwickler)

... arbeitet als zuverlässiger Full-Stack-Softwareentwickler, aktuell hauptsächlich im Backend mit NestJS, ECMAScript und diversen Datenbanktechnologien. Besonders großen Wert legt er auf ordentliche... mehr anzeigen

Github
Kiya

... ist unsere engagierte und leidenschaftliche Künstliche Intelligenz und Expertin für Softwareentwicklung. Mit einem unermüdlichen Interesse für technologische Innovationen bringt sie Enthusiasmus u... mehr anzeigen

Standort Hannover

newcubator GmbH
Bödekerstraße 22
30161 Hannover

Standort Dortmund

newcubator GmbH
Westenhellweg 85-89
44137 Dortmund