Тестування коду Node.js за допомогою Mocha та Chai

Вступ

Написання модульних тестів — це те, що як початківці, так і досвідчені інженери зазвичай відкладають на наступні етапи розробки, однак вони є ключовими для стабільної та надійної розробки програмного забезпечення.

Основна посилка Росії тестова розробка (TDD) пише ваші тести ще до того, як ви почнете кодувати. Це чудова мета, до якої варто прагнути, але для того, щоб слідувати її принципам, потрібно багато дисципліни та планування! Щоб значно полегшити весь цей процес, ви можете вдатися до простих у використанні та потужних систем тестування та тверджень, таких як кава мокко та Чай.

У цій статті ми почнемо з того, що познайомимо вас із цими двома бібліотеками, а потім покажемо, як використовувати їх разом для швидкого створення читабельних і функціональних модульних тестів.

Чай

Chai — це бібліотека тверджень, яка надає як BDD (розвиток, керований поведінкою) та TDD (розробка, керована тестуванням) стилі програмування для коду тестування, і призначений для поєднання з бібліотекою тестування, яка дозволяє організовувати тести. Його дуже часто поєднують з мокко.

Він має три основні API:

  • should
  • expect
  • assert

var.should.equal(var2)


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


assert.equal(var1, var2)

У цій статті ми зосередимося на стилі BDD із використанням Chai’s expect інтерфейсу, хоча використання інших інтерфейсів/стилів відповідно до вашої власної інтуїції цілком допустимо. The assert інтерфейс є найбільш схожим на загальну структуру тверджень TDD.

expect використовує дуже природну мову API для написання ваших тверджень, що полегшить написання ваших тестів і покращить їх пізніше. Це робиться шляхом об’єднання геттерів для створення та виконання твердження, що полегшує переклад вимог у код:

let user = {name: 'Scott'};


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

Примітка: Бачите, як ви можете майже прочитати твердження природною мовою і зрозуміти, що відбувається? Це одна з головних переваг використання такої бібліотеки тверджень, як Chai!

Ще кілька прикладів таких геттерів:

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

Досить багато з цих геттерів можна об’єднати разом і використовувати з такими методами твердження, як true, ok, exist та empty щоб створити кілька складних тверджень лише в одному рядку:

"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);

Примітка: Повний список доступних методів можна знайти тут.

Ви також можете переглянути список доступних plugins для чаю. Це значно полегшує тестування складніших функцій.

Приймати чай-http наприклад, це плагін, який допомагає тестувати маршрути сервера:

"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);
    });

Організація тестових випадків за допомогою Mocha – describe() і it()

Mocha — це платформа тестування для Node, яка дає вам можливість запускати асинхронний (або синхронний) код послідовно. Будь-які неперехоплені винятки відображаються поруч із тестовим прикладом, у якому вони були створені, що дозволяє легко визначити, що саме не вдалося та чому.

Рекомендується встановити Mocha глобально:

$ npm install mocha -g

Ви захочете, щоб це було глобальне встановлення, оскільки mocha Команда використовується для запуску тестів для проекту у вашому локальному каталозі.

Що робить цей фрагмент коду?

it() має повернути X. it() визначає тестові випадки, і Mocha запускатиме кожен it() як модульний тест. Ми можемо організувати кілька модульних тестів describe() загальну функціональність і, отже, структуру тестів Mocha.

Ймовірно, це найкраще описати на конкретному прикладі:

"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);
        });
    });
});

У describe() метод, ми визначили a назва тесту, Називаний #abs(). Ви також можете окремо запускати тести за їхніми іменами – це буде розглянуто пізніше.

Примітка: З тестами Mocha вам не потрібно require() будь-який із методів Мокко. Ці методи надаються глобально під час запуску з mocha команда

Щоб запустити ці тести, збережіть файл і використовуйте mocha команда:

$ mocha .

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


  1 passing (9ms)

Результатом є розбивка виконаних тестів і їх результати. Зверніть увагу, як вкладені describe() виклики переносяться на вихід результатів. Корисно мати всі тести для даного методу чи функції вкладеними разом.

Ці методи є основою для системи тестування Mocha. Використовуйте їх, щоб складати та впорядковувати свої тести, як вам подобається. Ми побачимо один приклад цього в наступному розділі.

Написання контрольних робіт з мокко та чаєм

