多维表格
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

6.5 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 comprendsakilaexemple 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é surlocalhost:3306avec nom d’utilisateurrootet mot de passepassword(qui peut être configuré) et s’il n’est pas trouvé, il utiliserasqlitecomme 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

  • restLe 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.
  • initLe 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.
    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 configurerbeforeEachqui est appelé avant l’exécution de chaque test. Nous utiliseronsinitfonction 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.).

initfait les choses suivantes -

  • Il initialise unNocoinstance (réutilisée dans tous les tests).
  • Restauremetaetsakilabase de données à son état initial.
  • Crée l'utilisateur root.
  • Retourcontextqui aauth tokenpour l'utilisateur créé, instance de serveur de nœud (app), etdbConfig.

Nous utiliseronscreateProjectetcreateProjectusines 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 utiliseronsitfonction pour créer un scénario de test. Nous utiliseronssupertestpour 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 .onlydansdescribeouitfonction 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.tsdanspackages/nocodb/tests/unit/rest/testsannuaire.

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 leTablesuite de tests pourRestsuite de tests danspackages/nocodb/tests/unit/rest/index.test.tsdéposer(Restla 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');
  });
}