بهترین روش های تست TensorFlow

اینها روش های توصیه شده برای آزمایش کد در مخزن TensorFlow هستند.

قبل از اینکه شروع کنید

قبل از اینکه کد منبع را به پروژه TensorFlow کمک کنید، لطفاً فایل CONTRIBUTING.md را در مخزن GitHub پروژه مرور کنید. (به عنوان مثال، فایل CONTRIBUTING.md را برای مخزن اصلی TensorFlow ببینید.) همه مشارکت کنندگان کد ملزم به امضای قرارداد مجوز مشارکت (CLA) هستند.

اصول کلی

فقط به آنچه در قوانین BUILD خود استفاده می کنید بستگی دارد

TensorFlow یک کتابخانه بزرگ است، و بسته به بسته کامل، هنگام نوشتن یک آزمون واحد برای زیر ماژول های آن، یک روش معمول بوده است. با این حال، این تجزیه و تحلیل مبتنی بر وابستگی bazel را غیرفعال می کند. این بدان معناست که سیستم‌های یکپارچه‌سازی پیوسته نمی‌توانند به‌طور هوشمندانه تست‌های نامرتبط را برای اجرای پیش ارسال/پس ارسال حذف کنند. اگر فقط به زیر ماژول هایی که در فایل BUILD خود آزمایش می کنید وابسته باشید، در زمان برای همه توسعه دهندگان TensorFlow و قدرت محاسباتی ارزشمند زیادی صرفه جویی خواهید کرد.

با این حال، تغییر وابستگی ساخت خود برای حذف اهداف TF کامل، محدودیت هایی را برای آنچه می توانید در کد پایتون خود وارد کنید، به همراه دارد. دیگر نمی توانید از دستور 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 و شتاب دهنده ها مراقبت کند، اگر آنها را مطابق با آن بنویسید. ما تست‌های خودکاری داریم که روی لینوکس، macos، ویندوز و دارای سیستم‌هایی با یا بدون GPU اجرا می‌شوند. شما به سادگی باید یکی از ماکروهای ذکر شده در بالا را انتخاب کنید و سپس از برچسب ها برای محدود کردن محل اجرای آنها استفاده کنید.

  • تگ manual تست شما را از اجرا در هر جایی محروم می کند. این شامل اجرای آزمایش دستی است که از الگوهایی مانند bazel test tensorflow/…

  • no_oss تست شما را از اجرا در زیرساخت رسمی تست TF OSS محروم می کند.

  • برچسب‌های no_mac یا no_windows می‌توانند برای حذف تست شما از مجموعه‌های تست سیستم عامل مربوطه استفاده شوند.

  • از تگ no_gpu می‌توان برای حذف آزمایش شما از اجرای مجموعه‌های آزمایشی GPU استفاده کرد.

تأیید کنید که آزمایش‌ها در مجموعه‌های آزمایشی مورد انتظار اجرا می‌شوند

TF چندین مجموعه آزمایشی دارد. گاهی اوقات، ممکن است تنظیم آنها گیج کننده باشد. ممکن است مشکلات مختلفی وجود داشته باشد که باعث شود تست‌های شما از ساخت‌های پیوسته حذف شوند. بنابراین، باید بررسی کنید که آزمایش‌های شما مطابق انتظار اجرا می‌شوند. برای انجام این کار:

  • منتظر بمانید تا پیش‌فرض‌هایتان در درخواست کششی (PR) تا تکمیل شود.
  • برای مشاهده بررسی وضعیت به پایین PR خود بروید.
  • روی پیوند "جزئیات" در سمت راست هر چک Kokoro کلیک کنید.
  • لیست "هدف ها" را بررسی کنید تا اهداف تازه اضافه شده خود را پیدا کنید.

هر کلاس/واحد باید فایل تست واحد خود را داشته باشد

کلاس‌های آزمایشی جداگانه به ما کمک می‌کنند تا شکست‌ها و منابع را بهتر جدا کنیم. آنها منجر به خواندن فایل های آزمایشی بسیار کوتاه تر و آسان تر می شوند. بنابراین، همه فایل‌های پایتون شما باید حداقل یک فایل تست مربوطه داشته باشند (برای هر foo.py ، باید foo_test.py داشته باشد). برای تست‌های دقیق‌تر، مانند تست‌های یکپارچه‌سازی که نیاز به تنظیمات مختلف دارند، اضافه کردن فایل‌های تست بیشتر خوب است.

سرعت و زمان اجرا

شاردینگ باید تا حد امکان کمتر استفاده شود

به جای اشتراک گذاری لطفاً در نظر بگیرید:

  • کوچکتر کردن آزمایشات
  • اگر موارد فوق امکان پذیر نیست، آزمایش ها را تقسیم کنید

Sharding به کاهش تأخیر کلی یک آزمایش کمک می کند، اما همین امر را می توان با تجزیه آزمایش ها به اهداف کوچکتر به دست آورد. تقسیم تست‌ها سطح کنترل دقیق‌تری را بر روی هر تست به ما می‌دهد، اجرای پیش‌ارسال غیرضروری را به حداقل می‌رساند و از دست دادن پوشش ناشی از یک buildcop که کل یک هدف را به دلیل یک کیس آزمایشی بد رفتار غیرفعال می‌کند، کاهش می‌دهد. علاوه بر این، اشتراک گذاری هزینه های پنهانی را متحمل می شود که چندان واضح نیستند، مانند اجرای تمام کدهای اولیه آزمایشی برای همه خرده ها. این موضوع توسط تیم های زیرساختی به عنوان منبعی که بار اضافی ایجاد می کند به ما تشدید شده است.

