Birim testi - Veritabanı bağlantılı uygulama


15

Veritabanına sıkıca bağlı bir uygulamaya entegre olan bir modeli test eden birim testinde en iyi yaklaşım ne olabilir?

Buradaki özel senaryo bir alışveriş sepeti - sepetten öğelerin kaldırılmasını ve alınmasını ve fiyatlandırma mantığını vb. Test edebilmek istiyorum. Birkaç kez okuduğum halde bence bu veritabanı erişimi gerektirir veritabanı erişiminden kaçınılmalıdır.


1
İlginç bir şekilde "uygulama kodunuzu yeniden yazın" yazan yanıtların oy kullanması
ilginç

Yanıtlar:


10

Bağımlılık enjeksiyonu bunu idare etmenin bir yoludur. Alışveriş sepetini taklit etmek için bir test veritabanı ayarlayabilir veya müşterinin işlemini "onaylayan" bir kod bile yazabilirsiniz. Ardından çalışma zamanında, yazılımınız hangi bileşene bağlanacağınızı seçecektir.

Test sırasında herhangi bir şey için üretim veritabanına bağlanmayın!


1
DI ve uygun uygulama tasarımı ile, enjekte ettiğiniz sahte arka uç veritabanının yeterince ayrıntılı alayını sağlaması koşuluyla, herhangi bir veritabanı olmadan test yapabilmeniz gerekir.
Peter K.Mar

4

Birim testinde, test ettiğiniz şeyin sınırını tanımlamanız gerekir. Birim testi, entegrasyon testinden farklıdır. Fiyatlandırma mantığı Alışveriş Sepeti içeriğinden bağımsızsa, bunu ayrı olarak test edersiniz. Durum böyle değilse ve tüm modüller sıkıca bağlıysa, üretimi olabildiğince taklit eden bir test ortamı oluşturun ve bununla çalışın. Kısa yolların ve simülasyonun uzun vadede yardımcı olduğuna inanmıyorum.


2

Model (beton) bir DB'ye bağlı olmamalıdır. Yalnızca modele teslim edilen soyut bir DB (okuma "arabirimi") biliyorsanız, DB'yi sahte bir nesneyle değiştirebilirsiniz .

Olarak nesne yönelimli programlama , sahte nesneler kontrollü şekilde gerçek nesneler davranışını taklit nesneleri simüle edilir. Bir programcı tipik olarak başka bir nesnenin davranışını test etmek için bir araba nesnesi yaratır, tıpkı bir araba tasarımcının bir aracın taşıt etkilerinde dinamik davranışını simüle etmek için çarpışma testi mankeni kullanması gibi ...


1

Benzer bir sorunum vardı - Test DB'mın değerleri koruduğunu garanti etme imkanım yoktu. Yani gelecekte örneğin diğer fiyatlar olsun.

İhtiyacım olan verileri küçük bir sqlite -DB'ye çıkardım ve testleri için bu DB'yi kullandım. Test-DB artık birim testimin kurulumunun bir parçası.


2
Birim testleri, kodunuzu tek tek test etmektir. Bir sqllite db kullanıyorsanız, o zaman onun izole değil. Ayrıca veritabanları arasındaki tutarsızlıklar hatalara neden olabilir
Tom Squires

0

"En iyi" özneldir, ancak sadece bir test db bağlantısı kullanabilirsiniz.

Bazı test verilerini (satın alınacak örnek ürünler) yüklemek için armatürleri kullanın ve ardından test etmek istediğiniz sınıf / işlev için test durumunu yazın.


Bir veritabanına etki eden bir işlevi sınama birimi olarak test eden birim sınamalarını tanımlamak @murph'u oldukça yanıltıcıdır.
AD7six

1
Tamam, şimdi derinden kafam karıştı - eğer bir veritabanı içeriyorsa, çoğu tanım tarafından değil, kendi içinde yer almadığı için bir birim testi. Eğer bir veritabanınız varsa, daha yüksek bir seviyede testler yürütüyorsunuz. Bunların bağımlılıkları olan şeyleri "birleştiriyor". Ne olursa olsun, bu sorunun nasıl çözüleceğine dair net bir açıklama değil.
Murph

