TensorFlow en iyi uygulamaları test ediyor

Bunlar TensorFlow deposundaki kodu test etmek için önerilen uygulamalardır.

Başlamadan önce

Bir TensorFlow projesine kaynak koduyla katkıda bulunmadan önce lütfen projenin GitHub deposundaki CONTRIBUTING.md dosyasını inceleyin. (Örneğin, temel TensorFlow deposu için CONTRIBUTING.md dosyasına bakın.) Tüm kod katılımcılarının bir Katılımcı Lisans Sözleşmesi (CLA) imzalaması gerekir.

Genel İlkeler

Yalnızca BUILD kurallarınızda ne kullandığınıza bağlıdır

TensorFlow büyük bir kütüphanedir ve tam pakete bağlı olarak alt modülleri için birim testi yazarken yaygın bir uygulama olmuştur. Ancak bu, bazel bağımlılığına dayalı analizi devre dışı bırakır. Bu, sürekli entegrasyon sistemlerinin gönderim öncesi/gönderim sonrası çalıştırmalar için ilgisiz testleri akıllı bir şekilde ortadan kaldıramayacağı anlamına gelir. Yalnızca BUILD dosyanızda test ettiğiniz alt modüllere bağlıysanız, tüm TensorFlow geliştiricileri için zamandan ve çok sayıda değerli hesaplama gücünden tasarruf edeceksiniz.

Ancak derleme bağımlılığınızı tam TF hedeflerini atlayacak şekilde değiştirmek, Python kodunuzda içe aktarabilecekleriniz konusunda bazı sınırlamalar getirir. Artık birim testlerinizde import tensorflow as tf kullanamayacaksınız. Ancak bu, tüm geliştiricileri binlerce gereksiz test yapmaktan kurtardığı için değerli bir ödündür.

Tüm kodlarda birim testleri bulunmalıdır

Yazdığınız herhangi bir kod için birim testlerini de yazmalısınız. Yeni bir foo.py dosyası yazarsanız, birim testlerini foo_test.py dosyasına yerleştirmeli ve aynı değişiklik içerisinde göndermelisiniz. Kodunuzun tamamı için %90'ın üzerinde artımlı test kapsamı hedefleyin.

TF'de yerel bazel test kurallarını kullanmaktan kaçının

TF'nin testleri çalıştırırken birçok inceliği vardır. Bazel makrolarımızda tüm bu karmaşıklıkları gizlemeye çalıştık. Bunlarla uğraşmamak için yerel test kuralları yerine aşağıdakileri kullanın. Bunların hepsinin tensorflow/tensorflow.bzl tanımlandığına dikkat edin. CC testleri için tf_cc_test , tf_gpu_cc_test , tf_gpu_only_cc_test kullanın. Python testleri için tf_py_test veya gpu_py_test kullanın. Yerel py_test kuralına gerçekten yakın bir şeye ihtiyacınız varsa lütfen bunun yerine tensorflow.bzl'de tanımlanan kuralı kullanın. BUILD dosyasının en üstüne şu satırı eklemeniz yeterli: load(“tensorflow/tensorflow.bzl”, “py_test”)

Testin nerede yürütüldüğünü bilin

Bir test yazdığınızda, test altyapımız, uygun şekilde yazmanız halinde testlerinizi CPU, GPU ve hızlandırıcılar üzerinde çalıştırmayla ilgilenebilir. GPU'lu veya GPU'suz sistemlere sahip Linux, macOS, Windows üzerinde çalışan otomatik testlerimiz var. Yukarıda listelenen makrolardan birini seçmeniz ve ardından yürütüldükleri yeri sınırlamak için etiketleri kullanmanız yeterlidir.

  • manual etiket, testinizin herhangi bir yerde çalışmasını engelleyecektir. Bu bazel test tensorflow/… gibi modelleri kullanan manuel test yürütmelerini içerir.

  • no_oss testinizin resmi TF OSS test altyapısında çalışmasını engelleyecektir.

  • no_mac veya no_windows etiketleri, testinizi ilgili işletim sistemi test paketlerinden hariç tutmak için kullanılabilir.

  • no_gpu etiketi, testinizin GPU test paketlerinde çalışmasını engellemek için kullanılabilir.

