בדיקת קוד 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 ממשק, אם כי שימוש בממשקים/סגנונות אחרים לפי האינטואיציה שלך הוא בסדר גמור. ה assert ממשק הוא מסגרות הצהרת TDD הנפוצות ביותר.

expect משתמש ב-API בשפה טבעית מאוד כדי לכתוב את הטענות שלך, מה שיקל על הכתיבה והשיפור של המבחנים שלך בהמשך הדרך. זה נעשה על ידי שרשרת קבלנים כדי ליצור ולבצע את הטענה, מה שמקל על תרגום הדרישות לקוד:

let user = {name: 'Scott'};


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

הערה: ראה איך אתה יכול פחות או יותר לקרוא את הקביעה בשפה טבעית ולהבין מה קורה? זה אחד היתרונות העיקריים של שימוש בספריית הצהרות כמו חי!

עוד כמה דוגמאות לגטרים אלה:

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

הערה: ניתן למצוא רשימה מלאה של השיטות הזמינות כאן.

אולי תרצה גם לבדוק את רשימת הזמינים תוספים עבור חי. אלה מקלים בהרבה על בדיקת תכונות מורכבות יותר.

לקחת chai-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 היא מסגרת בדיקה עבור Node המעניקה לך את הגמישות להריץ קוד אסינכרוני (או סינכרוני) באופן סדרתי. חריגים שלא נתפסו מוצגים לצד מקרה המבחן שבו הוא הושלך, מה שמקל על זיהוי בדיוק מה נכשל ומדוע.

מומלץ להתקין את Mocha ברחבי העולם:

$ npm install mocha -g

תרצה שזו תהיה התקנה גלובלית מאז mocha הפקודה משמשת להפעלת הבדיקות עבור הפרויקט בספרייה המקומית שלך.

מה עושה קטע הקוד הזה?

it() צריך להחזיר X. it() מגדיר מקרי בדיקה, ומוקה יריץ כל אחד מהם it() כמבחן יחידה. כדי לארגן בדיקות יחידות מרובות, אנחנו יכולים 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);
        });
    });
});

ב describe() שיטה, הגדרנו א שם המבחן, הנקרא #abs(). אתה יכול להריץ מבחנים בנפרד גם לפי שמם - זה יפורט בהמשך.

הערה: עם מבחני מוקה, אתה לא צריך require() כל אחת משיטות מוקה. שיטות אלו מסופקות באופן גלובלי כאשר מופעלות עם ה mocha פקודה.

על מנת להפעיל את הבדיקות הללו, שמור את הקובץ שלך והשתמש ב- mocha פקודה:

$ mocha .

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


  1 passing (9ms)

הפלט הוא פירוט של הבדיקות שרצו ותוצאותיהם. שימו לב כיצד קינן describe() שיחות עוברות לפלט התוצאות. כדאי לכלול את כל הבדיקות עבור שיטה או תכונה נתונה.

שיטות אלו הן הבסיס למסגרת בדיקת מוקה. השתמש בהם כדי לחבר ולארגן את המבחנים שלך איך שתרצה. נראה דוגמה אחת לכך בסעיף הבא.

כתיבת מבחנים עם מוקה וחי

הדרך המומלצת לארגן את המבחנים שלך בתוך הפרויקט שלך היא לשים את כולם בעצמם /test מַדרִיך. כברירת מחדל, Mocha בודק בדיקות יחידה באמצעות הגלובסים ./test/*.js ו ./test/*.coffee. משם, הוא יטען ויבצע כל קובץ שקורא ל- describe() שִׁיטָה.

עיין במדריך המעשי והמעשי שלנו ללימוד Git, עם שיטות עבודה מומלצות, סטנדרטים מקובלים בתעשייה ודף רמאות כלול. תפסיק לגוגל פקודות Git ולמעשה ללמוד זה!

מקובל להוסיף את קבצי הבדיקה .test.js עבור קבצי המקור המכילים מבחני מוקה:

├── 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.

עם זאת, ישנן כמה אפשרויות מועילות שאולי תרצה להשתמש בהן בעת ​​הפעלת בדיקות. אם חלק מהמבחנים שלך נכשלים, למשל, אתה כנראה לא רוצה להפעיל את כל החבילה בכל פעם שאתה מבצע שינוי. עבור פרויקטים מסוימים, חבילת הבדיקות המלאה עשויה להימשך מספר דקות. זה הרבה זמן מבוזבז אם אתה באמת צריך רק בדיקה אחת.

למקרים כאלה, כדאי תגיד למוקה אילו מבחנים לרוץ. ניתן לעשות זאת באמצעות -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 פקודה, או על דף זה.

היכן ניתן ללמוד עוד? יש הרבה יותר בנושא הזה ממה שאנחנו יכולים לכסות במאמר קצר, אז אם אתה רוצה ללמוד יותר אז אנחנו ממליצים לבדוק את הרשמי מוקה ו חי תיעוד.

סיכום

זכור שניתן להשתמש גם במוקה וגם בצ'אי לבדיקת כמעט כל סוג של פרויקט Node, בין אם זה ספרייה, כלי שורת פקודה או אפילו אתר אינטרנט. תוך ניצול האפשרויות והתוספים השונים העומדים לרשותך, אתה אמור להיות מסוגל לספק את צורכי הבדיקה שלך די בקלות. כל אחת מהספריות הללו שימושית מאוד לאימות הקוד שלך ויש להשתמש בה כמעט בכל פרויקטי ה-Node שלך.

אני מקווה שזה שימש כמבוא שימושי למוקה וחי. יש הרבה יותר מה ללמוד ממה שהצגתי כאן, אז הקפד לבדוק את המסמכים למידע נוסף.

בול זמן:

עוד מ Stackabuse