اذهب إلى المحتوى

نتعرف في مقال اليوم على إطار عمل جيست Jest أحد الأطر الشائعة لاختبار الشيفرات المصدرية المكتوبة باستخدام رياكت React ولغة جافا سكريبت، فهو يقدم مجموعة شاملة من المطابِقات Matchers التي تقارن بين القيم المتوقعة والقيم الفعلية أثناء اختبار الشيفرة مما يسمح بكتابة اختبارات لعدة أنواع من المشاريع. كما يُنَظم الاختبارات في مجموعات اختبار test suites ليُحَسّن الصيانة والمقروئية، وينجز الاختبار بكفاءة وسلاسة.

ستتعرّف في هذا المقال على عدّة اختبارات شائعة الاستخدام في مجال تطوير البرمجيات، وبعض الممارسات المفيدة في عملية الاختبار. إذ سنكتب توابع جافا سكريبت JavaScript ثم سنختبرها باستخدام إطار عمل جيست Jest على خادم Vultr مع تطبيق نود جي إس NodeJS جاهز من صفحة متجر تطبيقات NodeJS marketplace.

أنواع الاختبارات

تتضمن عملية تطوير البرمجيات ثلاثة أنواع من الاختبارات لضمان جودة الشيفرة البرمجية وسلامة وظائفها. يخدم كل منها غرضًا محددًا:

اختبارات الوحدة Unit tests

تركز هذه الاختبارات على اختبار الوحدات أو المكونات الفردية مثل الدوال functions أو التوابع methods أو الصفوف classes. إذ يضمن هذا الاختبار أن كل مكونات الشيفرة البرمجية تعمل بصورة صحيحة من تلقاء نفسها.

اختبارات التكامل Integration tests

تركز هذه الاختبارات على تقييم تفاعل مكونات التطبيق المختلفة مع بعضها البعض. على عكس اختبارات الوحدة، التي تختبر مكونًا واحدًا، تهتم هذه الاختبارات بالتفاعلات بين عدّة وحدات للتأكد من أنها تعمل كما هو متوقع عند دمجها.

الاختبارات الشاملة End-to-end tests

تحاكي هذه الاختبارات سيناريوهات الاستخدام الحقيقية عن طريق اختبار التطبيق من البداية إلى النهاية. وتكون مؤتمتة automated عادة، وتتفاعل مع التطبيق كمستخدم حقيقي، مما يضمن أن التطبيق يعمل كما ينبغي.

منهجيات شائعة في عملية الاختبار

تساعد منهجية الإعداد Arrange واتخاذ الإجراء المناسب Act والتأكيد Assert  أو ما يعرف اختصارًا بمهنجية AAA على تقسيم الاختبار إلى مراحل منفصلة، وبذلك يصبح من السهل على المطورين والمراجعين فهم كل جزء من الاختبار على حدة، وتحديد الأخطاء بسرعة أكبر.

فيما يلي مثال يوضح المنهجية السابقة، حيث سنختبر فيما إذا كان البريد الإلكتروني للمستخدم مكتوبًا بأبجدية رقمية alphanumeric أي مكون من أحرف وأرقام، ويستخدم النطاق example.com:

test("returns false for an invalid domain", () => {
  const email = "user123@example.net";
  const result = isValidEmail(email);
  expect(result).toBe(false);
});

فيما يلي شرح المراحل الثلاثة للاختبار

مرحلة الإعداد Arrange

علينا في هذه المرحلة إعداد الشرط الأولي وبيئة الاختبار. بما فيه تهيئة الكائنات objects وإعداد الدخل inputs وضبط البيئة لإنشاء حالة الاستخدام التي نرغب في اختبارها، نريد في مثالنا اختبار عمل الدالة isValidEmail ونتحقق فيما إذا كانت تحدد بدّقة رسائل البريد الإلكتروني غير الصالحة. وهنا أسندنا إلى متغير البريد الإلكتروني سلسلة نصية لا تفي بالمعايير التي حددناها حيث تستخدم النطاق ‎.net بدلاً من ‎.com

مرحلة اتخاذ الإجراء المناسب Act 

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

مرحلة التأكيد Assert

في هذه المرحلة، علينا التحقق من أن نتيجة المرحلة السابقة تلبي التوقعات، وقد استخدمنا في مثالنا التابع expect الذي يوفره إطار عمل Jest، للتأكد من أن النتيجة التي أرجعتها الدالة isValidEmail محددة بأنها خاطئة، كما هو متوقع بالنسبة لبريد إلكتروني غير صالح.

إعداد مجلد المشروع على Vultr