Beklenen test paketlerinde çalıştırılan testlerin doğrulanması

TF'nin epeyce test paketi var. Bazen kurulumu kafa karıştırıcı olabilir. Testlerinizin sürekli derlemelerden çıkarılmasına neden olan farklı sorunlar olabilir. Bu nedenle testlerinizin beklendiği gibi yürütüldüğünü doğrulamanız gerekir. Bunu yapmak için:

  • Çekme İsteğinizdeki (PR) ön gönderimlerinizin tamamlanmasını bekleyin.
  • Durum kontrollerini görmek için PR'ınızın alt kısmına doğru kaydırın.
  • Herhangi bir Kokoro çekinin sağ tarafındaki "Ayrıntılar" bağlantısını tıklayın.
  • Yeni eklenen hedeflerinizi bulmak için “Hedefler” listesini kontrol edin.

Her sınıf/ünitenin kendi ünite test dosyası olmalıdır

Ayrı test sınıfları, arızaları ve kaynakları daha iyi izole etmemize yardımcı olur. Test dosyalarının çok daha kısa ve okunması daha kolay olmasını sağlarlar. Bu nedenle, tüm Python dosyalarınızda en az bir karşılık gelen test dosyası bulunmalıdır (Her foo.py için foo_test.py bulunmalıdır). Farklı kurulumlar gerektiren entegrasyon testleri gibi daha ayrıntılı testler için daha fazla test dosyası eklemek uygundur.

Hız ve çalışma süreleri

Parçalama mümkün olduğunca az kullanılmalıdır

Parçalamak yerine lütfen şunları göz önünde bulundurun:

  • Testlerinizi küçültme
  • Yukarıdakiler mümkün değilse testleri bölün

Parçalama, bir testin genel gecikmesinin azaltılmasına yardımcı olur ancak aynı şey, testleri daha küçük hedeflere bölerek de başarılabilir. Testleri bölmek bize her testte daha iyi bir kontrol düzeyi sağlar, gereksiz ön gönderim işlemlerini en aza indirir ve yanlış davranan bir test durumu nedeniyle tüm hedefi devre dışı bırakan bir yapı polisinin kapsam kaybını azaltır. Üstelik parçalama, tüm parçalar için tüm test başlatma kodunu çalıştırmak gibi çok açık olmayan gizli maliyetlere neden olur. Bu konu ekstra yük yaratan bir kaynak olarak alt ekipler tarafından tarafımıza iletilmiştir.

Küçük testler daha iyidir

Testleriniz ne kadar hızlı yapılırsa insanların testlerinizi yapma olasılığı da o kadar artar. Testiniz için fazladan bir saniye, geliştiricilerin ve altyapımızın testinizi yürütmek için harcadığı ekstra zamanın saatlerce artmasına neden olabilir. Testlerinizin 30 saniyenin altında çalışmasını sağlayın (isteğe bağlı olmayan modda!) ve bunları küçük yapın. Testlerinizi yalnızca son çare olarak orta olarak işaretleyin. Infra, ön gönderim veya son gönderim olarak büyük testler yürütmez! Bu nedenle, yalnızca nerede çalışacağını ayarlayacaksanız büyük bir test yazın. Testlerin daha hızlı çalışmasını sağlayacak bazı ipuçları:

  • Testinizde daha az eğitim yinelemesi çalıştırın
  • Test edilen sistemin ağır bağımlılıklarını basit sahtekarlıklarla değiştirmek için bağımlılık enjeksiyonunu kullanmayı düşünün.
  • Birim testlerinde daha küçük girdi verileri kullanmayı düşünün
  • Başka hiçbir şey işe yaramazsa test dosyanızı bölmeyi deneyin.

Pullanmayı önlemek için test süreleri, test boyutu zaman aşımının yarısını hedeflemelidir

bazel test hedefleriyle küçük testlerin 1 dakikalık zaman aşımı vardır. Orta test zaman aşımları 5 dakikadır. Büyük testler TensorFlow test altyapısı tarafından gerçekleştirilmez. Ancak çoğu test, harcadıkları süre açısından belirleyici değildir. Çeşitli nedenlerden dolayı testleriniz ara sıra daha fazla zaman alabilir. Ortalama 50 saniye boyunca çalışan bir testi küçük olarak işaretlerseniz, testiniz eski CPU'lu bir makinede zamanlanırsa başarısız olur. Bu nedenle küçük testler için ortalama 30 saniyelik çalışma süresini hedefleyin. Orta seviye testler için 2 dakika 30 saniyelik ortalama çalışma süresini hedefleyin.