Рекомендований спосіб організації тестів у вашому проекті – розмістити їх усі окремо /test каталог. За замовчуванням Mocha перевіряє модульні тести за допомогою глобусів ./test/*.js та ./test/*.coffee. Звідти він завантажить і виконає будь-який файл, який викликає describe() метод.

Ознайомтеся з нашим практичним практичним посібником із вивчення Git з передовими методами, прийнятими в галузі стандартами та включеною шпаргалкою. Припиніть гуглити команди Git і фактично вчитися це!

До тестових файлів зазвичай додають суфікс .test.js для вихідних файлів, які містять тести Mocha:

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

util.js в test каталог не міститиме модульних тестів, лише службові функції, які допоможуть у тестуванні.

примітки: Ви можете використовувати будь-яку структуру, яка для вас є зрозумілою, модульні тести підбираються автоматично.

Коли справа доходить до фактичного написання тестів, це допомагає організувати їх за допомогою describe() методи. Ви можете впорядкувати їх за функціями, функціями, файлами чи будь-якими іншими довільними рівнями. Наприклад, тестовий файл, організований для опису роботи на функціональному рівні, виглядає так:

"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);
        });
    });
});

Запуск тестів дасть вам результат:

$ 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)

Розширюючи ще далі, ви навіть можете мати тести для кількох методів в одному файлі. У цьому випадку методи згруповані за Math об’єкт:

"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);
        });
    });
});

В результаті чого:

$ 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() і afterEach()

Слід визнати, що більшість модульних тестів не такі прості. Багато разів вам, ймовірно, знадобляться інші ресурси для виконання ваших тестів, як-от база даних або будь-який інший зовнішній ресурс (або їх макет/заглушка). Щоб налаштувати це, ми можемо скористатися одним або декількома з наведених нижче Гачок мокко методи:

  • before(): запускається перед усіма тестами в даному блоці
  • beforeEach(): запускається перед кожним тестом у заданому блоці
  • after(): запускається після всіх тестів у заданому блоці
  • afterEach(): запускається після кожного тесту в заданому блоці

Ці гачки є ідеальним місцем для виконання робіт з налаштування та демонтажу, необхідних для ваших тестів. Одним із типових випадків використання є встановлення з’єднання з базою даних перед виконанням тестів:

"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) {
            
        });
    });
});

Перед тим як будь-який тестів запущено, функція надіслана до нашого before() запускається метод (і запускається лише один раз протягом тестів), що встановлює з’єднання з базою даних. Після цього запускаються наші набори тестів.

Оскільки ми не хочемо, щоб дані з одного набору тестів впливали на інші наші тести, нам потрібно очистити дані з нашої бази даних після запуску кожного набору. Це те, що afterEach() для. Ми використовуємо цей хук, щоб очистити всі дані бази даних після кожен тестовий приклад запущено, тому ми можемо почати з чистого аркуша для наступних тестів.

Проведення тестів Mocha

У більшості випадків ця частина досить проста. Якщо припустити, що ви вже встановили Mocha та перейшли до каталогу проекту, більшості проектів просто потрібно використовувати mocha команда без аргументів для запуску своїх тестів:

$ 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, де знаходяться наші тести. У цьому прикладі тестовий код знаходиться в очікуваному місці /test.

Однак є деякі корисні параметри, які ви можете використовувати під час виконання тестів. Наприклад, якщо деякі з ваших тестів виявляються невдалими, можливо, ви не захочете запускати весь пакет щоразу, коли вносите зміни. Для деяких проектів повний набір тестів може тривати кілька хвилин. Це багато втраченого часу, якщо вам справді потрібно виконати лише один тест.

Для таких випадків ви повинні скажіть Mocha, які тести проводити. Це можна зробити за допомогою -g or -f Варіанти.

Щоб запустити окремі тести, ви можете надати -g прапорець і додайте загальний шаблон між тестами, які ви хочете запустити. Наприклад, якщо ви хочете запустити #sqrt() тести:

$ 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)

Зверніть увагу, що #abs() тести не були включені в цей запуск. Якщо ви плануєте відповідні назви своїх тестів, цей параметр можна використовувати лише для виконання певних розділів ваших тестів.

Однак це не єдині корисні варіанти. Ось ще кілька варіантів мокко, які ви можете перевірити:

  • --invert: Інвертує -g та -f сірники
  • --recursive: включити підкаталоги
  • --harmony: увімкніть усі функції гармонії у Node

примітки: ви можете переглянути повний список опцій, використовуючи mocha -h або увімк На цій сторінці.

Де дізнатися більше? Ця тема набагато більше, ніж ми можемо висвітлити в короткій статті, тому, якщо ви хочете дізнатися більше, ми рекомендуємо перевірити офіційний кава мокко та Чай документація.

Висновок

Майте на увазі, що як Mocha, так і Chai можна використовувати для тестування практично будь-якого типу проекту Node, будь то бібліотека, інструмент командного рядка або навіть веб-сайт. Використовуючи різноманітні опції та плагіни, доступні вам, ви зможете досить легко задовольнити свої потреби в тестуванні. Кожна з цих бібліотек дуже корисна для перевірки вашого коду, і її слід використовувати майже в усіх ваших проектах Node.

Сподіваюся, це послужило корисним вступом до мокко та чаю. Можна дізнатися набагато більше, ніж те, що я тут представив, тому обов’язково перегляньте документи, щоб отримати більше інформації.

Часова мітка:

Більше від Stackabuse