Django'da birim testi


12

Büyük bir Django projesi için etkili birim testleri yazmakta gerçekten zorlanıyorum. Oldukça iyi bir test kapsamım var, ancak yazdığım testlerin birim testleri değil kesinlikle entegrasyon / kabul testleri olduğunu fark ettim ve uygulamamın etkili bir şekilde test edilmeyen kritik kısımlarım var. Bu en kısa sürede düzeltmek istiyorum.

İşte benim sorunum. Şemam derinden ilişkisel ve çok zaman odaklı, model nesnesime yüksek iç bağlantı ve çok fazla durum sağlıyor. Model yöntemlerimin çoğu zaman aralıklarına göre sorgular ve auto_now_addzaman damgalı alanlarda çok şey oluyor. Öyleyse şöyle görünen bir yöntem alın örneğin:

def summary(self, startTime=None, endTime=None):
    # ... logic to assign a proper start and end time 
    # if none was provided, probably using datetime.now()

    objects = self.related_model_set.manager_method.filter(...)

    return sum(object.key_method(startTime, endTime) for object in objects)

Birisi böyle bir şeyi test etmeye nasıl yaklaşıyor?

İşte şimdiye kadar buradayım. Bana göre birim test amacına argümanlarında alaycı davranışlar verilmeli by key_method, summarydoğru bir sonuç elde etmek için doğru bir şekilde süzülüyor / toplanıyor mu?

Alay datetime.now () yeterince basittir, ancak davranışın geri kalanını nasıl alay edebilirim?

  • Fikstürleri kullanabilirdim, ancak verilerimi oluşturmak için fikstürleri kullanmanın artılarını ve eksilerini duydum (zayıf sürdürülebilirlik benim için eve çarpan bir con).
  • Verilerimi ORM aracılığıyla da kurabilirim, ancak bu sınırlayıcı olabilir, çünkü o zaman ilgili nesneleri de oluşturmam gerekiyor. ORM, auto_now_addalanları manuel olarak karıştırmanıza izin vermez .
  • ORM'yi taklit etmek başka bir seçenektir, ancak yalnızca derinden iç içe ORM yöntemlerini taklit etmek zor değildir, aynı zamanda ORM kodundaki mantık testten alay edilir ve alay etmek, testi gerçekten fonksiyon test altındaki.

Çatlamak için en zor somunlar, birkaç model modeli ve daha düşük seviyeli fonksiyonlara dayanan ve bu fonksiyonlar çok karmaşık olmasa bile, zamana çok bağlı olan bu gibi fonksiyonlar gibi görünüyor. Genel sorunum, nasıl dilimlediğim önemli değil, testlerimin test ettikleri işlevlerden çok daha karmaşık görünmesi.


İlk önce birim testleri yazmalısınız, bu gerçek üretim kodu yazılmadan önce tasarımınızdaki test edilebilirlik sorunlarını tespit etmenize yardımcı olur.
Chedy2149

2
Bu yararlıdır, ancak doğal olarak durumlu, ORM-ağır uygulamaların en iyi nasıl test edileceği konusunu ele almaz.
acjay

Kalıcılık katmanı soyutlamak zorunda
Chedy2149

1
Varsayımsal olarak harika görünüyor, ancak proje bakımı söz konusu olduğunda, iş mantığı ile son derece iyi belgelenmiş Django ORM arasına ısmarlama bir kalıcılık katmanı eklemenin önemsiz bir maliyeti olduğunu düşünüyorum. Aniden, sınıflar zaman içinde yeniden düzenlenmesi gereken bir dizi küçük aracı yöntemle doludur. Ama belki de bu, test edilebilirliğin kritik olduğu yerlerde haklıdır.
acjay

Yanıtlar:


6

Devam edeceğim ve şimdiye kadar bulduğum şey için bir cevap kaydedeceğim.

Benim hipotezim, derin kuplaj ve durum içeren bir fonksiyon için, gerçek şu ki, dış bağlamı kontrol etmek için çok fazla satır alacaktır.

Test durumum, standart Mock kütüphanesine dayanarak kabaca şöyle görünüyor:

  1. Olayların sırasını ayarlamak için standart ORM'yi kullanıyorum
  2. Kendi başlangıcı oluşturuyorum datetimeve auto_now_addzamanları tasarımımın sabit bir zaman çizelgesine uyacak şekilde değiştiriyorum. ORM'in buna izin vermediğini düşündüm, ancak iyi çalışıyor.
  3. Ben sadece bu işlevi from datetime import datetimeyama datetime.now()(böylece tüm datetimesınıf alay , ORM bir uyum pitches) yama test altında kullanır emin olun .
  4. object.key_method()Değişkenlere bağlı basit ama iyi tanımlanmış işlevsellik ile kendi değişimimi oluşturuyorum . Bağımsız değişkenlere bağlı olmasını istiyorum, çünkü aksi takdirde test altındaki fonksiyonun mantığının çalışıp çalışmadığını bilemeyebilirim. Benim durumumda, startTimeve arasındaki saniye sayısını döndürür endTime. Ben lambda sarın object.key_method()ve new_callablekwarg kullanarak doğrudan yama yama patch.
  5. Son olarak, summarysahte davranışın verilen davranışını hesaplayan beklenen elle hesaplanan sonuçlarla eşitliği kontrol etmek için farklı argümanlarla çeşitli çağrılarda bir dizi iddia yürütüyorumkey_method

Söylemeye gerek yok, bu işlevin kendisinden önemli ölçüde daha uzun ve daha karmaşıktır. DB'ye bağlıdır ve gerçekten bir birim test gibi hissetmez. Ancak aynı zamanda işlevin iç kısımlarından oldukça ayrıştırılmıştır - sadece imzası ve bağımlılıkları. Bence bu hala bir birim test olabilir.

Uygulamamda, bu fonksiyon oldukça önemlidir ve performansını optimize etmek için yeniden düzenleme işlemine tabidir. Bu yüzden bence sorun buna değer, karmaşıklığa rağmen. Ama hala buna nasıl yaklaşacağım konusunda daha iyi fikirlere açığım. Daha test odaklı bir gelişim tarzına doğru uzun yolculuğumun bir kısmı ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.