6.4 KiB
titre : "Écrire des tests unitaires" description: "Présentation des tests unitaires" balises : ['Ingénierie']
Tests unitaires
- Tous les tests unitaires individuels sont indépendants les uns des autres. Nous n'utilisons aucun état partagé entre les tests.
- L’environnement de test comprend
sakila
exemple de base de données et toute modification apportée à celle-ci par un test est annulée avant l’exécution d’autres tests. - Lors de l'exécution de tests unitaires, il essaie de se connecter au serveur MySQL exécuté sur
localhost:3306
avec nom d'utilisateurroot
et mot de passepassword
(qui peut être configuré) et s'il n'est pas trouvé, il utiliserasqlite
comme solution de secours, donc aucune exigence d'un serveur SQL pour exécuter des tests.
Conditions préalables
- MySQL est préférable - mais les tests peuvent également s'appuyer sur SQLite
Installation
pnpm --filter=-nocodb install
# add a .env file
cp tests/unit/.env.sample tests/unit/.env
# open .env file
open tests/unit/.env
Configurez les variables suivantes
DB_HOST : hôte DB_PORT : port DB_USER : nom d'utilisateur DB_PASSWORD : mot de passe
Exécuter des tests
pnpm run test:unit
Structure des dossiers
Le dossier racine des tests unitaires estpackages/nocodb/tests/unit
rest
Le dossier contient toutes les suites de tests pour les API restantes.model
Le dossier contient toutes les suites de tests pour les modèles.factory
Le dossier contient toutes les fonctions d’aide pour créer des données de test.init
Le dossier contient des fonctions d'assistance pour configurer l'environnement de test.index.test.ts
est le fichier racine de la suite de tests qui importe toutes les suites de tests.TestDbMngr.ts
est une classe d'assistance pour gérer les bases de données de test (c'est-à-dire la création, la suppression, etc.).
Modèle d'usine
- Utilisez des usines pour créer/mettre à jour/supprimer des données. Aucune donnée ne doit être directement créée/mise à jour/supprimée dans le test.
- Lors de l'écriture d'une usine, assurez-vous qu'elle peut être utilisée avec le moins de paramètres possible et utilisez les valeurs par défaut pour les autres paramètres.
- Utilisez des paramètres nommés pour les usines.
createUser({ email, password})
- Utilisez un fichier par usine.
Procédure pas à pas pour l'écriture d'un test unitaire
Nous allons créer unTable
suite de tests à titre d'exemple.
Configurer le test
Nous allons configurerbeforeEach
qui est appelé avant l’exécution de chaque test. Nous utiliseronsinit
fonction denocodb/packages/nocodb/tests/unit/init/index.ts
, qui est une fonction d'assistance qui configure l'environnement de test (c'est-à-dire la réinitialisation de l'état, etc.).
init
fait les choses suivantes -
- Il initialise un
Noco
instance (réutilisée dans tous les tests). - Restaure
meta
etsakila
base de données à son état initial. - Crée l'utilisateur root.
- Retour
context
qui aauth token
pour l'utilisateur créé, instance de serveur de nœud (app
), etdbConfig
.
Nous utiliseronscreateProject
etcreateProject
usines pour créer un projet et une table.
let context;
beforeEach(async function () {
context = await init();
project = await createProject(context);
table = await createTable(context, project);
});
Cas de test
Nous utiliseronsit
fonction pour créer un scénario de test. Nous utiliseronssupertest
pour faire une requête au serveur. Nous utilisonsexpect
(chai
) pour affirmer la réponse.
it('Get table list', async function () {
const response = await request(context.app)
.get(`/api/v1/db/meta/projects/${project.id}/tables`)
.set('xc-auth', context.token)
.send({})
.expect(200);
expect(response.body.list).to.be.an('array').not.empty;
});
:::Info
We can also run individual test by using .only
dansdescribe
ouit
fonction et l’exécution de la commande test.
:::
it.only('Get table list', async () => {
Intégration de la nouvelle suite de tests
Nous créons un nouveau fichiertable.test.ts
danspackages/nocodb/tests/unit/rest/tests
annuaire.
import 'mocha';
import request from 'supertest';
import init from '../../init';
import { createTable, getAllTables } from '../../factory/table';
import { createProject } from '../../factory/project';
import { defaultColumns } from '../../factory/column';
import Model from '../../../../src/lib/models/Model';
import { expect } from 'chai';
function tableTest() {
let context;
let project;
let table;
beforeEach(async function () {
context = await init();
project = await createProject(context);
table = await createTable(context, project);
});
it('Get table list', async function () {
const response = await request(context.app)
.get(`/api/v1/db/meta/projects/${project.id}/tables`)
.set('xc-auth', context.token)
.send({})
.expect(200);
expect(response.body.list).to.be.an('array').not.empty;
});
}
export default function () {
describe('Table', tableTests);
}
Nous pouvons alors importer leTable
suite de tests pourRest
suite de tests danspackages/nocodb/tests/unit/rest/index.test.ts
déposer(Rest
la suite de tests est importée dans le fichier racine de la suite de tests qui estpackages/nocodb/tests/unit/index.test.ts
).
Base de données d'échantillons d'ensemencement (Sakila)
function tableTest() {
let context;
let sakilaProject: Project;
let customerTable: Model;
beforeEach(async function () {
context = await init();
/******* Start : Seeding sample database **********/
sakilaProject = await createSakilaProject(context);
/******* End : Seeding sample database **********/
customerTable = await getTable({project: sakilaProject, name: 'customer'})
});
it('Get table data list', async function () {
const response = await request(context.app)
.get(`/api/v1/db/data/noco/${sakilaProject.id}/${customerTable.id}`)
.set('xc-auth', context.token)
.send({})
.expect(200);
expect(response.body.list[0]['FirstName']).to.equal('MARY');
});
}