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