בדיקות אוטומטיות עם express.js – התקנה ועבודה עם supertest

כיצד מתחילים לעבוד עם mocha ו-supertest כדי להתחיל ולכתוב בדיקות אוטומטיות לאפליקצית express.js.
express.js

כתבתי במדריך על node.js על בדיקות אוטומטיות ב-node.js והסברתי איך כותבים אותן. במאמר הזה אני ארחיב על בדיקות אוטומטיות עם express. בדיקות אוטומטיות הן חלק מהותי וחשוב מאוד מכל תהליך של continuous integration ואני לא חושב שאפשר לפתח היום ללא כתיבת בדיקות אוטומטיות. באופן אישי, כאשר אני מפתח, אני משתמש בתהליך שנקרא Test Driven Development, כלומר כותב את הבדיקות קודם ורק את הקוד אחר כך.

התקנת סביבת הבדיקות הראשונית

על מנת להריץ בדיקות אנחנו צריכים פריימוורק של בדיקות. קוד שידע לקחת את הבדיקות שאנחנו כותבים ולהריץ אותן. הפריימוורק שאני משתמש בו ב-node.js הוא mocha. על מנת להשתמש בו, אנחנו צריכים להתקין אותו באופן גלובלי באופן הבא:


npm install -g mocha

אחרי ההתקנה, אם תכתבו mocha -V (שימו לב, ה-V גדולה) בכל מקום באמצעות הקונסולה, נראה את הגרסה של mocha.

אם אנחנו משתמשים ב-mocha בפרויקט שלנו, מקובל לכלול אותו גם ב-package.json בחלק של ה-dev. עושים את זה באמצעות:


npm install mocha --save-dev

בתיקית הפרויקט. זה לא נדרש על מנת שהכל יעבוד, אבל מקובל מאוד.

השלב הבא הוא לפתוח תיקית test בפרויקט שלנו. באופן דיפולטיבי, mocha תמיד מסתכלת בתיקית test. בתוכה ניצור קובץ עם סיומת js, למשל test.js. על מנת שהכל עובד, נכתוב בדיקת דמה כלשהי בתוך test.js:


var assert = require("assert"); // core module
describe('Array', function() {
  describe('#indexOf()', function () {
    it('should return -1 when the value is not present', function () {
      assert.equal(-1, [1,2,3].indexOf(5));
      assert.equal(-1, [1,2,3].indexOf(0));
    });
  });
});

אם הכל תקין והסביבה מקונפגת יפה, כשנכתוב mocha בתיקיה הראשית של הפרויקט. נראה משהו כזה:

$ mocha     Array     #indexOf()       √ should return -1 when the value is not present     1 passing (7ms)
$ mocha
Array
#indexOf()
√ should return -1 when the value is not present
1 passing (7ms)

אם זה עדיין נראה לכם כמו סינית ואתם לא מבינים את הסינטקס של הבדיקה, אני ממליץ לכם לרענן את הידע בבדיקות בסביבת node.js עם mocha.

טעינת אפליקצית express ועבודה עם supertest

עכשיו ניגש לאפליקציה שלנו, שהיא אפליקצית express. יש כמה דרכים לבדוק אפליקציה כזו, אבל אני אדבר על הדרך שבה אני בודק אותה – וזה בדיקת התוצר הסופי. אם נסתכל על האפליקציה שבניתי, שמחזירה מידע אם אני נכנס ל /help/about-me/, הבדיקה שלי תהיה בעצם הרמת השרת, יצירת 'דפדפן' וירטואלי, כניסה אל הכתובת ובדיקה שהדף קיים ויש בו את התוכן שאני רוצה.

אני רק רוצה להזכיר שיש לנו app.js שנראה ככה:


var express = require('express');
var app = express();
var help = require('./help');

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

app.set('view engine', 'ejs');

//Routers.
app.use('/help', help);

//The 404 Route (ALWAYS Keep this as the last route).
app.get('*', function(req, res){
  res.send('404 page', 404);
  //You can use template too! res.render('404-page');

});

//500 Middleware
app.use(function(err, req, res, next) {
  console.error(err.stack);
  res.status(500).send('Something broke!');
  //You can use template too! res.render('500-page');
});

module.exports = app;

אני רוצה שתשימו לב לשורה האחרונה – השורה הזו לא נדרשת לתפקוד ה-express באופן רגיל, אך היא קריטית לבדיקה האוטומטית ואנחנו צריכים אותה. מה שהיא עושה (למי ששכחת node.js בסיסי) זה לחשוף את app.js החוצה למי שיקרא לו.

הראוטר שלנו הוא help והוא מכיל כתובת אחת של about-me. זה נראה ככה:


var express = require('express');
var router = express.Router();

router.get('/about-me', function(req, res) {

  var children = [
    { id: 1, name: "Omri" },
    { id: 2, name: "Kfir" },
    { id: 3, name: "Daniel" },
    { id: 3, name: "Michal" }
  ];

  res.render('about-me', {pageName : 'About Me', children: children});
});

module.exports = router;

אם אני מפעיל את ה-express שלי עם node app.js, ואכנס אל http://localhost:3000/help/about-me, אני אראה את שמות הילדים.

עכשיו, אני רוצה לכתוב את הבדיקה. אמרתי שאחת ממטרות הבדיקה היא ליצור דפדפן 'וירטואלי'. כלומר מודול שישלח בקשה ל-localhost. המודול שאני משתמש בו נקרא supertest והוא בנוי על superagent. הוא מאפשר לי בקלות ליצור בקשות לכל כתובת שהיא. על מנת להתקינו אני אכתוב בקונסולה:


npm install supertest --save-dev

כזכור, הפלאג save-dev מכניס את המודול הזה ל-package.json בחלק של ה-dev. עכשיו כל מה שנותר לנו לעשות זה לכתוב את הבדיקה. כך זה נראה:


var request = require('supertest'),
  app = require('../app.js');

describe('help router', function(){ //Name of the tests collection
  it('GET about-me should return 200', function(done){ //Single test
    request(app) //Initiating the supertest with the app
      .get('/help/about-me')//Send GET to localhost:3000/help/about-me
      .expect(200, done);
  });
});

מה בעצם קורה פה? מה שמעניין הוא ה-supertest שנכנס לתוך request. אנחנו מאתחלים אותו על ידי העברת ארגומנט app שהוא אפליקצית ה-express שלנו. עכשיו אנחנו משתמשים במתודת get כדי ליצור בקשת GET ושם אנחנו מפרטים את היעד ומציינים שאנחנו רוצים לקבל 200.

אם נכתוב mocha, נראה שהבדיקה רצה בהצלחה:

$ mocha   Example app listening on port 3000!   help router     √ GET about-me should return 200
$ mocha
Example app listening on port 3000!
help router
√ GET about-me should return 200

פוסטים נוספים שכדאי לקרוא

פתרונות ומאמרים על פיתוח אינטרנט

עבודה עם GPT למתכנתים

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

DALL·E 2023-10-21 22.28.58 - Photo of a computer server room with red warning lights flashing, indicating a potential cyber threat. Multiple screens display graphs showing a sudde
יסודות בתכנות

מבוא לאבטחת מידע: IDOR

הסבר על התקפה אהובה ומוצלחת שבאמצעותה שואבים מידע מאתרים

תמונה מצוירת של רובוט שמנקה HTML
יסודות בתכנות

סניטציה – למה זה חשוב

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

פתרונות ומאמרים על פיתוח אינטרנט

SSG עם next

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

גלילה לראש העמוד