Birim testleri ve TDD'yi çoğunlukla veritabanı CRUD işlemlerine dayanan bir uygulamayı test etmek için nasıl kullanabilirim?


22

İş yerimde projelerimden biri çoğunlukla harici bir müşteriden aktarılan verilerin alınması ve veritabanında kalması ile ilgili. JPA kullanan bir Java kurumsal uygulamasıdır ve mantığımızın çoğu CRUD işlemleri etrafında döner.

Böceklerimizin çoğu JPA'yı bir şekilde veya başka şekilde içerir.

  • Örnek 1: Kaydet düğmesine iki kez tıklarsanız, JPA aynı varlığı veritabanına ikinci kez eklemeye çalışarak birincil anahtar ihlaline neden olabilir.
  • Örnek 2: Veritabanından bir varlık alırsınız, düzenler ve verilerini güncellemeye çalışırsınız. JPA eskisini güncellemek yerine yeni bir örnek oluşturmaya çalışabilir.

Genellikle çözüm, bir JPA ek açıklaması eklemek / kaldırmak / değiştirmek için ihtiyaç duyar. Diğer zamanlarda DAO mantığını değiştirmekle ilgili.

Ünite testleri ve TDD kullanarak kodumuza nasıl güveneceğimi bilemiyorum. Bunun nedeni ünite testleri ve TDD'nin uygun olmadığından veya soruna yanlış yaklaşıyorsam emin değilim.

Ünite testleri kötü bir uygulama gibi gözüküyor çünkü bu sorunları yalnızca çalışma zamanında keşfedebiliyorum ve sorunları çoğaltmak için bir uygulama sunucusuna dağıtmam gerekiyor. Genellikle, bir birim testi tanımının dışında olduğumu düşündüğüm veritabanının dahil olması gerekir: Bunlar entegrasyon testleridir.

TDD kötü bir uyum gibi görünüyor çünkü konuşlandırma + test geri besleme döngüsü o kadar yavaş ki beni çok verimsiz yapıyor. Konuşlandırma + test geri besleme döngüsü 3 dakikadan fazla sürüyor ve bu sadece testleri yazdığım kodla ilgili olarak çalıştırmam durumunda. Tüm entegrasyon testlerini çalıştırmak 30 dakika sürer.

Bu kalıbın dışında kod var ve yapabildiğimde bunu her zaman test ediyordum. Ancak böceklerimizin büyük çoğunluğu ve en büyük lavabolar her zaman JPA veya veri tabanını içerir.


Benzer olan başka bir soru daha var , ancak tavsiyeye uyursam kodumun (JPA) en dengesiz bölümünü sarar ve dışındaki her şeyi test ederdim. Sorumu bağlamında aynı kötü durumda olurdum. JPA'yı tamamladıktan sonraki adım nedir? IMO bu soru (belki de) soruma cevap vermek için bir adım, ama buna bir cevap değil.


4
Yaptığınız şey aslında entegrasyon testidir, çünkü veritabanını gerçekten test etmek için kurmanız gerekir. Bir modülün diğerlerine güveneceğini hayal edebiliyorum, bu yüzden entegrasyon testine daha da çok benziyor. TDD yaklaşımlarını uygulamanıza nasıl uygulayacağınız konusundaki sorunuzu değiştiririm.
InformedA

@randomA doğru, ben bunu açıkça söylemek için sorumu düzenledi. Neden tavsiye ettiğinizi anlamıyorum, soruyu değiştiriyorum. Ayrıntılı olabilir misiniz? Ünite test bölümünü orada tutmak istiyorum çünkü entegrasyon testlerinden ziyade ünite testleri yazmayı tercih ediyorum (bunun farkında olduğum halde unit testing != TDD)
Daniel Kaplan

özel bir şey olsa, sadece TDD'yi oraya koyun. Orada birim testiniz varsa, o zaman birçok kişi bir şey anlamadığınızı düşünür, vb .. sizin için iyi değil ..
InformedA


Yanıtlar:


7

Bir seçenek H2 gibi bir bellek içi test veritabanı kullanmaktır ; standart bir disk kullanan veritabanından yaklaşık 10 kat daha hızlı ve daha düşük başlangıç ​​/ yırtılma süreleri ile olma eğilimindedir.

İşe yarayıp yaramayacağı büyük ölçüde, sahip olduğunuz JPA sorunlarının farklı veritabanlarında hala başarısızlığa uğrayacak kadar genel olup olmadığına bağlıdır. Sorunların büyük bölümünü özlüyorlarsa, nokta koşma testleri çok daha hızlı olmaz.

Ancak, tam sisteme sahip her biri için H2 ile 10 çalışma yapabilirseniz, bunun karşılığını verebilir.


Güzel bir düşünce ama yine de AFAIK adlı uygulama sunucusuna konuşlandırmam gerekiyor. Bu 3 + dakikadan fazlası. Bu kesinlikle yapmaya değer dedi. Fakat yine de testleri test etmeyi düşündüğüm kadar sık ​​çalıştırmayı hayal etmek hala zor ve bu nedenle TDD kullanarak geliştirme yapmak yetersiz kalıyor.
Daniel Kaplan,

