الخلاصة
غالبًا ما تختفي المتغيرات التي يتم تعيينها أثناء تنفيذ الطلبات يدويًا عند تشغيل نفس المجموعة في Collection Runner الخاص بـ Postman. السبب الجذري هو عدم تطابق نطاق المتغيرات: `pm.environment.set` يتصرف بشكل مختلف في الـ runner عنه في الوضع اليدوي، ومتغيرات المجموعة تعمل بشكل مختلف عن متغيرات البيئة. يشرح هذا الدليل بالضبط لماذا يحدث هذا وكيفية إصلاحه، ثم يوضح كيف يتعامل Apidog مع نطاق المتغيرات بطريقة يصعب فيها حدوث خطأ في التكوين عن طريق الخطأ.
مقدمة
كنت تختبر واجهة برمجة تطبيقات (API) يدويًا في Postman. تقوم بتشغيل طلب تسجيل دخول، ويقوم سكربت ما قبل الطلب بتعيين رمز مصادقة (auth token)، وتلتقطه الطلبات اللاحقة بشكل جيد. كل شيء يعمل.
ثم تنقر على "تشغيل المجموعة" (Run Collection). يبدأ الـ runner، وينجح طلب تسجيل الدخول، لكن الطلب التالي يفشل بخطأ 401. الرمز المميز ليس موجودًا.
يظهر هذا السيناريو بشكل متكرر على Stack Overflow ومنتديات مجتمع Postman. تشير الإجابات عادةً إلى نطاق المتغيرات، ولكنها نادرًا ما تشرح الصورة الكاملة لسبب اختلاف السلوك بين الاختبار اليدوي والـ runner.
يتطلب فهم هذا فهمًا لتسلسل هرمية نطاق المتغيرات في Postman. بمجرد أن تراها بوضوح، يكون الإصلاح مباشرًا.
التسلسل الهرمي لنطاق المتغيرات في Postman
لدى Postman خمسة نطاقات للمتغيرات، مدرجة من الأعلى إلى الأقل أولوية:
- المتغيرات المحلية (Local variables) – متاحة فقط ضمن تنفيذ السكربت الحالي، ولا يمكن الوصول إليها عبر الطلبات.
- متغيرات البيانات (Data variables) – يتم تحميلها من ملف CSV أو JSON للتشغيل المعتمد على البيانات.
- متغيرات المجموعة (Collection variables) – نطاقها مخصص للمجموعة، وتستمر عبر الطلبات في تلك المجموعة.
- متغيرات البيئة (Environment variables) – نطاقها مخصص للبيئة المحددة، وتستمر عبر المجموعات.
- المتغيرات الشاملة (Global variables) – متاحة في أي مجموعة وفي أي بيئة.
عندما يحل Postman مرجع متغير مثل {{token}}، فإنه يتتبع هذه القائمة ويستخدم أول تطابق يجده.
المشكلة هي أن "الاستمرارية" تعني أشياء مختلفة اعتمادًا على كيفية تشغيلك للمجموعة.
لماذا تختفي المتغيرات في Collection Runner
التمييز بين القيمة الحالية والقيمة الأولية
يحتوي كل متغير في Postman على حقلين: "القيمة الأولية" (initial value) و"القيمة الحالية" (current value).
- القيمة الأولية (Initial value) تتم مزامنتها مع سحابة Postman ومشاركتها مع الزملاء.
- القيمة الحالية (Current value) محلية لجهازك ولا تتم مزامنتها أبدًا.
عندما تقوم بتعيين متغير برمجيًا في سكربت باستخدام pm.environment.set('token', value)، يقوم Postman بتحديث القيمة الحالية في بيئتك النشطة.
في وضع الاختبار اليدوي، يعمل هذا كما هو متوقع لأن قيمك المحلية الحالية تستمر عبر عمليات تنفيذ الطلبات الفردية ضمن نفس الجلسة.
في Collection Runner، يتغير السلوك. يبدأ الـ runner كل تشغيل من الحالة الحالية للبيئة عند بدء التشغيل. تعمل السكربتات التي تحدث المتغيرات أثناء التشغيل بشكل صحيح ضمن ذلك التشغيل. ولكن إذا تم تكوين الـ runner لمسح المتغيرات بين عمليات التشغيل، أو إذا كانت القيمة الأولية فارغة واستخدم الـ runner لقطة بيئة جديدة، فقد ينتهي بك الأمر إلى حالة يعمل فيها السكربت الخاص بك ولكن المتغير لا يبدو مستمرًا.
مشكلة متغير البيئة مقابل متغير المجموعة
إليك الفخ الأكثر شيوعًا. أنت تقوم بتعيين متغير في سكربت ما بعد الاستجابة:
pm.environment.set('token', pm.response.json().access_token);
يقوم هذا بتعيين متغير في البيئة النشطة. لكن Collection Runner لديه خيار يسمى "الاحتفاظ بقيم المتغيرات" (Keep variable values). إذا كان هذا المربع غير محدد (افتراضيًا يكون غير محدد)، فإن الـ runner يعيد ضبط متغيرات البيئة إلى قيمها الأولية بعد التشغيل. يتم التخلص من أي قيمة تم تعيينها أثناء التشغيل.
إذا كنت تقوم بتشغيل المجموعة دون تحديد بيئة، فإن pm.environment.set يفشل بصمت. لا توجد بيئة للكتابة إليها. يختفي المتغير.
عدم تطابق النطاق بين الوضع اليدوي ووضع الـ Runner
في الاختبار اليدوي، عادة ما تكون لديك بيئة مختارة وتستمر عبر جلسة Postman بأكملها. عندما تقوم بتشغيل طلب، وتعيين متغير، وتشغيل طلب آخر، تحدث جميعها في نفس سياق البيئة المستمر.
ينشئ Collection Runner سياق تنفيذ منفصلًا. يقوم بتحميل حالة البيئة في البداية، ويشغل جميع الطلبات، ثم (ما لم تقم بتحديد "الاحتفاظ بقيم المتغيرات") يعيد البيئة إلى حالتها قبل التشغيل.
هذا يعني أن المتغيرات التي تم تعيينها بواسطة طلب واحد في الـ runner تكون متاحة للطلبات اللاحقة في نفس التشغيل، لكنها لا تستمر في لوحة البيئة الخاصة بك بعد انتهاء التشغيل ما لم تحتفظ بها صراحةً.
الإصلاحات
الإصلاح 1: تحديد "الاحتفاظ بقيم المتغيرات" في الـ runner
في Collection Runner، قبل النقر على تشغيل:
- ابحث عن خيار "الاحتفاظ بقيم المتغيرات" (Keep variable values) في لوحة إعدادات الـ runner.
- حدد هذا المربع.
يخبر هذا الـ runner بكتابة أي تغييرات على المتغيرات مرة أخرى إلى بيئتك النشطة بعد اكتمال التشغيل. ستكون المتغيرات التي تم تعيينها بواسطة السكربتات أثناء التشغيل مرئية في لوحة البيئة الخاصة بك عند انتهاء التشغيل.
متى تستخدم هذا: عندما تريد أن يقوم الـ runner بتحديث الحالة المشتركة، مثل تحديث رمز مصادقة (auth token) ستستخدمه أدوات أخرى أو عمليات تشغيل لاحقة.
متى لا تستخدم هذا: عندما تقوم بتشغيل عدة تكرارات وستؤدي المتغيرات التي تم تعيينها في التكرار الأول إلى تلويث التكرار الثاني. في هذه الحالة، استخدم ملفات البيانات أو أعد تعيين المتغيرات صراحةً في بداية كل تكرار.
الإصلاح 2: استخدام متغيرات المجموعة بدلاً من متغيرات البيئة للحالة داخل التشغيل
إذا كان المتغير يحتاج فقط إلى المشاركة بين الطلبات ضمن تشغيل المجموعة نفسه، استخدم متغيرات المجموعة بدلاً من متغيرات البيئة:
// في سكربت ما بعد الاستجابة لطلب تسجيل الدخول الخاص بك:
pm.collectionVariables.set('token', pm.response.json().access_token);
// في سكربت ما قبل الطلب للطلبات اللاحقة:
const token = pm.collectionVariables.get('token');
تكون متغيرات المجموعة متاحة دائمًا في الـ runner بغض النظر عما إذا كانت البيئة مختارة أم لا. تستمر طوال مدة تشغيل المجموعة. إنها النطاق الصحيح للقيم التي يتم تعيينها واستهلاكها ضمن مجموعة واحدة.
الإصلاح 3: التأكد من تحديد بيئة قبل التشغيل
يفشل pm.environment.set بصمت عندما لا تكون هناك بيئة نشطة. قبل تشغيل المجموعة:
- افتح Collection Runner.
- تحقق من تحديد بيئة في القائمة المنسدلة "البيئة".
- إذا لم تكن بحاجة إلى متغيرات على مستوى البيئة، استخدم متغيرات المجموعة بدلاً من ذلك (الإصلاح 2).
الإصلاح 4: استخدام القيم الأولية للمتغيرات التي يجب أن تكون موجودة دائمًا
إذا كان متغير مثل baseUrl يحتاج إلى أن يكون متاحًا من أول طلب في التشغيل، فقم بتعيينه كقيمة أولية في بيئتك، وليس فقط القيمة الحالية.
في محرر البيئة:
- عيّن حقل "القيمة الأولية" (Initial value)، وليس فقط حقل "القيمة الحالية" (Current value).
- القيمة الأولية هي ما يستخدمه الـ runner كحالة بدء.
إذا تم تعيين القيمة الحالية فقط ولم يتمكن الـ runner من الوصول إلى قيمك المحلية الحالية (على سبيل المثال، زميل يقوم بتشغيل المجموعة، أو تشغيل Newman/Apidog CLI)، يبدأ المتغير فارغًا.
الإصلاح 5: التصحيح باستخدام تسجيل وحدة التحكم
أضف console.log إلى سكربتات ما قبل الطلب وما بعد الاستجابة لترى بالضبط ما يحدث:
// سكربت ما قبل الطلب
console.log('الرمز المميز قبل الطلب:', pm.collectionVariables.get('token'));
console.log('رمز البيئة المميز:', pm.environment.get('token'));
افتح وحدة تحكم Postman (عرض > إظهار وحدة تحكم Postman) قبل تشغيل المجموعة. ستوضح لك السجلات بالضبط من أي نطاق تتم قراءة كل متغير وما هي القيمة التي يحملها في كل خطوة.
كيف يتعامل Apidog مع نطاق المتغيرات
يستخدم Apidog نفس التسلسل الهرمي للنطاق: شامل، بيئة، مجموعة، ومحلي. الفرق الرئيسي يكمن في واجهة المستخدم.
في محرر المتغيرات الخاص بـ Apidog، يتم عرض القيم الأولية والحالية بملصقات وألوان واضحة. تجعل الواجهة من الصعب تعيين القيمة الحالية فقط عن طريق الخطأ. عندما يقوم سكربت بتعيين متغير باستخدام pm.environment.set (الذي يدعمه Apidog لتوافق Postman)، يتم تحديث لوحة البيئة بصريًا في الوقت الفعلي حتى تتمكن من رؤية التغيير يحدث.
لا يقوم مشغل الاختبار في Apidog أيضًا بإعادة تعيين قيم المتغيرات بين الخطوات إلا إذا قمت بتكوينه صراحةً للقيام بذلك. السلوك الافتراضي هو الحفاظ على حالة المتغيرات عبر الطلبات في التشغيل، وهو ما يتوافق مع ما يتوقعه معظم المطورين من الاختبار اليدوي.
بالنسبة لسيناريوهات الفرق، فإن نموذج Apidog الذي يعتمد على المحلية أولاً يعني أن متغيرات البيئة يتم تخزينها على القرص. لا توجد مزامنة سحابية تقوم بالكتابة فوق قيمك الحالية بين عمليات التشغيل.
ملخص الأخطاء الشائعة
| الخطأ | العرض/المشكلة | الإصلاح |
|---|---|---|
| لم يتم تحديد بيئة | يفشل pm.environment.set بصمت |
حدد بيئة أو استخدم متغيرات المجموعة |
| تم تعيين القيمة الحالية فقط | المتغير مفقود في CI أو على جهاز الزميل | قم بتعيين القيمة الأولية في محرر البيئة |
| لم يتم تحديد "الاحتفاظ بقيم المتغيرات" | يتم إعادة تعيين المتغيرات بعد اكتمال الـ runner | حدد "الاحتفاظ بقيم المتغيرات" في إعدادات الـ runner |
| استخدام متغيرات البيئة للحالة داخل التشغيل | يعمل في الوضع اليدوي، ويفشل في الـ runner | انتقل إلى استخدام pm.collectionVariables.set |
| التحقق من النطاق الخاطئ في السجلات | المتغير موجود ولكن تم استخدام قيمة خاطئة | سجل كلا النطاقين وتحقق من أولوية الحل |
الأسئلة الشائعة
لماذا يعمل pm.environment.set في الوضع اليدوي ولكن ليس في الـ runner؟ في الوضع اليدوي، لديك جلسة بيئة مستمرة. في الـ runner، يتم تحميل البيئة في بداية التشغيل وإعادة ضبطها افتراضيًا في النهاية. تظل السكربتات التي تعين المتغيرات أثناء التشغيل تعمل للطلبات اللاحقة في ذلك التشغيل، لكن التغييرات لا تستمر في بيئتك ما لم يتم تحديد "الاحتفاظ بقيم المتغيرات".
ما الفرق بين pm.environment.set وpm.collectionVariables.set؟ يكتب pm.environment.set إلى البيئة النشطة، والتي يتم مشاركتها عبر جميع المجموعات التي تستخدم تلك البيئة. يكتب pm.collectionVariables.set إلى نطاق مرتبط بالمجموعة المحددة. بالنسبة للقيم التي تهم فقط ضمن تشغيل مجموعة واحدة، تكون متغيرات المجموعة أكثر ملاءمة ولا تتطلب تحديد بيئة.
هل تحدث هذه المشكلة في Newman؟ نعم. لدى Newman نفس نموذج النطاق. افتراضيًا، يبدأ Newman كل تشغيل بالقيم الأولية للبيئة المصدرة ولا يحتفظ بالتغييرات بعد التشغيل ما لم تستخدم علامة --export-environment لكتابة حالة البيئة النهائية إلى ملف.
ما هي علامة --export-environment في Newman؟ تخبر Newman بكتابة الحالة النهائية للبيئة، بما في ذلك أي قيم تم تعيينها بواسطة السكربتات أثناء التشغيل، إلى ملف JSON بعد اكتمال التشغيل. يمكنك بعد ذلك تمرير هذا الملف كبيئة للتشغيل التالي. هذا مفيد لخطوط الأنابيب حيث يقوم تشغيل واحد بتوليد رموز مميزة تستخدمها التشغيل التالي.
هل يدعم Apidog pm.collectionVariables.set؟ نعم. يدعم Apidog واجهة برمجة تطبيقات السكربتات الكاملة لـ Postman، بما في ذلك pm.collectionVariables.set وpm.collectionVariables.get وpm.environment.set وpm.environment.get. تستخدم المجموعات التي تم ترحيلها من Postman نفس بناء جملة السكربت.
كيف أمرر المتغيرات من مجموعة إلى أخرى في Postman؟ استخدم المتغيرات الشاملة: pm.globals.set('token', value). تستمر المتغيرات الشاملة عبر المجموعات والبيئات طوال فترة جلسة Postman. كن حذرًا مع هذا النهج في إعدادات الفريق نظرًا لأن المتغيرات الشاملة ليست ذات نطاق ويمكن أن تتسبب في تعارضات بالأسماء.
تعد مشاكل نطاق المتغيرات في Postman أحد أكثر المصادر الموثوقة للنتائج السلبية الكاذبة في مجموعات اختبار واجهات برمجة التطبيقات (API). الاختبار الذي ينجح يدويًا ولكنه يفشل في الـ runner ليس اختبارًا يمكنك الوثوق به. فهم نموذج النطاق، واستخدام المعين الصحيح للسياق الصحيح، وتحديد "الاحتفاظ بقيم المتغيرات" عند الاقتضاء هي الحركات الثلاث التي تحل معظم هذه المشاكل.
