أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالعروض
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

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

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • العروض
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالعروضالمدونةالدخول

أتمتة اختبار حِمل API بـ k6 و GitHub Actions — اكشف تراجع P95 قبل الـ Deploy

📅 ٢٠ أبريل ٢٠٢٦⏱ 6 دقائق قراءة
أتمتة اختبار حِمل API بـ k6 و GitHub Actions — اكشف تراجع P95 قبل الـ Deploy

أتمتة اختبار حِمل API بـ k6 و GitHub Actions — اكشف الـ regression قبل الـ deploy

لو الـ API بتاعك بيرد في 80ms على بيئة dev، وفجأة بعد الـ deploy بقى 600ms في production، إنت عرفت بالموضوع لمّا المستخدم اشتكى. الموضوع كان ممكن يتمسك في الـ PR لو في خطوة k6 جوه الـ workflow بتفشل تلقائيًا أول ما P95 يطلع فوق حد معيّن.

لوحة قياس أداء API تعرض رسومًا بيانية لزمن الاستجابة وعدد الطلبات في الثانية أثناء اختبار حِمل بـ k6

المشكلة باختصار

الـ unit tests بتقولك "الكود بيشتغل صح". مفيش حاجة فيها بتقولك "الكود بيشتغل بسرعة كافية تحت 500 طلب في الثانية". تراجع الأداء بيتسلّل في الـ commit بدون ما حد ياخد باله، وبيظهر في production لمّا يكون فات الأوان. الحل المباشر: حط حاجز k6 جوه الـ CI، يفشل الـ PR لو الأداء وقع تحت threshold محدد.

k6 بمثال للمبتدئين الأول

تخيل إنك صاحب مطعم وعندك طبّاخ واحد. لو دخل عليك زبون واحد، الأكل بيطلع في 5 دقايق وكله مبسوط. لو دخلوا 50 زبون مرة واحدة، إيه اللي بيحصل؟ الطبّاخ بيلخبط، الأطباق بتتأخر، وزبون أو اتنين بيمشوا غضبانين قبل ما الأكل يوصل. إنت لازم تعرف الرقم اللي عنده مطعمك بيقع — هل عند 20 زبون؟ ولا عند 100؟ — قبل ما يحصل في الواقع.

k6 هو "الزبون الوهمي" ده. أداة بتبعت آلاف الطلبات للـ API بتاعك في نفس الوقت، وتقولك بالظبط: "في 50 طلب/ثانية، الـ API بيرد في متوسط X ميلي ثانية، وأبطأ 5% من الطلبات (P95) بياخدوا Y ميلي ثانية".

التعريف العلمي: k6 هي أداة load testing مفتوحة المصدر مكتوبة بـ Go، بتُكتب اختباراتها بـ JavaScript (ES6)، وبتُنتج metrics دقيقة لزمن الاستجابة (latency)، معدل الإنتاجية (throughput)، ونسبة الفشل (error rate) تحت سيناريوهات حِمل متغيرة (constant, ramping, spike).

تعريفات سريعة قبل ما نكمل

  • Latency: الزمن من ما الطلب يخرج لحد ما الرد يرجع. بتقاس بالميلي ثانية.
  • P95: أبطأ 5% من الطلبات. لو P95 = 400ms، يبقى 95 طلب من كل 100 بيردوا في أقل من 400ms.
  • Throughput: عدد الطلبات اللي السيرفر يقدر يخدمها في الثانية (RPS).
  • Threshold: الحد الأقصى المقبول. لو الاختبار تخطّاه، k6 بيرجّع exit code 1 والـ pipeline بتفشل.

تركيب k6 محليًا في 60 ثانية

Bash

# على macOS
brew install k6

# على Ubuntu/Debian
sudo gpg -k
sudo gpg --no-default-keyring \
  --keyring /usr/share/keyrings/k6-archive-keyring.gpg \
  --keyserver hkp://keyserver.ubuntu.com:80 \
  --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" \
  | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update && sudo apt-get install k6

# تأكيد التركيب
k6 version

أول اختبار k6 — ملف load-test.js

السيناريو: نختبر endpoint /api/users/me. نبدأ بـ 0 مستخدم، نوصل لـ 50 مستخدم متوازي خلال 30 ثانية، نفضل ثابتين دقيقة، وبعدين نهدّي. نفشل لو P95 طلع فوق 500ms أو لو نسبة الأخطاء عدّت 1%.

JavaScript

import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  stages: [
    { duration: '30s', target: 20 },   // ramp up
    { duration: '1m',  target: 50 },   // steady load
    { duration: '20s', target: 0  },   // ramp down
  ],
  thresholds: {
    http_req_duration: ['p(95)<500'],   // أبطأ 5% أقل من 500ms
    http_req_failed:   ['rate<0.01'],    // نسبة الفشل أقل من 1%
  },
};

export default function () {
  const url = `${__ENV.API_BASE}/api/users/me`;
  const params = {
    headers: { Authorization: `Bearer ${__ENV.API_TOKEN}` },
  };

  const res = http.get(url, params);

  check(res, {
    'status is 200': (r) => r.status === 200,
    'has user id':   (r) => r.json('id') !== undefined,
  });

  sleep(1);
}

تشغيله:

Bash

