🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

كيفية كتابة اختبارات التكامل لواجهة برمجة تطبيقات REST في عام 2026: الدليل الكامل

⏱️3 min read  ·  503 words

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

اختبارات الوحدة مقابل التكامل

الجانب اختبار الوحدة اختبار التكامل
النطاق دالة واحدة منفردة أجزاء متعددة معًا (المسار + قاعدة البيانات)
التبعيات سخرية قاعدة بيانات حقيقية (أو اختبارية)
السرعة سريع جدا أبطأ (الإدخال/الإخراج الحقيقي)
المصيد أخطاء منطقية أخطاء التكامل/الأسلاك

تريد كلاهما – اختبارات الوحدة للمنطق، واختبارات التكامل للتحقق من عمل تدفق الطلب والاستجابة بالكامل.

Node.js: الاختبار باستخدام Supertest

npm install --save-dev jest supertest
// Export your app WITHOUT calling listen() so tests can use it
// app.js
const express = require('express');
const app = express();
app.use(express.json());
app.get('/users/:id', getUser);
app.post('/users', createUser);
module.exports = app;   // export the app

// server.js (separate) starts it
const app = require('./app');
app.listen(3000);
// users.test.js
const request = require('supertest');
const app = require('./app');
const db = require('./db');

describe('Users API', () => {
  beforeEach(async () => {
    await db.reset();   // clean database before each test
  });

  afterAll(async () => {
    await db.close();
  });

  it('creates a user', async () => {
    const res = await request(app)
      .post('/users')
      .send({ name: 'Alice', email: 'alice@example.com' });

    expect(res.status).toBe(201);
    expect(res.body).toMatchObject({ name: 'Alice' });
    expect(res.body.id).toBeDefined();
  });

  it('returns 404 for missing user', async () => {
    const res = await request(app).get('/users/999');
    expect(res.status).toBe(404);
  });

  it('validates required fields', async () => {
    const res = await request(app).post('/users').send({});
    expect(res.status).toBe(400);
    expect(res.body.error).toBeDefined();
  });
});

بايثون: الاختبار باستخدام pytest وTestClient

pip install pytest httpx
# test_users.py (FastAPI example)
import pytest
from fastapi.testclient import TestClient
from app.main import app
from app.database import get_test_db

client = TestClient(app)

@pytest.fixture(autouse=True)
def reset_db():
    db = get_test_db()
    db.reset()
    yield
    db.close()

def test_create_user():
    response = client.post("/users", json={
        "name": "Alice", "email": "alice@example.com"
    })
    assert response.status_code == 201
    data = response.json()
    assert data["name"] == "Alice"
    assert "id" in data

def test_get_missing_user():
    response = client.get("/users/999")
    assert response.status_code == 404

def test_validation_error():
    response = client.post("/users", json={})
    assert response.status_code == 422

استخدام قاعدة بيانات اختبارية

تحتاج اختبارات التكامل إلى قاعدة بيانات (اختبارية) حقيقية — منفصلة عن التطوير والإنتاج:

# Spin up a test database with Docker
docker run -d --name test-db -p 5433:5432 \
  -e POSTGRES_DB=testdb -e POSTGRES_PASSWORD=test \
  postgres:15-alpine

# Point tests at it via environment
DATABASE_URL=postgresql://postgres:test@localhost:5433/testdb
// Fast reset using transactions (rollback after each test)
beforeEach(async () => {
  await db.query('BEGIN');
});
afterEach(async () => {
  await db.query('ROLLBACK');   // undo all changes — fast and clean
});

اختبار نقاط النهاية المصادق عليها

describe('Protected routes', () => {
  let token;

  beforeAll(async () => {
    const res = await request(app)
      .post('/login')
      .send({ email: 'test@example.com', password: 'password' });
    token = res.body.accessToken;
  });

  it('allows access with valid token', async () => {
    const res = await request(app)
      .get('/protected')
      .set('Authorization', `Bearer ${token}`);
    expect(res.status).toBe(200);
  });

  it('rejects without token', async () => {
    const res = await request(app).get('/protected');
    expect(res.status).toBe(401);
  });
});

تشغيل اختبارات التكامل في CI

# GitHub Actions with a service database
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:15
        env:
          POSTGRES_DB: testdb
          POSTGRES_PASSWORD: test
        ports: ['5432:5432']
        options: --health-cmd pg_isready --health-interval 10s
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npm ci
      - run: npm run test:integration
        env:
          DATABASE_URL: postgresql://postgres:test@localhost:5432/testdb

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

  • اختبارات العزلة: يجب أن يكون كل اختبار مستقلاً — قم بإعادة ضبط قاعدة البيانات بين الاختبارات
  • اختبار العقد: التحقق من رموز الحالة وشكل الاستجابة وحالات الخطأ
  • تغطية مسارات الخطأ: اختبار 400 و401 و404 وفشل التحقق من الصحة، وليس فقط المسار السعيد
  • استخدم قاعدة بيانات اختبارية حقيقية: لا تسخر من قاعدة البيانات في اختبارات التكامل
  • احتفظ بها بسرعة معقولة: التراجع عن المعاملات أسرع من اقتطاع الجداول
  • تشغيل في CI: تكتشف اختبارات التكامل أخطاء الأسلاك التي تفوتها اختبارات الوحدة

الأسئلة المتداولة

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

س: كيف يمكنني إجراء اختبارات التكامل بسرعة؟
ج: استخدم التراجع عن المعاملات بين الاختبارات بدلاً من اقتطاع/إعادة إنشاء الجداول. قم بإجراء الاختبارات بالتوازي حيثما تسمح العزلة. استخدم قاعدة بيانات محتواة واحتفظ بها صغيرة.

س: كم عدد اختبارات التكامل التي أحتاجها؟
ج: قم بتغطية المسارات الهامة لكل نقطة نهاية – النجاح، وأخطاء التحقق من الصحة، وفشل المصادقة، والحالات التي لم يتم العثور عليها. تتعامل اختبارات الوحدة مع التفاصيل المنطقية؛ تغطي اختبارات التكامل السلوكيات الرئيسية لكل نقطة نهاية.

س: اختبارات التكامل أو اختبارات E2E؟
ج: تتحقق اختبارات التكامل من طبقة واجهة برمجة التطبيقات (المسارات + قاعدة البيانات). تتحقق اختبارات E2E من التدفق الكامل للمستخدم عبر واجهة المستخدم. كلاهما لهما قيمة — لديهما اختبارات تكامل أكثر من E2E نظرًا لأنهما أسرع وأكثر تركيزًا.

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

الخلاصة

تتحقق اختبارات التكامل من أن واجهة برمجة التطبيقات الخاصة بك تعمل بشكل كامل – المسارات وقاعدة البيانات والمنطق معًا – مما يؤدي إلى اكتشاف أخطاء الأسلاك التي تفشل اختبارات الوحدة في اكتشافها. استخدمSupertest مع Jest (Node.js) أو pytest مع TestClient (Python)، وقم بتوجيههم إلى قاعدة بيانات اختبار حقيقية (إعادة التعيين بين الاختبارات عبر استعادة المعاملة للسرعة)، وتغطية حالات النجاح، وأخطاء التحقق من الصحة، والمصادقة، والمسارات التي لم يتم العثور عليها. قم بتشغيلها في CI باستخدام قاعدة بيانات الخدمة. تمنحك اختبارات التكامل، جنبًا إلى جنب مع اختبارات الوحدة للمنطق، الثقة في أن واجهة برمجة التطبيقات الخاصة بك تعمل فعليًا كما يتوقع العملاء.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা