TDD'yi okuma / yazma işlevlerine nasıl uygularım?


10

Tavuk ve yumurta problemi gibi görünüyor.

Bazı veri deposuna yazma işlevi yazabilirsiniz, ancak test edilmiş bir okuma işlevi olmadan düzgün kaydettiğinizi asla bilemezsiniz.

Bir veri deposundan bir okuma işlevinin okunmasını sağlayabilirsiniz, ancak test edilen bir yazma işlevi olmadan bu veri deposuna bir şeyler okumak için nasıl koyabilirsiniz?

DÜZENLE:

Bağlanmak ve kullanmak için nesneleri yüklemek için bir SQL veritabanı ile işlemler yapıyorum. DB'nin sağladığı erişim işlevlerini test etmenin bir anlamı yoktur, ancak nesneleri serileştirmek / serisini kaldırmak için bu tür DB işlevlerini sararım. DB'ye doğru ve doğru şeyler yazdığım ve okuduğuma emin olmak istiyorum.

@Snowman'ın belirttiği gibi, ekleme / silme gibi değildir. Yazdığım içeriğin doğru olduğunu bilmek istiyorum, ancak bu iyi test edilmiş bir okuma fonksiyonu gerektiriyor. Okuduğumda, okuduğumun yazılana eşit bir nesne oluşturduğundan emin olmak istiyorum; ancak bu iyi sınanmış bir yazma işlevi gerektirir.


Kendi veri deponuzu mu yazıyorsunuz yoksa var olanı mı kullanıyorsunuz? Mevcut olanı kullanıyorsanız, zaten çalıştığını varsayın. Kendinizinkini yazıyorsanız, bu, TDD'nin yaptığı herhangi bir diğer yazılımı yazmakla aynı şekilde çalışır.
Robert Harvey


1
Yakın ilişki içinde olmakla birlikte, bunun o sorunun bir kopyası olduğunu düşünmüyorum. Dupe hedefi ekleme / silme hakkında konuşuyor, bu okuma / yazma. Fark okuma / yazma bağımlılığının büyük olasılıkla okunan / yazılan nesnelerin içeriğine dayanması, basit bir ekleme / silme testinin ise çok daha basit olması muhtemeldir: nesne var mı, yok mu.

2
Bir okuma fonksiyonunu test etmek için veri içeren ve yazma fonksiyonu olmayan bir veritabanını kademelendirebilirsiniz.
JeffO

Yanıtlar:


7

Okuma Fonksiyonu ile başlayın.

  • Test kurulumunda : veritabanını oluşturun ve test verileri ekleyin. taşıma komut dosyaları aracılığıyla veya bir yedeklemeden. Bu sizin kodunuz olmadığından TDD'de bir test gerektirmez

  • Testte : deponuzu örnekleyin , test db'nizin üzerine gelin ve Read yöntemini çağırın. Test verilerinin döndürüldüğünü kontrol edin.

Artık tamamen test edilmiş bir okuma işleviniz var, kendi sonuçlarını doğrulamak için mevcut Okuma'yı kullanabilen Yaz işlevine geçebilirsiniz


Sanırım işleri hızlandırmak için bellekte bir DB oluşturabilirsiniz, ancak bu çok karmaşık olabilir. Ünite testlerinde neden sahte kullanmıyorsunuz?
BЈовић

1
Biraz Devil's Advocate burada, ama veritabanının doğru oluşturulduğunu nasıl test edersiniz? OP'nin belirttiği gibi, tavuk ve yumurta.
user949300

1
@Ewan - DB kodlarını test etmemeniz konusunda kesinlikle katılıyorum. Ancak , DB kurulum kodunuzun bir yerde bir INSERT'i unutmadığını veya bir sütuna yanlış bir değer koymadığını nasıl anlarsınız ?
user949300

1
saf bir TDD yaklaşımından test şarttır. bu yüzden mantıksal olarak yanlış olamaz. gerçek dünyada obvs onu göz küresi var
Ewan

1
Quis custodiet ipsos velayeti? Veya, "Testleri kim test ediyor?" :-) Saf bir TDD dünyasında bunun korkunç sıkıcı ve hata eğilimli (özellikle 8 KATILAR ile karmaşık bir çoklu tablo yapısı olsaydı) yolu olacağını kabul ediyorum. Upvoted.
user949300

6

Ben genellikle sadece bir yazma ve ardından bir okuma yapmak. ör. (sözde kod)

Foo foo1 = setup some object to write
File tempfile = create a tempfile, possibly in memory 
writeFoo(foo1, tempfile) 
Foo foo2 = readFoo(tempfile) 
assertEquals(foo1, foo2); 
clean-up goes here

Daha Sonra Eklendi

