Testiranje kode Node.js z Mocha in Chai

Predstavitev

Pisanje testov enote je nekaj, kar tako začetniki kot izkušeni inženirji običajno odložijo za poznejše faze razvoja, vendar so ključni za stabilen in robusten razvoj programske opreme.

Osnovna premisa za testno usmerjen razvoj (TDD) piše vaše teste, še preden začnete kodirati. To je odličen cilj, h kateremu si morate prizadevati, vendar je potrebno veliko discipline in načrtovanja, ko poskušate slediti njegovim načelom! Da bi bil ta celoten postopek veliko lažji, se lahko zatečete k enostavnim in zmogljivim testiranjem in okvirom trditev, kot je npr. mocha in Chai.

V tem članku vam bomo najprej predstavili ti dve knjižnici in vam nato pokazali, kako ju uporabite skupaj za hitro ustvarjanje berljivih in funkcionalnih testov enot.

Chai

Chai je knjižnica trditev, ki zagotavlja tako BDD (razvoj, ki ga vodi vedenje) in TDD (testno usmerjen razvoj) stilov programiranja za testiranje kode in naj bi bil združen s knjižnico za testiranje, ki vam omogoča organiziranje testov. Zelo pogosto se kombinira z mokko.

Ima tri glavne API-je:

  • should
  • expect
  • assert

var.should.equal(var2)


expect.var.to.be.equal(var2)


assert.equal(var1, var2)

V tem članku se bomo osredotočali na slog BDD z uporabo Chai's expect vmesnik, čeprav je uporaba drugih vmesnikov/slogov po lastni intuiciji povsem v redu. The assert vmesnik je najbolj podoben običajnim okvirom trditev TDD.

expect uporablja zelo naraven jezikovni API za pisanje vaših trditev, kar bo olajšalo pisanje vaših testov in izboljšanje kasneje. To se izvede z verižnim združevanjem pridobivalnikov za ustvarjanje in izvajanje trditve, kar olajša prevajanje zahtev v kodo:

let user = {name: 'Scott'};


expect(user).to.have.property('name');

Opomba: Vidite, kako lahko precej preberete trditev v naravnem jeziku in razumete, kaj se dogaja? To je ena od glavnih prednosti uporabe knjižnice trditev, kot je Chai!

Še nekaj primerov teh pridobivalnikov je:

  • to
  • be
  • is
  • and
  • has
  • have

Kar nekaj teh pridobivalnikov je mogoče verižiti skupaj in uporabiti z metodami trditve, kot je true, ok, existin empty ustvariti nekaj zapletenih trditev v samo eni vrstici:

"use strict";

const expect = require('chai').expect;


expect({}).to.exist;
expect(26).to.equal(26);
expect(false).to.be.false;
expect('hello').to.be.string;


expect([1, 2, 3]).to.not.be.empty;


expect([1, 2, 3]).to.have.length.of.at.least(3);

Opomba: Najdete lahko celoten seznam razpoložljivih metod tukaj.

Morda boste želeli preveriti tudi seznam razpoložljivih plugins za Chai. Ti omogočajo veliko lažje testiranje kompleksnejših funkcij.

Bodite chai-http na primer, ki je vtičnik, ki vam pomaga preizkusiti strežniške poti:

"use strict";

const chai = require('chai');
const chaiHttp = require('chai-http');

chai.use(chaiHttp);

chai.request(app)
    .put('/api/auth')
    .send({username: '[email protected]', password: 'abc123'})
    .end(function(err, res) {
        expect(err).to.be.null;
        expect(res).to.have.status(200);
    });

Organiziranje testnih primerov z Mokko – describe() in it()

Mocha je ogrodje za testiranje za Node, ki vam omogoča serijsko izvajanje asinhrone (ali sinhrone) kode. Vse neulovljene izjeme so prikazane poleg testnega primera, v katerem so bile vržene, kar olajša prepoznavanje, kaj natančno ni uspelo in zakaj.

Priporočljivo je, da namestite Mocha globalno:

$ npm install mocha -g

Želeli boste, da gre za globalno namestitev od mocha ukaz se uporablja za izvajanje testov za projekt v vašem lokalnem imeniku.

Kaj počne ta del kode?

it() mora vrniti X. it() definira testne primere in Mocha bo izvajal vsakega it() kot test enote. Za organizacijo več enotnih testov lahko describe() skupno funkcionalnost in s tem strukturo testov Mocha.

To je verjetno najbolje opisati s konkretnim primerom:

"use strict";
const expect = require('chai').expect;

describe('Math', function() {
    describe('#abs()', function() {
        it('should return positive value of given negative number', function() {
            expect(Math.abs(-5)).to.be.equal(5);
        });
    });
});

v describe() metodo smo definirali a ime testa, klical #abs(). Preizkuse lahko izvajate tudi posamezno po njihovih imenih – to bo obravnavano kasneje.

Opomba: Pri testih Mocha vam tega ni treba require() katero koli od metod Mocha. Te metode so na voljo globalno, če jih izvajate z mocha ukaz.

Če želite zagnati te teste, shranite datoteko in uporabite mocha ukaz:

$ mocha .

  Math
    #abs()
      ✓ should return positive value of given number 


  1 passing (9ms)

Rezultat je razčlenitev izvedenih testov in njihovih rezultatov. Opazite, kako ugnezdeni describe() klici prenesejo na izpis rezultatov. Koristno je imeti vse teste za določeno metodo ali funkcijo ugnezdene skupaj.

Te metode so osnova za testni okvir Mocha. Uporabite jih za sestavljanje in organiziranje testov, kakor želite. En primer tega bomo videli v naslednjem razdelku.

Pisanje testov z mokko in čajem

Priporočen način za organizacijo testov znotraj vašega projekta je, da jih vse postavite v svoje /test imenik. Mocha privzeto preveri teste enot z uporabo globusov ./test/*.js in ./test/*.coffee. Od tam bo naložil in izvedel katero koli datoteko, ki kliče describe() metoda.

Oglejte si naš praktični, praktični vodnik za učenje Gita z najboljšimi praksami, standardi, sprejetimi v panogi, in priloženo goljufijo. Nehajte Googlati ukaze Git in pravzaprav naučiti it!

Običajno je testnim datotekam dodati pripono .test.js za izvorne datoteke, ki vsebujejo teste Mocha:

├── package.json
├── lib
│   ├── db.js
│   ├── models.js
│   └── util.js
└── test
    ├── db.test.js
    ├── models.test.js
    ├── util.test.js
    └── util.js

util.js v test imenik ne bi vseboval nobenih testov enote, samo pomožne funkcije za pomoč pri testiranju.

Opombe: Uporabite lahko katero koli strukturo, ki se vam zdi smiselna, testi enot se samodejno izberejo.

Ko gre za dejansko pisanje testov, jih pomaga organizirati z uporabo describe() metode. Lahko jih organizirate po lastnostih, funkcijah, datotekah ali kateri koli drugi poljubni ravni. Na primer, testna datoteka, organizirana za opis delovanja na ravni funkcije, je videti takole:

"use strict";

const expect = require('chai').expect;

describe('Math', function() {
    describe('#abs()', function() {
        it('should return positive value of given negative number', function() {
            expect(Math.abs(-5)).to.be.equal(5);
        });

        it('should return positive value of given positive number', function() {
            expect(Math.abs(3)).to.be.equal(3);
        });

        it('should return 0 given 0', function() {
            expect(Math.abs(0)).to.be.equal(0);
        });
    });
});

Izvajanje testov bi nato dalo izhod:

$ mocha .

  Math
    #abs()
      ✓ should return positive value of given negative number 
      ✓ should return positive value of given positive number 
      ✓ should return 0 given 0 


  3 passing (11ms)

Če še bolj razširite, boste morda celo imeli teste za več metod v eni datoteki. V tem primeru so metode razvrščene po Math predmet:

"use strict";

const expect = require('chai').expect;

describe('Math', function() {
    describe('#abs()', function() {
        it('should return positive value of given negative number', function() {
            expect(Math.abs(-5)).to.be.equal(5);
        });

        it('should return positive value of given positive number', function() {
            expect(Math.abs(3)).to.be.equal(3);
        });

        it('should return 0 given 0', function() {
            expect(Math.abs(0)).to.be.equal(0);
        });
    });

    describe('#sqrt()', function() {
        it('should return the square root of a given positive number', function() {
            expect(Math.sqrt(25)).to.be.equal(5);
        });

        it('should return NaN for a given negative number', function() {
            expect(Math.sqrt(-9)).to.be.NaN;
        });

        it('should return 0 given 0', function() {
            expect(Math.sqrt(0)).to.be.equal(0);
        });
    });
});

Posledica tega je:

$ mocha .

  Math
    #abs()
      ✓ should return positive value of given negative number 
      ✓ should return positive value of given positive number 
      ✓ should return 0 given 0 
    #sqrt()
      ✓ should return the square root of a given positive number 
      ✓ should return NaN for a given negative number 
      ✓ should return 0 given 0 


  6 passing (10ms)

Mocha Hooks – before(), after(), beforeEach() in afterEach()

Res je, da večina testov enot ni tako preprosta. Velikokrat boste verjetno potrebovali druge vire za izvajanje svojih testov, na primer bazo podatkov ali kak drug zunanji vir (ali lažni del). Da bi to nastavili, lahko uporabimo enega ali več od naslednjega Mocha kavelj metode:

  • before(): Zažene se pred vsemi testi v danem bloku
  • beforeEach(): Zažene se pred vsakim testom v danem bloku
  • after(): Zažene se po vseh testih v danem bloku
  • afterEach(): Zažene se po vsakem testu v danem bloku

Te kljuke so popolno mesto za nastavitev in razstavljanje, potrebno za vaše teste. Eden od običajnih primerov uporabe je vzpostavitev povezave z vašo zbirko podatkov pred izvajanjem testov:

"use strict";

const expect = require('chai').expect;
let User = require('../models').User;

describe('Users', function() {

    let database = null;

    before(function(done) {
        
    });

    afterEach(function(done) {
        
    });

    describe('#save()', function() {
        it('should save User data to database', function(done) {
            
        });
    });

    describe('#load()', function() {
        it('should load User data from database', function(done) {
            
        });
    });
});

pred kaj izvedenih testov, funkcija poslana našemu before() zažene se metoda (in se zažene samo enkrat v vseh preskusih), ki vzpostavi povezavo z bazo podatkov. Ko je to opravljeno, se zaženejo naši testni paketi.

Ker ne želimo, da bi podatki iz enega testnega paketa vplivali na naše druge teste, moramo počistiti podatke iz naše zbirke podatkov po vsakem zagonu. To je tisto afterEach() je za. To kljuko uporabimo za brisanje vseh podatkov baze podatkov vsak testni primer je zagnan, tako da lahko začnemo s čistim listom za naslednje teste.

Izvajanje testov Mocha

V večini primerov je ta del precej preprost. Ob predpostavki, da ste že namestili Mocha in se pomaknili do imenika projektov, mora večina projektov uporabiti le mocha ukaz brez argumentov za izvajanje njihovih testov:

$ mocha


  Math
    #abs()
      ✓ should return positive value of given negative number 
      ✓ should return positive value of given positive number 
      ✓ should return 0 given 0 
    #sqrt()
      ✓ should return the square root of a given positive number 
      ✓ should return NaN for a given negative number 
      ✓ should return 0 given 0 


  6 passing (10ms)

To se nekoliko razlikuje od naših prejšnjih primerov, saj nam Mocha ni bilo treba povedati, kje so naši testi. V tem primeru je testna koda na pričakovani lokaciji /test.

Obstaja pa nekaj koristnih možnosti, ki jih boste morda želeli uporabiti pri izvajanju testov. Če so na primer nekateri vaši testi neuspešni, verjetno ne želite zagnati celotnega paketa vsakič, ko naredite spremembo. Pri nekaterih projektih lahko traja celoten testni paket nekaj minut. To je veliko izgubljenega časa, če res potrebujete samo en test.

Za takšne primere bi morali povejte Mochi, katere teste naj izvede. To je mogoče storiti z uporabo -g or -f opcije.

Za izvajanje posameznih testov lahko priskrbite -g zastavico in dodajte skupni vzorec med testi, ki jih želite izvesti. Na primer, če želite zagnati #sqrt() testi:

$ mocha -g sqrt

  Math
    #sqrt()
      ✓ should return the square root of a given positive number 
      ✓ should return NaN for a given negative number 
      ✓ should return 0 given 0 


  3 passing (10ms)

Opazite, da #abs() testi niso bili vključeni v to izvedbo. Če načrtujete ustrezno z imeni svojih testov, lahko to možnost uporabite samo za izvajanje določenih delov vaših testov.

Vendar to niso edine uporabne možnosti. Tukaj je še nekaj možnosti za mokko, ki bi jih morda želeli preveriti:

  • --invert: Obrne -g in -f tekme
  • --recursive: Vključi podimenike
  • --harmony: Omogoči vse funkcije harmonije v Node

Opombe: Celoten seznam možnosti si lahko ogledate z uporabo mocha -h ukaz ali vklop stran.

Kje izvedeti več? Na to temo je veliko več, kot bi lahko zajeli v kratkem članku, zato vam priporočamo, da si ogledate uradni članek, če želite izvedeti več. mocha in Chai dokumentacija.

zaključek

Ne pozabite, da se tako Mocha kot Chai lahko uporabljata za testiranje skoraj vseh vrst projektov Node, ne glede na to, ali gre za knjižnico, orodje ukazne vrstice ali celo spletno mesto. Z uporabo različnih možnosti in vtičnikov, ki so vam na voljo, bi morali biti sposobni precej enostavno zadovoljiti svoje potrebe po testiranju. Vsaka od teh knjižnic je zelo uporabna za preverjanje vaše kode in bi jo bilo treba uporabiti v skoraj vseh vaših projektih Node.

Upajmo, da je to služilo kot koristen uvod v Mokko in Čaj. Naučiti se je treba veliko več od tega, kar sem predstavil tukaj, zato si za več informacij oglejte dokumente.

Časovni žig:

Več od Stackabuse