سننشر أولًا خادم على Vultr ومن الضروري أن نحرص على تحديد الخيار NodeJS في علامة تبويب تطبيقات المتجر Apps Marketplace. بعدها علينا إعداد مشروع Node.js وتثبيت إطار عمل Jest. ثم تعريف دالتين في ملفي جافا سكريبت منفصلين، حيث سنختبر هاتين الدالتين في الخطوات القادمة.

نتأكّد من تثبيت Node.jS باستخدام الأمر التالي:

node --version

بعدها، ننشئ مجلدًا للمشروع ثم ننتقل إليه:

mkdir sample
cd sample

نبدأ تشغيل المشروع باستخدام الأمر التالي:

npm init -y

ثم نثبّت إطار عمل Jest:

npm install --save-dev jest

نلاحظ أننا استخدمنا الراية ‎--save-dev لتثبيت الحزمة كتبعية تطوير development dependency. ويعني هذا أن الحزمة ستُسخدم فقط خلال مرحلتي التطوير والاختبار، وليس في مرحلة الإنتاج.

بعد ذلك نفتح ملف package.json باستخدام أحد محررات الأكواد، وسنستخدم في مثالنا محرر النصوص نانو Nano.

nano package.json

الآن، علينا إضافة سكربت للاختبار

"scripts": {
  "test": "jest"
}

نغلق الملف باستخدم الاختصار Ctrl+X، ثم ننقر على مفتاح Y لحفظ التغييرات.

بعدها سنشئ ملف جافا سكريبت ونطلق عليه اسم token:

nano token.js

ننسخ الشيفرة التالية ونلصقها في ملف token.js، إذ توضح هذه الشيفرة كيفية حساب تاريخ انتهاء صلاحية مفتاح تشفير ويب JSON Web Token أو JWT اختصارًا، والتحقق من صلاحيته.

ملاحظة: إن شيفرة التحقق التالية هي للتوضيح فقط، حيث يوصى الاعتماد على مكتبات معتمدة عند التعامل مع رموز المصادقة في المشاريع الحقيقية مثل مكتبة jsonwebtoken.

/**
 *
 * @param {string} token
 * @returns {Date}
 */

function getTokenExpiryDate(token) {
  if (!token) return null;

  const tokenParts = token.split(".");
  const payload = tokenParts[1];
  const decodedPayload = Buffer.from(payload, "base64").toString();
  const payloadObject = JSON.parse(decodedPayload);
  const expiryDate = new Date(payloadObject.exp * 1000);

  return expiryDate;
}

/**
 *
 * @param {string} token
 * @returns {boolean}
 */

function isTokenExpired(token) {
  const expiryDate = getTokenExpiryDate(token);
  const currentDate = new Date();

  return currentDate > expiryDate;
}

module.exports = { isTokenExpired };

تُعَرّف الشيفرة السابقة دالتين هما getTokenExpiryDate وisTokenExpired اللتان تحسبان تاريخ انتهاء صلاحية رمز JWT وتعطيان إما القيمة true أو false بناءً على حالة صلاحية الرمز. 

نحفظ الملف ونغلقه، ثم ننشئ ملف جافا سكريبت آخر باسم email:

nano email.js

ثم نلصق فيه الشيفرة التالية:

function isValidEmail(email) {
  const emailRegex = /[a-zA-Z0-9]+@example\.com/;
  return emailRegex.test(email);
}


module.exports = { isValidEmail };

تُعَرّف الشيفرة السابقة الدالة isValidEmail التي تتحقق من صحة بنية البريد الإلكتروني باستخدام التعابير النمطية regex، والتي تتيح لنا التحقق من أن جميع عناوين البريد الإلكتروني مكتوبة بأبجدية رقمية وتنتهي بـالنطاق ‎@example.com. والآن، علينا حفظ الملف وإغلاقه.

كتابة اختبارات الوحدة Unit Tests باستخدام إطار عمل Jest

سنتعلم الآن كيفية كتابة اختبارات الوحدة باستخدام إطار عمل جيست Jest لاختبار دوال جافا سكريبت التي عرّفناها سابقًا. سنضع هذه الاختبارات في مجلد منفصل ضمن مجلد المشروع، ونوصي باتباع التسميات الاصطلاحية التي سنعتمدها في مقالنا لأن Jest يتعامل مع الملفات التي تنتهي بالصيغة .test.js‎ كملفات اختبار. 

أولًا، ننشئ مجلدّا يدعى tests داخل مجلد sample، ثم ننتقل إليه باستخدام الأمر cd على النحو التالي:

mkdir tests
cd tests

بعدها ننشئ ملف جافا سكريبت.

nano token.test.js

ننسخ الشيفرة التالية ونلصقها في الملف.