0

Ben inşa Symfony'nin 1.4 (PHP) için bir eklenti (diğerleri arasında) bu sorunu çözmek için. Django'nun test çerçevesinin (Python) çalışma biçiminden sonra modellenmiştir : çerçeve, her test başlamadan önce ayrı bir test veritabanı oluşturur ve doldurur ve her test tamamlandıktan sonra test veritabanını yok eder.

Hem performans açısından (şema değişmezse, neden tüm yapıyı yeniden oluşturmak yerine verileri temizlemiyorsunuz?) Hem de kolaylık açısından (bazen bir veritabanından sonra veritabanını incelemek istiyorum) bu strateji hakkında birkaç endişem vardı Test başarısızlığı, bu yüzden ayrım gözetmeden yok etmeyin!), bu yüzden biraz farklı bir yaklaşım aldım.

İlk test çalıştırılmadan önce, son testten bu yana model değişiklikleri olması durumunda veritabanı yok edilir ve yeniden oluşturulur. Sonraki her test çalıştırılmadan önce, veritabanındaki veriler silinir, ancak yapı yeniden oluşturulmaz (gerekirse manuel olarak bir testten manuel yeniden oluşturma tetiklenebilir).

Her bir teste veri fikstürlerini seçici olarak yükleyerek, sonraki testlere müdahale etmeden bu test için uygun ortamı oluşturabilirsiniz. Fikstür dosyaları da tekrar kullanılabilir, bu da bu görevi çok daha az zahmetli hale getirir (yine de test yazmadaki en az favori parçamdır!).

Her iki test çerçevesinde de veritabanı bağdaştırıcısı, test yürütmesinin var olan verileri bozmasını önlemek için "üretim" bağlantısı yerine test bağlantısını kullanacak şekilde yapılandırılmıştır.


0

Söylemeliyim, sadece devam edin ve verileri önceden yüklemek için fikstürleri kullanın. Verilerin manipülasyonunu test ederken birim test çerçevelerinin genel olarak işleyiş şekli budur.

Ancak, herhangi bir tür veritabanına bağlanmaktan kaçınmak ve birim testlerinin kodun dışındaki herhangi bir şeye dokunmadığı aşırı katı bir tanımdan geçmek istemiyorsanız, nesne alayına bir göz atın - size fikir verebilir.

Örneğin, SQL'i doğrudan ihtiyacınız olan koda bırakmak yerine, yalnızca SQL'in yaptıklarını yapan bir yöntemi çağırmanın bir yolu var. Person.getPhoneNumber()Örneğin, yerine kullanın SELECT phone_number FROM person WHERE id = <foo>. Sadece bir bakışta anlaşılması daha kolay ve daha kolay olmakla kalmaz, aynı zamanda test sırasında Personele nesneyi alay edebilirsiniz, böylece veritabanına dokunmak yerine getPhoneNumber()her zaman geri döner 555-555-5555.


0

Bu, biraz uzun sarılırsa junit ile yapmak oldukça kolaydır.

"Kurulum" bir dizi geçici tablo tanımlamalı ve doldurmalıdır.

Daha sonra tüm güncelleme, ekleme, silme işlevleri için birim testleri yapabilirsiniz.

Her test için güncelleme yönteminizi çağırdıktan sonra beklenen sonucu doğrulamak için biraz SQL çalıştırın.

"Teardown" aşamasında tüm tabloları düşürürsünüz.

Bu şekilde her zaman aynı testleri aynı başlangıç ​​verilerinde gerçekleştirirsiniz. Tabloları testler arasında tutarsanız, başarısız testlerle "kirlenmiş" olurlarsa, her testte yeni anahtarlar icat etmeye devam etmeniz gerektiğinden tutarlı bir "insert" testi neredeyse imkansızdır.

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.