أفضل ممارسات اختبار TensorFlow

هذه هي الممارسات الموصى بها لاختبار التعليمات البرمجية في مستودع TensorFlow .

قبل أن تبدأ

قبل المساهمة بالكود المصدري لمشروع TensorFlow، يرجى مراجعة ملف CONTRIBUTING.md في مستودع GitHub الخاص بالمشروع. (على سبيل المثال، راجع ملف CONTRIBUTING.md للحصول على مستودع TensorFlow الأساسي .) يُطلب من جميع المساهمين في التعليمات البرمجية التوقيع على اتفاقية ترخيص المساهمين (CLA).

المبادئ العامة

تعتمد فقط على ما تستخدمه في قواعد BUILD الخاصة بك

TensorFlow عبارة عن مكتبة كبيرة، وكان الاعتماد على الحزمة الكاملة عند كتابة اختبار الوحدة لوحداتها الفرعية ممارسة شائعة. ومع ذلك، يؤدي هذا إلى تعطيل التحليل المستند إلى تبعية bazel . وهذا يعني أن أنظمة التكامل المستمر لا يمكنها التخلص بذكاء من الاختبارات غير ذات الصلة لعمليات الإرسال المسبق/بعد الإرسال. إذا كنت تعتمد فقط على الوحدات الفرعية التي تختبرها في ملف BUILD الخاص بك، فسوف توفر الوقت لجميع مطوري TensorFlow، والكثير من قوة الحساب القيمة.

ومع ذلك، فإن تعديل تبعية البناء الخاص بك لحذف أهداف TF الكاملة يجلب بعض القيود على ما يمكنك استيراده في كود Python الخاص بك. لن تتمكن من استخدام import tensorflow as tf في اختبارات وحدتك بعد الآن. لكن هذه مقايضة جديرة بالاهتمام لأنها توفر على جميع المطورين من إجراء آلاف الاختبارات غير الضرورية.

يجب أن تحتوي جميع التعليمات البرمجية على اختبارات الوحدة

بالنسبة لأي كود تكتبه، يجب عليك أيضًا كتابة اختبارات الوحدة الخاصة به. إذا كتبت ملفًا جديدًا foo.py ، فيجب عليك إجراء اختبارات الوحدة الخاصة به في foo_test.py وإرساله ضمن نفس التغيير. اهدف إلى الحصول على تغطية اختبارية تزايدية بنسبة تزيد عن 90% لجميع التعليمات البرمجية الخاصة بك.

تجنب استخدام قواعد اختبار بازل الأصلية في TF

لدى TF الكثير من التفاصيل الدقيقة عند إجراء الاختبارات. لقد عملنا على إخفاء كل تلك التعقيدات في وحدات الماكرو الخاصة بنا. لتجنب الاضطرار إلى التعامل مع هذه الأمور، استخدم ما يلي بدلاً من قواعد الاختبار الأصلية. لاحظ أن كل هذه الأمور محددة في tensorflow/tensorflow.bzl بالنسبة لاختبارات CC، استخدم tf_cc_test و tf_gpu_cc_test و tf_gpu_only_cc_test . بالنسبة لاختبارات بايثون، استخدم tf_py_test أو gpu_py_test . إذا كنت بحاجة إلى شيء قريب حقًا من قاعدة py_test الأصلية، فيرجى استخدام القاعدة المحددة في Tensorflow.bzl بدلاً من ذلك. تحتاج فقط إلى إضافة السطر التالي في أعلى ملف BUILD: load(“tensorflow/tensorflow.bzl”, “py_test”)

كن على علم بمكان تنفيذ الاختبار

عندما تكتب اختبارًا، يمكن أن تعتني الأشعة تحت الحمراء للاختبار لدينا بتشغيل اختباراتك على وحدة المعالجة المركزية (CPU) ووحدة معالجة الرسومات (GPU) والمسرعات إذا كتبتها وفقًا لذلك. لدينا اختبارات تلقائية تعمل على أنظمة Linux، وmacos، وWindows، التي تحتوي على أنظمة تحتوي على وحدات معالجة الرسومات أو لا تحتوي عليها. كل ما عليك فعله هو اختيار إحدى وحدات الماكرو المذكورة أعلاه، ثم استخدام العلامات لتحديد مكان تنفيذها.

  • ستستبعد العلامة manual اختبارك من التشغيل في أي مكان. يتضمن ذلك عمليات تنفيذ الاختبار اليدوية التي تستخدم أنماطًا مثل bazel test tensorflow/…

  • سوف يقوم no_oss باستبعاد اختبارك من التشغيل في البنية التحتية الرسمية لاختبار TF OSS.

  • يمكن استخدام علامات no_mac أو no_windows لاستبعاد الاختبار الخاص بك من مجموعات اختبار نظام التشغيل ذات الصلة.

  • يمكن استخدام علامة no_gpu لاستبعاد اختبارك من التشغيل في مجموعات اختبار GPU.

التحقق من تشغيل الاختبارات في مجموعات الاختبار المتوقعة

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

  • انتظر حتى يتم تشغيل عمليات الإرسال المسبق الخاصة بك على طلب السحب (PR) حتى الاكتمال.
  • قم بالتمرير إلى أسفل PR الخاص بك لرؤية عمليات التحقق من الحالة.
  • انقر فوق رابط "التفاصيل" الموجود على الجانب الأيمن من أي فحص لـ Kokoro.
  • تحقق من قائمة "الأهداف" للعثور على أهدافك المضافة حديثًا.

يجب أن يكون لكل فئة/وحدة ملف اختبار الوحدة الخاص بها

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

السرعة وأوقات التشغيل

يجب استخدام التقسيم بأقل قدر ممكن

