اختبار كود Node.js مع Mocha و Chai

المُقدّمة

تعد اختبارات وحدة الكتابة أمرًا يؤجله المهندسين المبتدئين والمحنكين على حد سواء عادةً لمراحل لاحقة من التطوير ، ومع ذلك - فهي مفتاح لتطوير البرامج المستقرة والقوية.

الفرضية الأساسية ل التطوير القائم على الاختبار (TDD) يكتب اختباراتك حتى قبل أن تبدأ في البرمجة. يعد هذا هدفًا رائعًا يجب السعي لتحقيقه ، ولكنه يتطلب الكثير من الانضباط والتخطيط عندما تحاول اتباع مبادئه! لتسهيل هذه العملية برمتها ، يمكنك اللجوء إلى أطر اختبار وتأكيد قوية وسهلة الاستخدام ، مثل موكا و تشاي.

في هذه المقالة ، سنبدأ بتقديمك إلى هاتين المكتبتين ثم نوضح لك كيفية استخدامهما معًا لإنشاء اختبارات وحدة قابلة للقراءة ووظيفية بسرعة.

تشاي

Chai هي مكتبة تأكيد توفر كلا من BDD (التنمية المدفوعة بالسلوك) و TDD (التطوير القائم على الاختبار) أنماط البرمجة لاختبار الكود ، والمقصود أن يتم إقرانها بمكتبة اختبار تتيح لك تنظيم الاختبارات. يتم إقرانها بشكل شائع مع الموكا.

لديها ثلاث واجهات برمجة تطبيقات رئيسية:

  • should
  • expect
  • assert

var.should.equal(var2)


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


assert.equal(var1, var2)

في هذه المقالة ، سنركز على أسلوب BDD باستخدام Chai's expect الواجهة ، على الرغم من استخدام واجهات / أنماط أخرى وفقًا للحدس الخاص بك ، فهو أمر جيد تمامًا. ال assert السطح البيني هو أطر تأكيد TDD الأكثر شيوعًا.

expect يستخدم واجهة برمجة تطبيقات لغة طبيعية جدًا لكتابة تأكيداتك ، مما يجعل اختباراتك أسهل في الكتابة والتحسين في وقت لاحق على الطريق. يتم ذلك عن طريق تجميع الحاصلين معًا لإنشاء التأكيد وتنفيذه ، مما يسهل ترجمة المتطلبات إلى تعليمات برمجية:

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

ملحوظة: يمكن العثور على قائمة كاملة بالطرق المتاحة هنا.

قد ترغب أيضًا في التحقق من قائمة المتاحة الإضافات لشاي. هذه تجعل اختبار الميزات الأكثر تعقيدًا أسهل بكثير.

أخذ تشاي- 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 - صف () و ()

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() الطريقة ، حددنا أ اسم الاختبارودعا #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 ، مع أفضل الممارسات ، والمعايير المقبولة في الصناعة ، وورقة الغش المضمنة. توقف عن أوامر Googling 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)

موكا هوكس - قبل () ، بعد () ، قبل كل () وبعد كل ()

من المسلم به أن معظم اختبارات الوحدة ليست بهذه البساطة. في كثير من الأحيان ستحتاج إلى موارد أخرى لإجراء اختباراتك ، مثل قاعدة بيانات ، أو بعض الموارد الخارجية الأخرى (أو وهمية / كعب منها). لإعداد هذا ، يمكننا استخدام واحد أو أكثر مما يلي موكا هوك أساليب:

  • 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


  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)

هذا مختلف قليلاً عن الأمثلة السابقة لأننا لم نكن بحاجة إلى إخبار موكا بمكان اختباراتنا. في هذا المثال ، يكون رمز الاختبار في الموقع المتوقع لـ /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() لم يتم تضمين الاختبارات في هذا التشغيل. إذا كنت تخطط وفقًا لأسماء الاختبار الخاصة بك ، فيمكن استخدام هذا الخيار لتشغيل أقسام محددة فقط من اختباراتك.

ومع ذلك ، فهذه ليست الخيارات المفيدة الوحيدة. فيما يلي بعض الخيارات الإضافية لـ Mocha التي قد ترغب في التحقق منها:

  • --invert: المقلوب -g و -f اعواد الثقاب
  • --recursive: تضمين الدلائل الفرعية
  • --harmony: تفعيل جميع ميزات التناغم في Node

ملاحظات: يمكنك التحقق من القائمة الكاملة للخيارات باستخدام ملف mocha -h الأمر ، أو في هذه الصفحة.

أين تتعلم المزيد؟ هناك ما هو أكثر بكثير من هذا الموضوع مما يمكننا تغطيته في مقال قصير ، لذلك إذا كنت تريد معرفة المزيد ، فإننا نوصي بمراجعة المسؤول موكا و تشاي كابل بيانات.

وفي الختام

ضع في اعتبارك أنه يمكن استخدام كل من Mocha و Chai لاختبار أي نوع من مشاريع Node تقريبًا ، سواء كانت مكتبة أو أداة سطر أوامر أو حتى موقع ويب. باستخدام الخيارات والإضافات المختلفة المتاحة لك ، يجب أن تكون قادرًا على تلبية احتياجات الاختبار الخاصة بك بسهولة تامة. تعد كل من هذه المكتبات مفيدة جدًا للتحقق من صحة التعليمات البرمجية الخاصة بك ويجب استخدامها في جميع مشاريع Node الخاصة بك تقريبًا.

نأمل أن يكون هذا بمثابة مقدمة مفيدة لـ Mocha و Chai. هناك الكثير لتعلمه أكثر مما قدمته هنا ، لذا تأكد من مراجعة المستندات لمزيد من المعلومات.

الطابع الزمني:

اكثر من ستاكابوز