تست های کوچکتر بهتر است

هرچه تست های شما سریعتر اجرا شود، احتمال بیشتری وجود دارد که افراد تست های شما را اجرا کنند. یک ثانیه اضافی برای آزمایش شما می تواند به ساعت ها زمان اضافی صرف شده برای اجرای آزمایش شما توسط توسعه دهندگان و زیرساخت های ما تبدیل شود. سعی کنید تست های خود را کمتر از 30 ثانیه (در حالت غیر انتخابی!) اجرا کنید و آنها را کوچک کنید. تست های خود را فقط به عنوان آخرین راه حل به عنوان متوسط ​​علامت گذاری کنید. Infra هیچ تست بزرگی را به عنوان پیش ارسال یا ارسال ارسال نمی کند! بنابراین، فقط در صورتی که می‌خواهید مکان اجرای آن را مشخص کنید، یک تست بزرگ بنویسید. چند نکته برای سرعت بخشیدن به تست ها:

  • تکرارهای کمتری از آموزش را در آزمون خود اجرا کنید
  • استفاده از تزریق وابستگی را برای جایگزینی وابستگی های سنگین سیستم تحت آزمایش با تقلبی های ساده در نظر بگیرید.
  • استفاده از داده های ورودی کوچکتر را در تست های واحد در نظر بگیرید
  • اگر هیچ چیز دیگری کار نمی کند، سعی کنید فایل آزمایشی خود را تقسیم کنید.

زمان‌های آزمایش باید نیمی از وقفه‌ی زمانی اندازه آزمون را هدف قرار دهند تا از ایجاد تکه‌ها جلوگیری شود

با اهداف تست bazel ، تست های کوچک 1 دقیقه تایم اوت دارند. تایم اوت آزمون متوسط ​​5 دقیقه است. تست های بزرگ فقط توسط تست زیرین TensorFlow اجرا نمی شوند. با این حال، بسیاری از آزمایش‌ها از نظر مدت زمان قطعی نیستند. به دلایل مختلف ممکن است هر از چند گاهی آزمایش های شما زمان بیشتری ببرد. و اگر تستی را که به طور متوسط ​​50 ثانیه اجرا می شود به عنوان کوچک علامت گذاری کنید، اگر روی دستگاهی با CPU قدیمی برنامه ریزی شود، تست شما پوسته پوسته می شود. بنابراین، میانگین زمان اجرای 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 در تست ها می تواند یکی از دلایل اصلی پوسته پوسته شدن باشد. به خصوص در هنگام استفاده از چندین رشته، استفاده از خواب برای منتظر ماندن برای رشته دیگر هرگز قطعی نخواهد بود. این به این دلیل است که سیستم قادر به تضمین هر گونه ترتیب اجرای موضوعات یا فرآیندهای مختلف نیست. بنابراین، ساختارهای همگام سازی قطعی مانند mutexes را ترجیح دهید.

بررسی کنید که آیا تست پوسته پوسته شده است

Flakes باعث می شود که buildcops و توسعه دهندگان ساعت های زیادی را از دست بدهند. شناسایی آنها دشوار است و اشکال زدایی آنها دشوار است. حتی اگر سیستم‌های خودکاری برای تشخیص پوسته پوسته شدن وجود دارد، قبل از اینکه بتوانند آزمایش‌ها را به‌طور دقیق رد کنند، باید صدها آزمایش آزمایشی را جمع آوری کنند. حتی وقتی تشخیص دادند، آزمایش‌های شما را رد می‌کنند و پوشش آزمایشی از بین می‌رود. بنابراین، نویسندگان آزمون باید در هنگام نوشتن تست بررسی کنند که آیا تست های آنها پوسته پوسته است. با اجرای تست خود با پرچم: --runs_per_test=1000 می توان این کار را به راحتی انجام داد

از TensorFlowTestCase استفاده کنید

TensorFlowTestCase اقدامات احتیاطی لازم را انجام می‌دهد، مانند کاشت تمام مولدهای اعداد تصادفی مورد استفاده برای کاهش پوسته پوسته شدن تا حد امکان. همانطور که ما منابع پوسته پوسته شدن بیشتری را کشف و رفع می کنیم، همه آنها به TensorFlowTestCase اضافه می شوند. بنابراین، شما باید از TensorFlowTestCase در هنگام نوشتن تست برای tensorflow استفاده کنید. TensorFlowTestCase در اینجا تعریف می شود: tensorflow/python/framework/test_util.py

تست های هرمتیک را بنویسید

تست های هرمتیک به هیچ منبع خارجی نیاز ندارند. آنها مملو از همه چیزهایی هستند که نیاز دارند، و فقط خدمات جعلی را که ممکن است نیاز داشته باشند راه اندازی می کنند. هر سرویسی غیر از تست های شما منبعی برای عدم قطعیت است. حتی با وجود 99٪ در دسترس بودن سایر خدمات، شبکه ممکن است پوسته پوسته شود، پاسخ rpc ممکن است به تأخیر بیفتد، و ممکن است با یک پیام خطای غیرقابل توضیح مواجه شوید. سرویس‌های خارجی ممکن است GCS، S3 یا هر وب‌سایتی باشد، اما نه محدود به آن.