Aller au contenu principal
Version: 5.x

Tests de Bout en Bout

End-to-end tests are located in the src/e2e directory.

Build and Run E2E Tests​

Watch mode (for development)​

npm run e2e

This command builds and executes the e2e tests. If you modify a file and save it, the code is rebuilt and the tests are run again. This is particularly useful in development: you do not need to re-run the command every time you make code changes.

The process runs forever until you stop it.

Simple mode (for CI and Git hooks)​

If you need to build and run the tests only once, you can use these two commands:

npm run build:e2e # Build the e2e tests code (compile the typescript files and copy the templates)
npm run start:e2e # Execute the e2e tests from the built files

These commands are particularly useful when you want to integrate your tests into a CI pipeline or a Git hook.

The SuperTest library​

You can use the SuperTest library to write your e2e tests. It is installed by default.

Simple example

// 3p
import { createApp } from '@foal/core';
import * as request from 'supertest';
import { DataSource } from 'typeorm';

// App
import { AppController } from '../app/app.controller';
import { createDataSource } from '../db';

describe('The server', () => {

let app;
let dataSource: DataSource;

before(async () => {
app = await createApp(AppController);
dataSource = createDataSource();
await dataSource.initialize();
});

after(async () => {
if (dataSource) {
await dataSource.destroy();
}
});

it('should return a 200 status on GET / requests.', () => {
return request(app)
.get('/')
.expect(200);
});

});

Advanced example

// std
// The `assert` module provides a simple set of assertion tests.
import { ok } from 'assert';

// 3p
import { createApp } from '@foal/core';
import * as request from 'supertest';
import { DataSource } from 'typeorm';

// App
import { AppController } from '../app/app.controller';
import { User } from '../app/entities';
import { createDataSource } from '../db';

// Define a group of tests.
describe('The server', () => {

let dataSource: DataSource;
let app: any;

// Create the application and the connection to the database before running all the tests.
before(async () => {
app = await createApp(AppController);
dataSource = createDataSource();
await dataSource.initialize();
});

// Close the database connection after running all the tests whether they succeed or failed.
after(async () => {
if (dataSource) {
await dataSource.destroy();
}
});

// Define a nested group of tests.
describe('on GET /api/todos requests', () => {

it('should return a 401 status if the user did not signed in.', () => {
return request(app)
.get('/api/todos')
.expect(401);
});

it('should return a 200 status if the user did signed in.', async () => {
// Create a new user in the empty database.
const user = new User();
user.email = 'john@foalts.org';
await user.setPassword('john_password');
await user.save();

// Log the user in.
let cookie = '';
await request(app)
.post('/auth/login')
// Set the body of the request
.send({ email: 'john@foalts.org', password: 'john_password' })
// The response should have the status 302 (redirection)
.expect(302)
.then(data => {
// The response should set the authentication cookie for the next requests.
ok(Array.isArray(data.header['set-cookie']));
// Save the cookie to be able to use it in further requests.
cookie = data.header['set-cookie'][0];
});

// Test the /api/todos endpoint when the user has logged in.
return request(app)
.get('/api/todos')
// Send the authentication cookie.
.set('Cookie', cookie)
.expect(200);
});

});

});