diff --git a/scripts/docs/fr/150.engineering/fr-040.unit-testing.md b/scripts/docs/fr/150.engineering/fr-040.unit-testing.md index e69de29bb2..5eaa98d9fd 100644 --- a/scripts/docs/fr/150.engineering/fr-040.unit-testing.md +++ b/scripts/docs/fr/150.engineering/fr-040.unit-testing.md @@ -0,0 +1,192 @@ +*** + +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’utilisateur`root`et mot de passe`password`(qui peut être configuré) et s’il n’est pas trouvé, il utilisera`sqlite`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 + +```bash +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 + +```bash +pnpm run test:unit +``` + +### Structure des dossiers + +Le dossier racine des tests unitaires est`packages/nocodb/tests/unit` + +* `rest`Le dossier contient toutes les suites de tests pour les API restantes. +* Le dossier `rest` contient toutes les suites de tests pour les API restantes. +* Le dossier `model` contient toutes les suites de tests pour les modèles. +* Le dossier `factory` 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 et 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. + ```ts + createUser({ email, password}) + ``` +* Utilisez un fichier par usine. + +### Procédure pas à pas pour l'écriture d'un test unitaire + +Nous allons créer un`Table` suite de tests à titre d’exemple. + +#### Configurer le test + +Nous allons configurer`beforeEach`qui est appelé avant l’exécution de chaque test. Nous utiliserons`init`fonction de`nocodb/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`et`sakila`base de données à son état initial. +* Crée l'utilisateur root. +* Retour`context`qui a`auth token`pour l'utilisateur créé, instance de serveur de nœud (`app`), et`dbConfig`. + +Nous utiliserons`createProject`et`createProject`usines pour créer un projet et une table. + +```typescript +let context; + +beforeEach(async function () { + context = await init(); + + project = await createProject(context); + table = await createTable(context, project); +}); +``` + +#### Cas de test + +Nous utiliserons`it`fonction pour créer un scénario de test. Nous utiliserons`supertest`pour faire une requête au serveur. Nous utilisons`expect`(`chai`) pour affirmer la réponse. + +```typescript +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`dans`describe`ou`it`fonction et l’exécution de la commande test. + +::: + +```typescript +it.only('Get table list', async () => { +``` + +#### Intégration de la nouvelle suite de tests + +Nous créons un nouveau fichier`table.test.ts`dans`packages/nocodb/tests/unit/rest/tests`annuaire. + +```typescript +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 le`Table`suite de tests pour`Rest`suite de tests dans`packages/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 est`packages/nocodb/tests/unit/index.test.ts`). + +### Base de données d'échantillons d'ensemencement (Sakila) + +```typescript + +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'); + }); +} +```