الحفر أعمقالإختبارات

الاختبارات في كوكب Kawkab

الاختبارات هي جزء أساسي من تطوير البرمجيات في إطار العمل كوكب Kawkab. تساعد في ضمان جودة الكود وموثوقيته، وتسهل اكتشاف الأخطاء مبكراً في دورة التطوير.


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

في كوكب Kawkab، هناك نوعان رئيسيان من الاختبارات:

1. الاختبارات الوحدوية (Unit Tests)

  • تختبر وحدات صغيرة من الكود بشكل منعزل
  • تتركز على دالة أو فئة واحدة
  • سريعة التنفيذ وسهلة الصيانة

2. الاختبارات التكاملية (Integration Tests)

  • تختبر تفاعل عدة مكونات مع بعضها
  • تتحقق من سير العمل الكامل
  • أكثر شمولية من الاختبارات الوحدوية

هيكل الاختبارات

هيكل الملفات

/app
  /main
    /test
      /unit          # الاختبارات الوحدوية
      /integration   # الاختبارات التكاملية

كتابة الاختبارات الوحدوية

مثال على اختبار وحدوي

import { BasicMath } from "../BasicMath";
 
describe("BasicMath", () => {
  let math: BasicMath;
 
  beforeEach(() => {
    math = new BasicMath();
  });
 
  test("should add two numbers correctly", () => {
    expect(math.add(2, 3)).toBe(5);
  });
 
  test("should subtract two numbers correctly", () => {
    expect(math.subtract(5, 3)).toBe(2);
  });
});

شرح المكونات:

  1. describe: يجمع مجموعة من الاختبارات المتعلقة
  2. beforeEach: يُنفذ قبل كل اختبار
  3. test: يحدد حالة اختبار واحدة
  4. expect: يتحقق من النتيجة المتوقعة

كتابة الاختبارات التكاملية

مثال على اختبار تكاملي

describe("User Registration Flow", () => {
  let connectToDatabase: () => Promise<void>;
  let disconnectFromDatabase: () => Promise<void>;
  let registerUser: (user: {
    username: string;
    email: string;
  }) => Promise<{
    status: boolean;
    user?: { username: string; email: string };
  }>;
 
 
  beforeAll(async () => {
    // إعداد دوال الاتصال بالقاعدة
    connectToDatabase = async () => {
      // محاكاة الاتصال بالقاعدة
      console.log("Database connected");
    };
 
    disconnectFromDatabase = async () => {
      // محاكاة فصل الاتصال بالقاعدة
      console.log("Database disconnected");
    };
 
    registerUser = async (user) => {
      // محاكاة عملية التسجيل
      if (user.username && user.email) {
        return { status: true, user };
      }
      return { status: false };
    };
 
    // الاتصال بالقاعدة
    await connectToDatabase();
  });
 
  afterAll(async () => {
    // فصل الاتصال بالقاعدة
    await disconnectFromDatabase();
  });
 
  test("should register a new user successfully", async () => {
    const user = {
      username: "test_user",
      email: "test@example.com",
    };
 
    const response = await registerUser(user);
    expect(response.status).toBe(true);
    expect(response.user).toBeDefined();
    expect(response.user?.username).toBe(user.username);
    expect(response.user?.email).toBe(user.email);
  });
});

شرح المكونات:

  1. beforeAll: يُنفذ مرة واحدة قبل جميع الاختبارات
  2. afterAll: يُنفذ مرة واحدة بعد جميع الاختبارات
  3. async/await: للتعامل مع العمليات غير المتزامنة

تشغيل الاختبارات

تشغيل جميع الاختبارات

npm run test

تشغيل اختبارات محددة

npm run test -- path/to/test

تشغيل في وضع المراقبة

npm run test -- --watch

أوامر إنشاء الاختبارات

إنشاء اختبار تكاملي جديد

npm run kawkab test:integration <name> [module]

إنشاء اختبار وحدوي جديد

npm run kawkab test:unit <name> [module]

تفاصيل المعلمات:

  • <name>: اسم الـ Test الذي ترغب في إنشائه.
  • [module]: اسم الموديول الذي يحتوي على الـ Action (اختياري، الافتراضي هو main).

أفضل الممارسات

1. تسمية الاختبارات

  • استخدم أسماء وصفية واضحة
  • اتبع نمط “should do something”
test("should return user details when valid ID is provided", () => {
  // ...
});

2. تنظيم الاختبارات

  • جمع الاختبارات المتعلقة في describe واحد
  • استخدم describe متداخلة للتنظيم الأفضل

3. التحضير للاختبار

  • استخدم beforeEach لإعداد الحالة الأولية
  • نظف البيانات بعد كل اختبار باستخدام afterEach

4. التغطية

  • اختبر الحالات الإيجابية والسلبية
  • تأكد من تغطية جميع المسارات المنطقية

التعامل مع الأخطاء

اختبار الاستثناءات

test("should throw error for invalid input", () => {
  expect(() => {
    math.divide(1, 0);
  }).toThrow("Cannot divide by zero");
});

اختبار الوعود (Promises)

test("should resolve with user data", async () => {
  const data = await userService.fetch(1);
  expect(data).toBeDefined();
});

الاختبارات الوهمية (Mocks)

إنشاء كائن وهمي

const mockDatabase = {
  query: jest.fn().mockResolvedValue({ rows: [] }),
};

التحقق من الاستدعاءات

test("should call database once", async () => {
  await userService.getUsers();
  expect(mockDatabase.query).toHaveBeenCalledTimes(1);
});

تقارير التغطية

تشغيل تقرير التغطية

npm run test:coverage

تفسير النتائج

  • Statements: نسبة العبارات المغطاة
  • Branches: نسبة المسارات المنطقية
  • Functions: نسبة الدوال المختبرة
  • Lines: نسبة الأسطر المغطاة

الختام

الاختبارات في كوكب Kawkab توفر طريقة منظمة وفعالة للتأكد من جودة الكود. باتباع هذه الإرشادات والممارسات، يمكنك بناء مجموعة اختبارات قوية تساعد في تطوير وصيانة تطبيقك بثقة.

💡 تذكر: الاختبارات الجيدة تؤدي إلى كود أفضل وتطبيق أكثر موثوقية!