Örnek sayısını azaltın ve eğitim toleranslarını artırın

Yavaş çalışan testler katkıda bulunanları caydırır. Testlerde eğitimin yürütülmesi çok yavaş olabilir. Testlerinizi yeterince hızlı tutabilmek için (maksimum 2,5 dakika) testlerinizde daha az numune kullanabilmek için daha yüksek toleransları tercih edin.

Determinizmi ve pulları ortadan kaldırın

Deterministik testler yazın

Birim testleri her zaman deterministik olmalıdır. TAP ve gitar üzerinde çalışan tüm testler, eğer onları etkileyen bir kod değişikliği yoksa, her seferinde aynı şekilde çalışmalıdır. Bunu sağlamak için aşağıda dikkate alınması gereken bazı noktalar verilmiştir.

Her zaman herhangi bir stokastisite kaynağını tohumlayın

Herhangi bir rastgele sayı üreteci veya başka herhangi bir stokastiklik kaynağı, düzensizliğe neden olabilir. Bu nedenle bunların her birinin tohumlanması gerekir. Bu, testleri daha az hatalı hale getirmenin yanı sıra tüm testleri tekrarlanabilir hale getirir. TF testlerinde ayarlamanız gerekebilecek bazı tohumları ayarlamanın farklı yolları şunlardır:

# 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)

Çok iş parçacıklı testlerde sleep kullanmaktan kaçının

Testlerde sleep fonksiyonunun kullanılması pullanmanın önemli bir nedeni olabilir. Özellikle birden fazla iş parçacığı kullanıldığında, başka bir iş parçacığını beklemek için uykuyu kullanmak hiçbir zaman belirleyici olmayacaktır. Bunun nedeni, sistemin farklı iş parçacıklarının veya süreçlerin yürütülmesi sırasını garanti edememesidir. Bu nedenle muteksler gibi deterministik senkronizasyon yapılarını tercih edin.

Testin pul pul olup olmadığını kontrol edin

Pullar inşaat polislerinin ve geliştiricilerin saatlerce kaybetmesine neden olur. Tespit edilmeleri zordur ve hata ayıklamaları zordur. Kesintiyi tespit edecek otomatik sistemler olsa da, testleri doğru bir şekilde reddedilenler listesine ekleyebilmeleri için yüzlerce test çalışmasını biriktirmeleri gerekir. Tespit ettiklerinde bile testlerinizi red listesine eklerler ve test kapsamı kaybolur. Bu nedenle test yazarları, testleri yazarken testlerinin hatalı olup olmadığını kontrol etmelidir. Bu, testinizi şu bayrakla çalıştırarak kolayca yapılabilir: --runs_per_test=1000

TensorFlowTestCase'i kullanın

TensorFlowTestCase, pullanmayı mümkün olduğu kadar azaltmak için kullanılan tüm rastgele sayı üreteçlerinin tohumlanması gibi gerekli önlemleri alır. Daha fazla pullanma kaynağı keşfedip düzelttikçe bunların hepsi TensorFlowTestCase'e eklenecek. Bu nedenle tensorflow için testler yazarken TensorFlowTestCase'i kullanmalısınız. TensorFlowTestCase burada tanımlanır: tensorflow/python/framework/test_util.py

Hermetik testler yazın

Hermetik testler herhangi bir dış kaynağa ihtiyaç duymaz. İhtiyaç duydukları her şeyle dolular ve ihtiyaç duyabilecekleri her türlü sahte hizmete başlıyorlar. Testleriniz dışındaki tüm hizmetler determinizm dışı kaynaklardır. Diğer hizmetlerin %99 kullanılabilirliği durumunda bile ağ çökebilir, rpc yanıtı gecikebilir ve açıklanamayan bir hata mesajıyla karşılaşabilirsiniz. Dış hizmetler GCS, S3 veya herhangi bir web sitesi olabilir ancak bunlarla sınırlı değildir.