const { isTokenExpired } = require("/root/sample/token.js");

describe("isTokenExpired", () => {
  test("should return false if the token is not expired", () => {
    const token = "eyJ0eXAiOiJKV1QiLCJhbGciOi...";
    const result = isTokenExpired(token);
    expect(result).toBe(false);
  });

  test("should return true if the token is expired", () => {
    const token = "eyJ0eXAiOiJKV1QiLCJhbGciOi...";
    const result = isTokenExpired(token);
    expect(result).toBe(true);
  });
});

تستخدم الشيفرة السابقة الدالة isTokenExpired التي عرّفناها سابقًا لتحديد ما إذا كانت الدالة تتصرف كما هو متوقع، وتعيد قيمةً منطقيةً تحدد إن كان رمز JWT منتهي الصلاحية أم لا.

ملاحظة: إن أردنا أن تتحقق الدالة isTokenExpired من صحة رموز مصادقة حقيقية، يمكننا إنشاء رموز JWT منتهية الصلاحية وأخرى غير منتهية الصلاحية بواسطة أداة مثل JSON Web Token Builder واستخدامها بدلاً من النصوص المستخدمة في الاختبارات السابقة.

نحفظ الملف ونغلقه، ثم ننشئ ملف جافا سكريبت آخر للاختبار.

nano email.test.js

ننسخ الشيفرة التالية ونلصقها في ملف الاختبار.

const { isValidEmail } = require("/root/sample/email.js");

describe("isValidEmail", () => {
  test("returns true for a valid email", () => {
    const email = "user123@example.com";
    const result = isValidEmail(email);
    expect(result).toBe(true);
  });

  test("returns false for an invalid domain", () => {
    const email = "user123@example.net";
    const result = isValidEmail(email);
    expect(result).toBe(false);
  });
});

تختبر الشيفرة السابقة دالة isValidEmail من خلال توفير بريد إلكتروني صالح وآخر غير صالح. ثم تتحقق من صحة النتائج عن طريق مطابقة المخرجات المتوقعة مع المخرجات الفعلية.

تشغيل اختبارات Jest على Vultr

سنتعلم الآن كيف نجري اختبارات باستخدام إطار عمل Jest بطريقتين. إذ سنجري في الطريقة الأولى اختبارات وحدة فردية لكل دالة معرّفة سابقًا. أما في الطريقة الثانية، فسنختبر الدالتين في وقت واحد.

اختبارات وحدة فردية

أولًا: نختبر صحة رمز المصادقة.

npm test -- tests/token.test.js

إن نجح الاختبار فيجب أن يبدو الخرج على النحو التالي:

> sample@1.0.0 test
 > jest tests/token.test.js

 PASS  tests/token.test.js
 isTokenExpired
     ✓ should return false if the token is not expired (2 ms)
     ✓ should return true if the token is expired (1 ms)

 Test Suites: 1 passed, 1 total
 Tests:       2 passed, 2 total
 Snapshots:   0 total
 Time:        0.315 s, estimated 1 s
 Ran all test suites matching /tests\/token.test.js/i.

ثانيًا: نختبر صحة البريد الإلكتروني.

npm test -- tests/email.test.js

إن نجح الاختبار فسيبدو الخرج على النحو التالي:

> sample@1.0.0 test
> jest tests/email.test.js

PASS  tests/email.test.js
isValidEmail
    ✓ returns true for a valid email (2 ms)
    ✓ returns false for an invalid domain (1 ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        0.451 s
Ran all test suites matching /tests\/email.test.js/i.

إجراء جميع الاختبارات في وقت واحد

أولًا: نشغّل جميع الاختبارات في وقت واحد.

npm test

إن نجح الاختبار فسيبدو الخرج على النحو التالي:

> sample@1.0.0 test
> jest

PASS  tests/email.test.js
PASS  tests/token.test.js

Test Suites: 2 passed, 2 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        0.225 s, estimated 1 s
Ran all test suites.

ختامًا

تعرّفنا في هذا المقال على أنواع مختلفة من الاختبارات البرمجية، وعلى بعض المنهجيات والممارسات المفيدة في عملية الاختبار. وتعلّمنا كيفية كتابة وتطبيق اختبارات الوحدة باستخدام إطار عمل Jest على خادم Vultr مثبّت عليه Node.js. حيث يمكن زيادة موثوقية وقوة الشيفرة البرمجية من خلال الاستفادة من أدوات الاختبار مثل Jest لتطوير برامج أكثر استقرارًا وقابلة للصيانة.

ترجمة -وبتصرّف- للمقال Testing JavaScript with Jest on Vultr.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...