Bu çözümün "prgamatic" ve "yeterince iyi" olmasına ek olarak, diğer çözümlerin yanlış şeyi test ettikleri iddia edilebilir . Dizelerin veya SQL ifadelerinin eşleşip eşleşmediğini test etmek korkunç bir fikir değil, bunu kendim yaptım, ancak bir yan etkiyi test ediyor ve kırılgandır. Büyük / küçük harf kullanımını değiştirir, alan ekler veya verilerinizdeki bir sürüm numarasını güncellerseniz ne olur? SQL sürücünüz verimlilik çağrılarının sırasını değiştirirse veya güncellenmiş XML serileştiriciniz fazladan bir alan ekler veya şema sürümünü değiştirirse ne olur?

Şimdi, bazı resmi özelliklere çok sıkı sıkıya bağlı kalmanız gerekiyorsa, ince ayrıntıların kontrol edilmesinin uygun olduğunu kabul ediyorum.


1
Çünkü% 90 gerçekten yoğun sözde kod? Emin değil. Belki metni vurgulayın ve kodu daha az gürültülü yapın?
RubberDuck

1
Evet @ Ewan. Zealot bunun üzerine kaşlarını çattı, ancak pragmatik programcı "yeterince iyi" diyip ilerlemeye devam edecekti.
RubberDuck

1
soruyu biraz okudum .. "TDD'yi bir zealot gibi takip ettiğimi varsayarak ..."
Ewan

1
OP ve TDD hakkındaki yorumum, testinizin önce yazılması ve başka bir yerde de test edilmedikçe hem okuma hem de yazma kullanmaması gerektiğidir.
Ewan

2
test edersiniz, 'okuma yazdıklarımı döndürmelidir' ancak gereksinimler 'okuma db'den veri döndürmelidir' ve 'yazma db'ye veri yazmalıdır'
Ewan

4

Yapma. Ünite test G / Ç işlemlerini yapmayın. Bu bir zaman kaybı.

Birim test mantığı. G / Ç kodunda test etmek istediğiniz çok fazla mantık varsa, G / Ç yaptığınız mantığı ve G / Ç yaptığınız gerçek G / Ç yapmanın mantığını ayırmak için kodunuzu yeniden düzenlemelisiniz. (test etmek neredeyse imkansızdır).

Bir HTTP sunucusunu test etmek istiyorsanız, bunu iki tür testle yapmalısınız: entegrasyon testleri ve birim testleri. Birim testleri G / Ç ile hiç etkileşime girmemelidir. Bu yavaştır ve kodunuzun doğruluğu ile ilgisi olmayan birçok hata koşulu sunar. Birim testleri ağınızın durumuna tabi olmamalıdır!

Kodunuz ayrı olmalıdır:

  • Hangi bilgilerin gönderileceğini belirleme mantığı
  • Belirli bir bilgi parçasını göndermek için hangi baytların gönderileceğini belirleme mantığı (bir yanıtı vb. Ham baytlara nasıl kodlayabilirim) ve
  • Bu baytları bir sokete gerçekten yazma mekanizması.

İlk ikisi mantık ve kararları içerir ve birim testleri gerektirir. Sonuncusu, çok sayıda karar almayı gerektirmez ve entegrasyon testi kullanılarak harika bir şekilde test edilebilir.

Bu genel olarak iyi bir tasarım aslında, ama bunun nedenlerinden biri test etmeyi kolaylaştırıyor.


İşte bazı örnekler:

  • İlişkisel bir veritabanından veri alan bir kod yazıyorsanız, ilişkisel sorgulardan döndürülen verilerin uygulama modelinize nasıl eşlendiğini birim olarak sınayabilirsiniz.
  • İlişkisel bir veritabanına veri yazan bir kod yazıyorsanız, kullandığınız belirli SQL sorgularını test etmeden veritabanına yazmak istediğiniz veri parçalarını birim olarak sınayabilirsiniz. Örneğin, uygulama durumunuzun iki kopyasını bellekte tutabilirsiniz: veritabanının neye benzediğini temsil eden bir kopya ve çalışan kopya. Veritabanıyla senkronize etmek istediğinizde, bunları dağıtmanız ve farklılıkları veritabanına yazmanız gerekir. Bu fark kodunu kolayca birim testi yapabilirsiniz.
  • Bir yapılandırma dosyasından bir şey okuyan kod yazıyorsanız, yapılandırma dosyası biçim ayrıştırıcısını test etmek istersiniz, ancak diskten aldığınız dizeler yerine test kaynak dosyanızdaki dizelerle.

2

Bunun standart bir uygulama olup olmadığını bilmiyorum ama benim için iyi çalışıyor.

