تقارير الأتمتة وتصحيح الأخطاء
تقارير الأتمتة (Automation Reporting) هي الطريقة التي يخبر بها تشغيلُ الاختبارات الناسَ بما حدث: أيّ الاختبارات نُفّذت، وأيّها فشل، وكم استغرق كلٌّ منها، وما الأدلة التي تركها كل فشل. أما تصحيح الأخطاء (Debugging) في اختبار فاشل فهو العمل الذي يلي ذلك: قراءة تلك الأدلة لمعرفة سبب الفشل، وهل يكمن السبب في المنتج أم في الاختبار أم في البيئة.
مثال ذلك: يُبلغ التشغيل الليلي أن الاختبار VAT is added to the order total فشل، إذ كانت القيمة المتوقعة 172.50 SAR والفعلية 150.00 SAR. ولقطة الشاشة وملف الأثر (trace) واستجابة الخادم المحفوظة مع الفشل تُظهر، دون إعادة تشغيل أي شيء، أن الخادم توقف عن إضافة ضريبة القيمة المضافة.
لماذا يهم
تُقاس فائدة حزمة الاختبارات الآلية بسرعة التصرف حين تظهر نتيجة حمراء. فإذا لم يترك الفشل سوى expected true, received false، اضطر أحدهم إلى إعادة تشغيل الاختبار وتخمين ظروف CI؛ ثم يعيد الفريق التشغيل حتى يخضرّ البناء، وتمرّ حالات الانحدار الحقيقية وسط الضجيج.
أما الأدلة الجيدة فتحوّل الفشل إلى تحقيق قصير: فلقطة الشاشة وملف الأثر يُظهران عادةً هل تصلح الاختبار، أم تتواصل مع مالك البيئة، أم تُبلغ عن عيب. وهي تجعل تقرير الخطأ قابلاً للتنفيذ، إذ يُرفق به الطلب الفاشل والاستجابة وملف الأثر بدلاً من «فشل اختبار الدفع».
التقارير: تشغيل واحد وقرّاء متعددون
للتشغيل الواحد عدة قرّاء. فمن بدأه يقرأ الطرفية. ومن يحقق في فشل يحتاج إلى تقرير HTML يُفتح فيه كل اختبار على خطواته وخطئه ومحاولات إعادته ومرفقاته. وخادم CI يحتاج إلى ملف تقرؤه الآلة، وهو عادةً JUnit XML، ليعرض النتائج لكل اختبار ويحتفظ بتاريخها. وفي Playwright تُدرج الصيغ التي تحتاجها تحت reporter.
التقرير الجيد يجيب، دون أن تسأل أحداً، عمّا فشل وأين وفي أي بيئة وبأي أدلة. سمِّ الاختبارات بالسلوك الذي تفحصه، وضع إجراءات منطق العمل داخل test.step() ليُقرأ التقرير كحالة اختبار، وأرفق البيانات التي لا تظهر على الشاشة.
- سياق التشغيل: البناء أو الإيداع، والمتصفح، والعنوان الأساسي (base URL)، ووقت البدء، لربط الفشل بعمليات النشر وسجلات الخادم.
- الاختبارات المتذبذبة (Flaky، أي فشلت ثم نجحت عند إعادة المحاولة) تُعدّ منفصلة عن الناجحة؛ وإلا أخفاها التقرير.
// playwright.config.ts (excerpt): one run, three readers
import { defineConfig } from '@playwright/test';
export default defineConfig({
reporter: [
['list'], // the terminal
['html', { open: 'never' }], // people: playwright-report/
['junit', { outputFile: 'results/junit.xml' }], // the CI server
],
});
// checkout.spec.ts: steps and attachments make the report read like a test case
import { test, expect } from '@playwright/test';
test('VAT is added to the order total', async ({ page }, testInfo) => {
const cart = await test.step('Create a cart with one 150.00 SAR book', () =>
createCart(page, { sku: 'BOOK-01', qty: 1 })); // createCart: a project helper
await testInfo.attach('cart', {
body: JSON.stringify(cart), contentType: 'application/json',
});
await test.step('Open checkout and check the total', async () => {
await page.goto('/checkout/' + cart.id);
await expect(page.getByTestId('order-total')).toHaveText('172.50 SAR');
});
});لقطات الشاشة والفيديو وملفات الأثر: ماذا يُظهر كلٌّ منها
احتفظ بالأدلة للاختبارات الفاشلة فقط: فكل نوع منها يجيب عن سؤال مختلف ويكلّف وقتاً في التشغيل ومساحة في التخزين.
- لقطة الشاشة (Screenshot): الصفحة لحظة الفشل، وتجيب عن سؤال «ماذا رأى المستخدم؟»: شريط خطأ، أو مؤشر تحميل، أو نافذة فوق الزر. في Playwright:
screenshot: 'only-on-failure'؛ ويلتقط Cypress لقطة تلقائياً حين يفشل اختبار فيcypress run؛ ومع Selenium استدعِtakeScreenshot()(JavaScript) أوgetScreenshotAs(Java) في خطاف الفشل (hook) لدى المشغّل. - الفيديو: الاختبار كاملاً، يُظهر الترتيب والحركة كنافذة ظهرت واختفت، لكن دون بيانات DOM أو الشبكة أو وحدة التحكم. وملفاته كبيرة: في Playwright استخدم
video: 'retain-on-failure'؛ ولا يسجّل Cypress إلا إذا فُعّل خيارهvideo(وهو معطّل افتراضياً). - ملف الأثر (Trace): تسجيل تتنقّل فيه خطوة خطوة. يضم أثر Playwright كل إجراء مع لقطات DOM قبله وبعده، وسجل الاستدعاء (call log)، ووحدة التحكم، وطلبات الشبكة واستجاباتها، وسطر الشيفرة. افتحه بـ
npx playwright show-trace، أو من تقرير HTML، أو في trace.playwright.dev الذي يحمّله في متصفحك دون رفعه إلى أي مكان. - السجلات: مخرجات المشغّل، ووحدة تحكم المتصفح، وسجلات الخادم للنافذة الزمنية نفسها، تُربط بالطابع الزمني أو بمعرّف الطلب.
- الأدلة بيانات أيضاً: قد يحمل ملف الأثر ترويسات الطلبات وملفات تعريف الارتباط (cookies) وكل ما كتبه الاختبار، فاستخدم بيانات اصطناعية واجعل للمخرجات (artifacts) مدة صلاحية.
// playwright.config.ts (excerpt): keep evidence for failures only
import { defineConfig } from '@playwright/test';
export default defineConfig({
retries: process.env.CI ? 1 : 0,
use: {
screenshot: 'only-on-failure',
video: 'retain-on-failure',
trace: 'on-first-retry', // needs retries; with none, use 'retain-on-failure'
},
});
// Then, in a terminal, open a trace downloaded from a CI run:
// npx playwright show-trace trace.zipتصحيح اختبار فاشل: من الخطأ الأول إلى السبب
يفصل ISTQB بين الاختبار، الذي يُظهر الإخفاقات، وتصحيح الأخطاء، الذي يجد أسبابها ويحللها ويزيلها. وفي الاختبار الآلي الفاشل يتولى المختبِر تحليل الإخفاق: هل العيب في المنتج أم في شيفرة الاختبار أم في البيئة؟ ويصحّح المختبِر شيفرة الاختبار، ويصحّح المطور المنتج انطلاقاً من الأدلة.
اقرأ الخطأ الأول لا الأخير؛ فالأخطاء اللاحقة نتائج له في الغالب. ونوعه يخبرك أيّ دليل تفتح. فخطأ الإعداد يعني أن الاختبار لم يصل إلى فحصه أصلاً: اقرأ خطأ الخطاف وسجل الخادم. وانتهاء مهلة إجراء يعني أن عنصراً لم يُعثر عليه أو لم يمكن استخدامه: افتح لقطة DOM قبل ذلك الإجراء وسجل استدعائه. وفشل التأكيد يعني أن الصفحة أظهرت شيئاً آخر: قارن لقطة الشاشة بالقيمة المتوقعة، ثم تحقّق في تبويب Network هل وصلت البيانات خاطئة أم متأخرة.
الإجابة: إعداد: فشلت خطوة إعداد أو خطاف أو تجهيزة
النتيجة: فشل في الإعداد: البيانات أو تسجيل الدخول أو خدمةلم يصل الاختبار إلى فحصه. اقرأ خطأ الخطاف وسجل الخادم قبل أن تشك في الميزة.الإجابة: انتهاء مهلة إجراء: نفد وقت نقرة أو إدخال أو انتظار
سؤال 2: هل العنصر موجود في لقطة DOM قبل الإجراء؟افتح ملف الأثر عند ذلك الإجراء واقرأ سجل الاستدعاءالإجابة: لا: صفحة خطأ أو مؤشر تحميل أو مساحة فارغة
النتيجة: لم تُحمَّل الصفحة: البيئة أو المنتجطلب فاشل أو بطيء في Network، أو خطأ برمجي في Console، يفسّر ذلك. ليست مشكلة محدِّد.الإجابة: نعم، لكن دوره أو نصه أو معرّف الاختبار تغيّر
النتيجة: محدِّد قديم أو تغيير غير معلن في الواجهةراجع المتطلب: حدّث الاختبار إن كان التغيير مقصوداً، وأبلغ عنه إن لم يكن.الإجابة: نعم، لكنه مغطّى أو معطّل أو ما زال يتحرك
النتيجة: سجل الاستدعاء يسمّي العائقانتظر حالة التطبيق نفسه أو عالج الطبقة المغطّية في الإعداد، ولا تفرض الإجراء بالقوة؛ وأبلغ عن عيب في الواجهة إن كان المستخدمون محجوبين أيضاً.
الإجابة: تأكيد: المتوقع يخالف الفعلي
سؤال 3: هل تُظهر لقطة الشاشة القيمة التي تلقاها الاختبار؟الإجابة: لا: تُظهر القيمة المتوقعة
النتيجة: مشكلة في الاختبار: فحص مبكر أو عنصر خاطئاستخدم تأكيداً يعيد المحاولة ومحدِّداً يشير إلى العنصر الصحيح.الإجابة: نعم: الصفحة تعرض القيمة الخاطئة
سؤال 4: في تبويب Network من ملف الأثر، كيف وصلت الاستجابة؟الإجابة: خاطئة: أرسل الخادم بيانات خاطئة
النتيجة: الواجهة الخلفية: عيب أو بيانات اختبار خاطئة أو إعداد تغيّرقارن الاستجابة بآخر تشغيل ناجح، وأبلغ عنها مع الطلب والاستجابة ونطاق البناءات.المثال التطبيقيالإجابة: صحيحة، لكن بعد انتهاء مهلة التأكيد
النتيجة: استجابة بطيئة: بيئة مثقلة أو انحدار في الأداءلا ترفع المهلة؛ قارن الزمن بآخر تشغيل ناجح واقرأ سجل الخادم لذلك الطلب.الإجابة: صحيحة وفي وقتها
النتيجة: عيب في الواجهة الأماميةتعرض الصفحة بيانات صحيحة بشكل خاطئ؛ أبلغ عنه مع لقطة الشاشة وملف الأثر.
لاختبار فاشل واحد تملك أدلته. أما الاختبار الذي ينجح عند إعادة تشغيله دون أي تغيير فيمرّ أولاً بإجراءات الاختبارات المتذبذبة.
- أعد إنتاج الإخفاق محلياً:
npx playwright test --debugيمشي بك في الاختبار خطوة خطوة داخل Playwright Inspector، و--uiيفتح وضع الواجهة (UI mode) مع عرض لكل تشغيل تتنقّل فيه عبر الزمن، وawait page.pause()يوقف الاختبار عند سطر تختاره في تشغيل بواجهة مرئية (headed). وغيّر شيئاً واحداً في كل مرة، كما في درس إعادة إنتاج الإخفاقات. - لا ترفع المهلة قبل أن تعرف لماذا نفد الوقت: فالاستجابة الأبطأ قد تكون هي العيب نفسه.
مثال تطبيقي: إجمالي طلب خاطئ في التشغيل الليلي
يُبلغ تشغيل الواجهة الليلي على بيئة staging، في البناء 512، عن فشل واحد؛ وقد فشلت إعادة المحاولة أيضاً، فهو فاشل لا متذبذب. وفيما يلي مقتطفات مختصرة من التقرير وملف الأثر.
الخطأ الأول فشلُ تأكيد: وُجد العنصر لكنه أظهر قيمة خاطئة. وتُظهر لقطة الشاشة ضريبة قدرها 0.00 في السلة، أي أن الاختبار قرأ ما عرضته الصفحة. وفي ملف الأثر تحتوي استجابة GET /api/cart/8812 أصلاً على "vatRate": 0: فقد عرض المتصفح ما أرسله الخادم. ولم يحتفظ آخر تشغيل ناجح، البناء 509، بملف أثر، لكن تقريره ما زال يضم بيانات cart بصيغة JSON التي يرفقها الاختبار في كل تشغيل، وفيها "vatRate": 0.15؛ ومقارنة الاستجابة بهذه البيانات بأداة مقارنة JSON تُظهر أن vatRate وtotal وحدهما تغيّرا.
إذن السبب تغيير في الواجهة الخلفية (back end) بين البناءين 509 و512 أو إعداد ضريبي تغيّر في بيئة staging؛ وسؤال واحد للمطور أو لمالك البيئة يحسم أيهما. الاختبار صحيح ويبقى كما هو. ويحمل التقرير «واجهة السلة البرمجية تعيد vatRate بقيمة 0 لسلة سعودية منذ البناء 512» الاستجابتين وملف الأثر ونطاق البناءات.
✘ checkout.spec.ts:42 › checkout › VAT is added to the order total
failed (retry #1 failed too) · chromium · staging · build 512
Error: expect(locator).toHaveText(expected)
Locator: getByTestId('order-total')
Expected: "172.50 SAR"
Received: "150.00 SAR"
at checkout.spec.ts:51
Attachments: cart · screenshot · video · trace
Build 512 › trace › Network › GET /api/cart/8812 → 200
{ "subtotal": 150.00, "vatRate": 0, "total": 150.00 }
Build 509 (last green run, no trace kept) › HTML report › attachment "cart"
{ "subtotal": 150.00, "vatRate": 0.15, "total": 172.50 }أخطاء شائعة
- إعادة تشغيل الاختبار الأحمر حتى ينجح دون قراءة أدلة المحاولة الفاشلة.
- رفع المهلة أو إضافة انتظار ثابت قبل معرفة سبب نفاد الوقت.
- تغيير القيمة المتوقعة إلى ما يعرضه التطبيق الآن دون الرجوع إلى المتطلب.
- تسجيل الفيديو وملفات الأثر لكل اختبار ناجح، أو عدم تسجيل شيء وترك إخفاقات CI برسالة فقط.
- مشاركة تقارير وملفات أثر تحتوي بيانات عملاء حقيقية أو كلمات مرور أو رموز وصول (tokens).
من منظور ضمان الجودة
في معظم الفرق يُلقي المختبِر النظرة الأولى على التشغيل الآلي الأحمر: يصنّف كل فشل في اليوم نفسه، ويربط إخفاقات المنتج بتقارير أخطاء مرفق بها ملف الأثر، ويصلح مشكلات الاختبار، ويحيل مشكلات البيئة إلى مالكها.
قدّم أدلة لا استنتاجات لا يمكن التحقق منها: الخطوة الفاشلة، والقيمتين المتوقعة والفعلية، والطلب والاستجابة، ونطاق البناءات، ورابطاً إلى ملف الأثر. واسأل عمّا لا تجيب عنه الأدلة، مثل: هل كان تغيير الواجهة مقصوداً؟
تمرين عملي
صنّف ثلاثة اختبارات فاشلة من تقرير ليلي
في التشغيل الليلي أدناه ثلاثة اختبارات فاشلة، لكلٍّ منها خطؤه الأول وما تُظهره لقطة الشاشة وملف الأثر. صنّف كلاً منها مستعيناً بشجرة القرار في هذا الدرس، وحدّد ما تفعله بعد ذلك.
Nightly UI run · build 731 · chromium · staging · 212 passed, 3 failed, 0 flaky
1) login.spec.ts:18 › login › shows the dashboard after sign-in
Error: locator.click: Timeout 10000ms exceeded.
Call log: getByRole('button', { name: 'Sign in' }): visible, enabled and stable
<div class="cookie-banner"> intercepts pointer events, retrying click
Screenshot: a new cookie banner covers the lower half of the sign-in form
2) profile.spec.ts:44 › profile › saves a new phone number
Error: expect(locator).toHaveText(expected)
Expected: "Saved" Received: "Saving..." Timeout: 5000ms
Trace: PUT /api/profile → 200 after 7.8 s
Server log, last green run (build 728): the same request took 0.4 s
3) orders.spec.ts:71 › orders › lists the newest order first
Error: expect(locator).toHaveText(expected)
Expected: "ORD-1042" Received: "ORD-1039"
Screenshot: the list shows ORD-1039 in the first row, ORD-1042 in the second
Trace: GET /api/orders?sort=newest → [ORD-1039 (10:02), ORD-1042 (10:05)]- سمِّ نوع الخطأ الأول: إعداد، أو انتهاء مهلة إجراء، أو تأكيد.
- سمِّ الدليل الذي يجيب عن السؤال التالي وما يُظهره.
- صنّف: مشكلة اختبار، أو مشكلة بيئة، أو عيب في الواجهة الأمامية أو الخلفية، أو لم يُحسم بعد.
- اكتب الإجراء التالي: تعديل الاختبار، أو عنوان تقرير الخطأ، أو السؤال الذي تطرحه.
إظهار الإجابة النموذجية
الاختبار 1، انتهاء مهلة إجراء: الزر جاهز، لكن سجل الاستدعاء ولقطة الشاشة يُظهران شريط ملفات تعريف ارتباط جديداً فوقه. فإن كان الشريط مقصوداً فهي مشكلة اختبار: اضبط الموافقة أو اقبلها في الإعداد المشترك، ولا تفرض النقر بالقوة أبداً. واسأل أيضاً هل يواجه المستخدمون على الشاشات الصغيرة الزر المغطّى نفسه؛ فإن كان كذلك فأبلغ عن عيب في الواجهة.
الاختبار 2، تأكيد: النص Saving... يدل على أن الصفحة كانت ما تزال تنتظر. ويشرح ملف الأثر السبب: نجح طلب الحفظ لكنه تأخر، إذ استغرق 7.8 ثانية، مقابل 0.4 ثانية في البناء 728 ومهلة تأكيد قدرها 5 ثوانٍ. ورفع المهلة يُخفي بطئاً يشعر به المستخدمون. لم يُحسم بعد: سجلات الخادم لذلك الطلب، بالرجوع إلى وقته في ملف الأثر، تفرّق بين بيئة staging مثقلة وانحدار في البناء 731.
الاختبار 3، تأكيد: الصفحة تعرض ما تلقّته، ويُظهر ملف الأثر أن الواجهة البرمجية نفسها أعادت ORD-1039 (10:02) قبل ORD-1042 (10:05) مع sort=newest. فالواجهة الخلفية ترتّب في الاتجاه المعاكس: أبلغ عن «واجهة الطلبات البرمجية مع sort=newest تعيد أقدم طلب أولاً» مع الطلب والاستجابة وملف الأثر.
أسئلة شائعة
هل أسجّل ملفات الأثر والفيديو لكل اختبار؟
غالباً لا: تسجيل كل شيء يبطئ التشغيل وينتج ملفات كبيرة لا يفتحها أحد. والإعداد الشائع إعادة محاولة واحدة في CI مع trace: 'on-first-retry'، أو 'retain-on-failure' حين لا توجد إعادة محاولة (فمع صفر محاولات لا يسجّل on-first-retry شيئاً)، مع الفيديو ولقطات الشاشة للاختبارات الفاشلة فقط. وفعّل التسجيل الكامل مؤقتاً فقط حين تطارد مشكلة بعينها.
هل تصحيح الأخطاء عمل المختبِر أم المطور؟
كلاهما، لعيوب مختلفة. يعدّ ISTQB الاختبار وتصحيح الأخطاء نشاطين منفصلين: الاختبار يُظهر الإخفاقات، وتصحيح الأخطاء يجد أسبابها ويحللها ويزيلها. يحلل المختبِر إخفاق الاختبار الآلي بما يكفي لإظهار مكان العيب، ويصحّح شيفرة الاختبار؛ أما شيفرة المنتج فيصححها المطور انطلاقاً من الأدلة التي أرفقها المختبِر.
أستخدم Selenium أو Cypress، فهل ينطبق هذا؟
نعم؛ يختلف التسجيل فقط. يلتقط Cypress لقطات الشاشة عند الفشل في cypress run، ويسجّل الفيديو حين يُفعَّل خيار video، ويُظهر لقطة لكل أمر في سجل الأوامر (Command Log) عند cypress open. أما Selenium WebDriver فلا يسجّل شيئاً بنفسه: التقط لقطة شاشة واحفظ مصدر الصفحة في خطاف الفشل لدى المشغّل، وسجّل كل خطوة مع طابعها الزمني. ويبقى ترتيب القراءة كما هو: الخطأ الأول، ثم الأدلة، ثم المقارنة.
من أين أبدأ حين تفشل اختبارات كثيرة في التشغيل نفسه؟
ابحث أولاً عن سبب مشترك. فإن فشلت اختبارات كثيرة بالخطأ الأول نفسه وفي الخطوة نفسها، مثل تسجيل الدخول أو خطاف الإعداد، فالسبب عادةً في البيئة أو في تجهيزة (fixture) مشتركة لا في كل اختبار على حدة. أصلحه أو أبلغ عنه مرة واحدة ثم أعد التشغيل؛ ويضم دليل اختبار CI/CD مخطط فرز لإخفاقات خط الأنابيب.
المراجع
- ISTQB Certified Tester Foundation Level (CTFL) v4.0المنهج التأسيسي لاختبار البرمجيات: مستويات الاختبار وأنواعه وتقنيات تصميم الاختبارات وإدارة الاختبار والأدوات.
- Certified Tester Advanced Level Test Automation Engineering (CTAL-TAE) v2.0منهج ISTQB المتقدم لتصميم حلول أتمتة الاختبار وتنفيذها وصيانتها وبنيتها.
- Trace viewer — Playwrightتسجيل تشغيل الاختبار وإعادة عرضه خطوة بخطوة — لقطات DOM والشبكة ووحدة التحكم — لتشخيص الإخفاقات، خصوصاً القادمة من CI.
- Cypress Documentationالتوثيق الرسمي لاختبار الويب الشامل واختبار المكونات في المتصفح باستخدام Cypress.
تدرّب بأدوات متقن
مقارنة مستندي JSON دلالياً وإبراز القيم المضافة والمحذوفة والمتغيرة.
قارن نصّين سطراً بسطر أو كلمةً بكلمة مع إبراز الاختلافات.
تنسيق XML بشكل أنيق مع مسافة بادئة قابلة للتخصيص، وإعادة تصغيره عند الحاجة.
حوّل الطوابع الزمنية (ثوانٍ، ميلي ثانية، ميكرو ثانية) إلى تواريخ مقروءة وبالعكس، بأي منطقة زمنية.
اشرح تتبّعات المكدس (stack traces) ورسائل الأخطاء، وحدّد الأسباب الجذرية المحتملة وخطوات التصحيح التالية باستخدام الذكاء الاصطناعي من متقن.
للتعمّق أكثر
- الاختبار في خطوط CI/CDتقارير الاختبار والمخرجات
- الاختبار في خطوط CI/CDتحليل إخفاقات خط الأنابيب: مسار للفرز
- الاختبارات المتذبذبةتشخيص اختبار متذبذب
- كيف تكتب تقرير خطأ (Bug Report)كيف تكتب تقرير خطأ يستطيع المطورون التصرف بناءً عليه: الحقول المهمة، ونموذج جاهز للنسخ، ومثال كامل، والفرق بين الخطورة والأولوية، والأخطاء الواجب تجنبها.
تقدّمك في هذا الموضوع
سجّل الدخول لتتابع تقدّمك
علّم الموضوعات مكتملة، وتابع من حيث توقفت، وافتح امتحانات التخصص.