1
Bu gereksinimin etrafında genellikle yollar olduğunu düşünüyorum (örneğin, docs.oracle.com/middleware/1212/toplink/TLADG/testingjpa.htm ). Haklı olmasına rağmen daha fazla iş olma şansı oldukça yüksek; Başka bir seçenek de bazı daha güçlü test sunucularına sahip olmak ve işleri paralel olarak çalıştırmak olacaktır.
soru

1
@tieTYT hsqldb ünitesi ile kendi kavram kanıtım github'da bir crud web uygulamasını test ediyor: TestWithHsqldb ile - ünite testleri uygulamanın konuşlandırılması gerekmiyor.

3

Veritabanları birim testi çok kolay olabilir - saklı yordamlar ve işlemler gerekir.

Microsoft, Veritabanı birim testi hakkında ne diyor . Ayrıca, bir DB bağlantısı kurarak, bir işlemi başlatarak, testleri DB'ye ayarlayarak test etmek için Java veya C # dilinde yazarak birim testlerini çalıştırabilir, bir işlemi başlatabilir, test etmek için hangi verileri kullanmak istediğinizi yazabilir, testleri çalıştırabilir ve daha sonra geri alabilirsiniz. Aynı zamanda dağıttığınız birini kullanıyorsanız DB'ye zarar vermez ve tamamen yalıtılmış testler alırsınız.

Umarım bu size, kendi çerçevenizde nasıl yapılacağına dair bir fikir verebilir.


Dediğim gibi, "Hatalarımızın çoğu JPA'yı bir şekilde veya başka bir şekilde içerir.", Makalenin tavsiyelerinin hepsini kaçıracağını düşünüyorum. Ayrıca, eğer bu Java / C # testlerini hala birim testler olarak görüyorsanız, çok farklı tanımlarımız var. Bunun genel olarak iyi bir tavsiye olduğunu düşünüyorum, ancak süitin dağıtılması ve çalıştırılması ve bu nedenle TDD'ye elverişli olmamanın bir süre alacağı görülüyor. Katılmıyor musun
Daniel Kaplan,

SQL için DB birim sınamalarını kullanırdık, ama sonra hepsi sprocs içerisindeydi. Eğer, bizim birim test çerçevesi mstest diğer sql prosedürlerden birim test sql dizin oldu olabilir iken onları çalıştırmak için mantıklı şekilde orada (hey, biz oldu derleme sunucusu yeşil keneler var en önemli faktör). Her zaman bir DB'niz varsa (ve yine de int testi için yaptık) o zaman tüm sql kodunu yüklemek ve tüm sunucu testlerini derleme sunucusunda çalıştırmak kolaydır. Bazen bu konularda pragmatik olmalısın.
gbjbaanb

İlk cezama cevap verdiğini sanmıyorum.
Daniel Kaplan

Öyleyse, sadece jpa ünitesini kullanın JPA kodunuzun nasıl çalıştığını (veya çalışmadığını) cevaplayamıyorum, sadece db'de test edilen sql'i test etmek için bazı fikirler vermeye çalışın.
gbjbaanb

3

Diğer insanlar "DB'nizi taklit edin!" - gerçekte kodunuzla nasıl etkileşime girdiğini test etmeniz gerekiyorsa, DB katmanınızı alay etmenin amacı nedir?

Aradığın şey entegrasyon testleri ve / veya otomatik UI testleri. Sorunun şu durumlarda olacağını söylediniz:

*If you click the save button twice*

Bunu test etmenin tek yolu, düğmeye iki kez tıklamak için otomatik bir UI testi yazmaktır. Belki selenyumu kontrol et.

Muhtemelen ayrıca DB test eden bir birime ihtiyacınız olacak ve testleriniz için bunu işaret edeceksiniz. TDD'yi korumak için gerçek dünyadaki bir acıyı bekliyoruz.


Bu bir cevaptan daha rant gibi görünüyor
gnat

Soruyu üç kez cevapladım - entegrasyon testleri, GUI testleri ve / veya DB testini gerçekleştiren bir birim. Evet biraz rant, biraz şimdi aklı başında bir akıl sağlığı düzenleyeceğim.
Rocklan

1
"Bunu test etmenin tek yolu, düğmeye iki kez tıklamak için otomatik bir UI testi yazmak. Belki de Selenyum'u kontrol et." Bu gibi durumlarda, arka uç bunun gerçekleşmesini önlüyorsa, aksi takdirde UI veritabanına doğrudan erişebilir.
Daniel Kaplan,

0

Sorunuzda verdiğiniz örnekte, çok kolay bir hataya neden olmak için düğmeyi iki kez tıklatma durumunda yolunuzu test etme / TDD yapamazsınız. Ancak birim sınaması, düğmeyi tıklattığınızda çağrılan kodda, kalıcılık katmanından bir istisna elde ederseniz, uygun şekilde kullanmanızdır (kalıcılık katmanını atarak veya bellek içi veritabanını kullanarak başka cevaplarda da önerilmiştir) - tekrar veya bir hatayı veya ne olursa olsun göstererek.

Birim testine uygun olmayan testler yapmanız gerektiğinde TDD'nin bozulmaya başlayabileceği konusunda haklısınız (yani entegrasyon / sistem testleri) - bu, son zamanlarda yapılan tartışmaların oldukça çoğunu oluşturdu. Ölü?" Kent Beck, Martin Fowler ve David Heinemeier Hansson arasındaki tartışmalar: http://martinfowler.com/articles/is-tdd-dead/

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.