بدلاً من المشاركة، يرجى مراعاة ما يلي:

  • جعل اختباراتك أصغر
  • إذا لم يكن ما سبق ممكنا، قم بتقسيم الاختبارات

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

الاختبارات الأصغر هي الأفضل

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

  • قم بتشغيل تكرارات أقل للتدريب في الاختبار الخاص بك
  • فكر في استخدام حقن التبعيات لاستبدال التبعيات الثقيلة للنظام قيد الاختبار بأخرى مزيفة بسيطة.
  • فكر في استخدام بيانات إدخال أصغر في اختبارات الوحدة
  • إذا لم ينجح أي شيء آخر، فحاول تقسيم ملف الاختبار الخاص بك.

يجب أن تهدف أوقات الاختبار إلى نصف مهلة حجم الاختبار لتجنب الرقائق

بالنسبة لأهداف اختبار bazel ، فإن الاختبارات الصغيرة لها مهلة مدتها دقيقة واحدة. مهلة الاختبار المتوسطة هي 5 دقائق. لا يتم تنفيذ الاختبارات الكبيرة بواسطة اختبار TensorFlow بالأشعة تحت الحمراء. ومع ذلك، فإن العديد من الاختبارات لا تحدد مقدار الوقت الذي تستغرقه. لأسباب مختلفة، قد تستغرق اختباراتك وقتًا أطول بين الحين والآخر. وإذا قمت بوضع علامة على اختبار يتم تشغيله لمدة 50 ثانية في المتوسط ​​على أنه صغير، فسوف يتكسر اختبارك إذا تمت جدولته على جهاز مزود بوحدة معالجة مركزية قديمة. لذلك، استهدف أن يكون متوسط ​​وقت التشغيل 30 ثانية للاختبارات الصغيرة. استهدف دقيقتين و30 ثانية من متوسط ​​وقت التشغيل للاختبارات المتوسطة.

تقليل عدد العينات وزيادة التحمل للتدريب

اختبارات التشغيل البطيئة تمنع المساهمين. يمكن أن يكون التدريب على الاختبارات بطيئًا جدًا. تفضل التفاوتات الأعلى لتتمكن من استخدام عينات أقل في اختباراتك للحفاظ على سرعة اختباراتك بشكل كافٍ (2.5 دقيقة كحد أقصى).

القضاء على عدم الحتمية والرقائق

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

يجب أن تكون اختبارات الوحدة دائمًا حتمية. يجب إجراء جميع الاختبارات التي يتم إجراؤها على TAP والغيتار بنفس الطريقة في كل مرة، إذا لم يكن هناك تغيير في الكود يؤثر عليها. ولضمان ذلك، فيما يلي بعض النقاط التي يجب مراعاتها.

دائما زرع أي مصدر من مصادر العشوائية

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

# Python RNG
import random
random.seed(42)

# Numpy RNG
import numpy as np
np.random.seed(42)

# TF RNG
from tensorflow.python.framework import random_seed
random_seed.set_seed(42)

تجنب استخدام sleep في الاختبارات ذات مؤشرات الترابط المتعددة

يمكن أن يكون استخدام وظيفة sleep في الاختبارات سببًا رئيسيًا للتقشر. خاصة عند استخدام سلاسل رسائل متعددة، فإن استخدام السكون لانتظار خيط آخر لن يكون محددًا أبدًا. ويرجع ذلك إلى عدم قدرة النظام على ضمان أي ترتيب لتنفيذ مؤشرات الترابط أو العمليات المختلفة. ولذلك، تفضل بنيات التزامن الحتمية مثل كائنات المزامنة.

تحقق مما إذا كان الاختبار قشاريًا

تتسبب الرقائق في خسارة عمال البناء والمطورين لساعات عديدة. من الصعب اكتشافها، ومن الصعب تصحيحها. على الرغم من وجود أنظمة آلية للكشف عن نقاط الضعف، إلا أنها تحتاج إلى تجميع المئات من عمليات التشغيل الاختبارية قبل أن تتمكن من وضع الاختبارات في القائمة المرفوضة بدقة. حتى عندما يكتشفون ذلك، فإنهم يرفضون اختباراتك ويتم فقدان تغطية الاختبار. لذلك، يجب على مؤلفي الاختبار التحقق مما إذا كانت اختباراتهم غير مستقرة عند كتابة الاختبارات. يمكن القيام بذلك بسهولة عن طريق تشغيل الاختبار باستخدام العلامة: --runs_per_test=1000

استخدم TensorFlowTestCase

يتخذ TensorFlowTestCase الاحتياطات اللازمة مثل زرع جميع مولدات الأرقام العشوائية المستخدمة لتقليل التقشر قدر الإمكان. عندما نكتشف المزيد من مصادر التقشر ونصلحها، ستتم إضافتها جميعًا إلى TensorFlowTestCase. لذلك، يجب عليك استخدام TensorFlowTestCase عند كتابة اختبارات Tensorflow. يتم تعريف TensorFlowTestCase هنا: tensorflow/python/framework/test_util.py

اكتب الاختبارات المحكمه

الاختبارات المحكمه لا تحتاج إلى أي موارد خارجية. إنهم مليئون بكل ما يحتاجون إليه، ويبدأون فقط في تقديم أي خدمات وهمية قد يحتاجون إليها. أي خدمات أخرى غير اختباراتك هي مصادر لعدم الحتمية. حتى مع توفر الخدمات الأخرى بنسبة 99%، يمكن أن تتدهور الشبكة، ويمكن أن تتأخر استجابة RPC، وقد ينتهي بك الأمر بظهور رسالة خطأ لا يمكن تفسيرها. قد تكون الخدمات الخارجية، على سبيل المثال لا الحصر، GCS أو S3 أو أي موقع ويب.