Benim veritabanı olmayan okuma yazma yöntemi uygulamalarda ben uygulama türü olarak kendi türüne özgü toString()ve fromString()yöntemleri kullanın .

Bunlar kolayca izole edilebilir:

 assertEquals("<xml><car type='porsche'>....", new Car("porsche").toString());

Gerçek okuma yazma yöntemleri için fiziksel olarak bir testte okuma ve yazma bir entegrasyon testi var

Bu arada: Testin birlikte okunması / yazılmasıyla ilgili bir testin olması yanlış bir şey mi var?


Kendini iyi veya "saf" hissetmeyebilir, ama bu pragmatik bir çözümdür.
RubberDuck

Ben de birlikte okuma ve yazma test fikrini seviyorum. ToString () yönteminiz güzel bir pragmatik uzlaşmadır.
user949300

1

Bilinen veriler, bilinen bir şekilde biçimlendirilmelidir. Bunu uygulamanın en kolay yolu, sabit bir dize kullanmak ve @ k3b açıklandığı gibi sonucu karşılaştırmaktır.

Yine de sabitlerle sınırlı değilsiniz. Yazılı verilerin, normal ifadeler gibi farklı bir ayrıştırıcı türü veya hatta verilerin özelliklerini arayan geçici problar kullanarak ayıklayabileceğiniz bir dizi özelliği olabilir.

Verileri okumak veya yazmak için, sistemin diğer bölümlerinden müdahale olasılığı olmadan testlerinizi yürütmenizi sağlayan bir bellek içi dosya sistemine sahip olmak yararlı olabilir. İyi bir bellek içi dosya sistemine erişiminiz yoksa geçici bir dizin ağacı kullanın.


1

Bağımlılık enjeksiyon ve alay kullanın.

SQL sürücünüzü test etmek istemiyorsunuz ve SQL veritabanınızın çevrimiçi olup olmadığını ve düzgün bir şekilde kurulup kurulmadığını test etmek istemiyorsunuz. Bu bir entegrasyon veya sistem testinin bir parçası olabilir. Kodunuzun göndermesi gereken SQL ifadelerini gönderip göndermediğini ve yanıtları olması gerektiği şekilde yorumlayıp yorumlamadığını test etmek istersiniz.

Bu nedenle, bir veritabanıyla bir şeyler yapması gereken bir yöntem / sınıfınız olduğunda, bu veritabanı bağlantısını kendi başına almasını sağlayın. Veritabanı bağlantısını temsil eden nesne kendisine geçirilecek şekilde değiştirin.

Üretim kodunuzda, gerçek veritabanı nesnesini iletin.

Birim testlerinizde, gerçek bir veritabanı gibi davranan bir sahte nesneyi gerçekte bir veritabanı sunucusuna başvurmaz. Sadece alması beklenen SQL ifadelerini alıp almadığını kontrol etmesini sağlayın ve ardından sabit kodlu yanıtlarla yanıt verin.

Bu şekilde, veritabanı soyutlama katmanınızı gerçek bir veritabanına bile ihtiyaç duymadan test edebilirsiniz.


Devil's Advocate: Hangi SQL deyimlerinin "alması gerekiyor" olduğunu nereden biliyorsunuz? DB sürücüsü siparişi kodda görünenden en iyi duruma getirirse ne olur?
user949300

@ user949300 Bir veritabanı sahte nesnesi genellikle veritabanı sürücüsünün yerini alır .
Philipp

bir depo test ederken alaycı bir veritabanı istemcisi enjekte hiçbir anlamı yoktur. Kodunuzun veritabanında çalışan sql çalıştırdığını test etmeniz gerekir. aksi taktirde uo'nuzu sadece test edersiniz
Ewan

@Ewan Birim testin konusu bu değil. Birim testi, dünyanın geri kalanından izole edilen bir birim kodu test eder. Kodunuz ve veritabanı gibi bileşenler arasındaki etkileşimleri test etmiyorsunuz. Entegrasyon testi bunun içindir.
Philipp

Evet. im db deposu test hiçbir nokta birimi olduğunu söyleyerek. entegrasyon testi yapmaya değer tek şey
Ewan

0

Nesne ilişkisel bir eşleyici kullanıyorsanız, genellikle bir toplama oluşturarak, devam ettirerek ve yeni bir oturumdan yeniden yükleyerek ardından durumun orijinal nesne.

NHibernate Kalıcılık Belirleme Testi sunar . Hızlı birim testleri için bellek içi bir mağazada çalışacak şekilde yapılandırılabilir.

Depo ve İş Birimi kalıplarının en basit sürümünü izler ve tüm eşlemelerinizi test ederseniz, hemen hemen işe yarayan şeylere güvenebilirsiniz.

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.