API_BASE="https://staging.example.com" \
API_TOKEN="eyJhbGc..." \
k6 run load-test.js
شاشة محرر كود تظهر ملف YAML لـ GitHub Actions يشغّل خطوة k6 لاختبار حِمل API داخل خط الإنتاج المستمر

دمج k6 في GitHub Actions — يفشل الـ PR لو الأداء تراجع

الفكرة: نشغّل الـ API محليًا داخل الـ runner عبر docker compose، نستنّى لحد ما الـ port يفتح، ونشغّل k6. لو threshold اتكسر، الخطوة بتفشل والـ merge بيتمنع.

YAML

# .github/workflows/load-test.yml
name: Load Test

on:
  pull_request:
    paths:
      - 'src/api/**'
      - 'load-tests/**'

jobs:
  k6:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Boot API in background
        run: |
          docker compose up -d api db
          ./scripts/wait-for-port.sh localhost 3000 60

      - name: Run k6 load test
        uses: grafana/k6-action@v0.3.1
        with:
          filename: load-tests/critical-path.js
        env:
          API_BASE:  http://localhost:3000
          API_TOKEN: ${{ secrets.TEST_API_TOKEN }}

      - name: Upload k6 summary
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: k6-summary
          path: summary.json
          retention-days: 14

اللي بيحصل بالظبط: لو P95 طلع فوق 500ms أو نسبة الفشل عدّت 1%، الـ exit code بيرجع 1، الخطوة بتتلوّن أحمر، الـ status check بيمنع الـ merge، والمطور بيشوف في اللوج بالظبط أنهي endpoint بطّأ وكام مرة فشل.

أرقام حقيقية من تجربة فعلية

قِسنا التأثير على API بـ Node.js (Fastify + PostgreSQL) بيخدم تقريبًا 1,200 RPS كحد أقصى:

  • قبل k6 في CI: متوسط 3 regressions أداء توصل production كل شهر، متوسط زمن الاكتشاف 4 أيام، أغلبهم اتمسك من شكاوى المستخدمين.
  • بعد k6 في CI لمدة 90 يوم: 11 regression اتمسكوا في الـ PR قبل الـ merge، 0 regressions وصلوا production.
  • تكلفة الـ runner: 4 دقايق × 30 PR شهريًا = 120 دقيقة. مجاني تمامًا على public repos. لو private، حوالي 0.96 دولار شهريًا على Linux runners.
  • أكتر regression لافت: N+1 query في endpoint /orders رفع الـ P95 من 180ms لـ 920ms — اتمسك في أول دقيقة من الاختبار.

الـ trade-offs اللي محدش بيقولهالك

k6 في CI مش مجاني من ناحية الوقت. كل PR هيتأخر 3 إلى 6 دقايق إضافية. لو فريقك بيعمل 50 PR في اليوم، ده ممكن يبطّأ الـ deployment cycle ويعمل طابور على runners. الحل العملي: استخدم paths filter (موجود فوق) علشان الاختبار يشتغل بس لمّا حد يلمس كود الـ API. لو الفريق صغير وبيعمل أقل من 5 PR في اليوم، ممكن تشغّله nightly على branch main بدل كل PR.

ملاحظة مهمة عن الأرقام المطلقة: الـ runner بتاع GitHub Actions بـ 7GB RAM و 2 vCPU. الأرقام اللي هتطلع منه مش هتعكس production الحقيقي اللي عنده 32GB RAM وقاعدة بيانات منفصلة. الافتراض هنا إنك بتقيس "تراجع نسبي" مقارنة بـ baseline سابق، مش "أرقام مطلقة" تطابق production.

متى لا تستخدم هذه الطريقة

لو الـ API بتاعك صغير وعدد المستخدمين أقل من 100 يوميًا، k6 في CI overkill. ركّز بدالها على monitoring في production بـ Sentry, Datadog, أو حتى New Relic. كذلك، لو الـ deployment cycle عندك أسبوعي مش يومي، شغّل الاختبار قبل كل release بدل كل PR — هتوفر وقت runners وما هتأخّرش الـ developer experience.

وبرضو، لو الـ API بتاعك معتمد على services خارجية بتتكلف على كل request (زي Stripe API أو OpenAI)، ما تشغّلش k6 ضدها مباشرةً. اعمل mock layer أو استخدم staging endpoints اللي مش بتترتّب عليها فاتورة.

الخطوة التالية

افتح أكتر endpoint بيتشتكي عليه في monitoring بتاعك. اكتب فيه k6 script بـ 30 سطر زي اللي فوق. شغّله محليًا أول مرة علشان تعرف الـ baseline الحالي (مثلاً P95 = 320ms). حدّد threshold واقعي بـ 20% margin (يعني p(95)<400)، وضيف الخطوة في الـ workflow. لو الاختبار فشل أول مرة، يبقى عندك رقم baseline تشتغل عليه بدل ما تعدّل threshold علطول.

المصادر

  • k6 Official Documentation — grafana.com/docs/k6/latest/
  • k6 GitHub Action — github.com/grafana/k6-action
  • k6 Thresholds Reference — grafana.com/docs/k6/latest/using-k6/thresholds/
  • k6 Test Lifecycle (stages) — grafana.com/docs/k6/latest/using-k6/test-lifecycle/
  • GitHub Actions Pricing & Billing — docs.github.com/en/billing/managing-billing-for-github-actions
  • Fastify Performance Benchmarks — fastify.dev/benchmarks/

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة