Birim testleri için yürütme emrini uygulamak kötü bir uygulama mıdır?


84

Birden fazla alt modülden oluşan bir proje için testler yazıyorum. Yazdığım her test durumu birbirinden bağımsız çalışıyor ve testler arasındaki tüm verileri temizliyorum.

Testler bağımsız çalışsa da, bazı durumlarda birden fazla alt modül gerektirdiğinden, yürütme emrini yerine getirmeyi düşünüyorum. Örneğin, bir alt modül veri üretiyor, diğeri veri üzerinde sorgular çalıştırıyor. Verileri üreten alt modül bir hata içeriyorsa, alt modülün kendisi de iyi çalışsa bile, sorgu alt modülünün sınaması da başarısız olacaktır.

Sahte verilerle çalışamıyorum, test ettiğim temel işlevsellik, yalnızca ilk alt modülden verileri alan bir kara kutu uzak sunucusuna bağlantı olması.

Bu durumda, testler için bir icra emri uygulamak doğru mudur, yoksa kötü bir uygulama mı? Bu düzende bir koku varmış gibi hissediyorum, ancak daha iyi bir yol bulamıyorum.

düzenleme: soru bir test başka bir testin kurulum olduğu testleri nasıl yapılandırılır? "önceki" sınama bir kurulum değil, ancak ayarları yapan kodu sınar.



123
Uzak bir sunucuya bağlantıyı test ediyorsanız, bunlar tanım gereği birim testleri değildir.
Telastyn

9
İlk cevap kafamı karıştırdı çünkü başlığında "Kötü bir uygulama mı?" Dedin. ve sorunuzun özetinde "tamam mı?" yazdınız. Evet ya da hayır cevabını veren herkes bunlardan birini karıştırır!
Liath

8
Bir dizi entegrasyon testi yaratıyor gibisiniz. Bunun için bile bir test diğer testlere dayanmamalı.
Low Flying Pelican

17
Sipariş önemli ise, o zaman muhtemelen yanlış yapıyorsunuzdur.
Mark Rogers,

Yanıtlar:


236

Sahte verilerle çalışamıyorum, test ettiğim temel işlevsellik, yalnızca ilk alt modülden verileri alan bir kara kutu uzak sunucusuna bağlantı olması.

Bu benim için kilit kısım. "Birim testleri" ve "birbirlerinden bağımsız olarak çalışanlar" hakkında konuşabilirsiniz, ancak hepsi bu uzak sunucuya bağlı ve "ilk alt modül" e bağlı gibi geliyor. Bu yüzden her şey sıkıca bağlı ve dış duruma bağlı geliyor. Dolayısıyla, aslında entegrasyon testleri yazıyorsunuz. Bu testlerin belirli bir düzende gerçekleştirilmesi, harici faktörlere oldukça bağımlı oldukları için oldukça normaldir. Bir şeyler ters giderse test çalışmasından erken ayrılma seçeneği olan düzenli bir test çalışması entegrasyon testleri için mükemmel şekilde kabul edilebilir.

Ancak, uygulamanızın yapısına yeni bir göz atmaya da değecektir. İlk alt modülü ve harici sunucuyu alay etmek, diğer tüm alt modüller için gerçek birim testleri yazmanıza izin verecektir.


14
Bazı testlerin özellikle uzak sunucu kullanılamadığında beklenen davranışın gerçekleştiğini kontrol etmek zorunda olduğunu belirtmemek gerekir.
Alexander,

2
Belki de aslında entegrasyon testleri yazmayı düşünüyorsunuz ve bu nedenle verileri alay etmek, bu testlerle başarmaya çalıştığınız şeyi başaramayacak.
Guy Schalnat

10
Sorun büyük olasılıkla Junit'in adına "birim" olması.
Thorbjørn Ravn Andersen

7
@ ThorbjørnRavnAndersen Tam olarak. İnsanlar, doğal olarak, birim testlerinden ziyade entegrasyon testleri yazarlar, çünkü entegrasyon testleri hem gerçek hem de "gerçek" birim testlerinden çok daha faydalı ve yazmak daha zordur. Ancak, popüler test çerçevelerinin birim test konseptinden sonra seçilmeleri nedeniyle, terim ortak olarak seçildi ve modern bakışta “herhangi bir otomatik test” anlamına geldi.
Mason Wheeler

1
@MasonWheeler Veya kabul testi demek için teknik olmayan yöneticiler tarafından bile seçildi.
TKK

32

Evet, kötü bir uygulama.

Genel olarak, bir birim testinin, tek bir kod birimini (örneğin bilinen bir duruma dayalı tek bir işlev) test etmesi amaçlanmaktadır.

Vahşi doğada olabilecek bir olaylar zincirini test etmek istediğinizde, entegrasyon testi gibi farklı bir test stili istiyorsunuz. Bir üçüncü taraf servisine bağlıysanız, bu daha da geçerlidir.

Bunun gibi şeyleri sınamak için, örneğin web isteğini yansıtan, ancak yerel bir sahte veri dosyasından bilinen verileri döndüren bir veri hizmeti arabirimi uygulayarak sahte verileri enjekte etmenin bir yolunu bulmanız gerekir.


8
Kabul. Bence bu karışıklık, birçok insanın entegrasyon testlerinin baştan sona yapılması gerektiği fikrine sahip olmasından ve sadece bir katmanı test eden herhangi bir testi ifade etmek için "birim testi" kullanmasından kaynaklanmaktadır .
autophage

8
@ autophage: Kesinlikle buna katılıyorum. Aslında ben düzenli kendimi aynı tuzağa düşen bulmak o kadar onunla hemfikir bunun bir tuzak olduğunu kabul rağmen 😂
Orbit Açıklık Races

16

Teklif ettiğiniz zorunlu yürütme emri, yalnızca ilk başarısızlıktan sonraki test çalıştırmasını iptal ederseniz anlamlıdır.

Testin ilk başarısızlıkta iptal edilmesi, her test çalışmasının sadece tek bir problemi çözebileceği ve önceki tüm problemler çözülmeden yeni problemler bulamayacağı anlamına gelir. Çalıştırılacak ilk testin düzeltilmesi bir ay süren bir sorun bulursa, o ay etkili bir şekilde test yapılmayacaktır.

İlk başarısızlıktaki test çalıştırmasını iptal etmezseniz, zorunlu yürütme emri size bir şey almaz çünkü her başarısız testin yine de araştırılması gerekir. Sorgu alt modülünde yapılan testin, alt modül oluşturan verilerde de tespit edilen başarısızlık nedeniyle başarısız olduğunu onaylamak için bile.

Verebileceğim en iyi tavsiye, testleri bir bağımlılıktaki bir başarısızlığın testin başarısız olmasına neden olduğunu tespit etmeyi kolaylaştıracak şekilde yazmaktır.


7

Bahsettiğiniz koku, yanlış sınırlamaların ve kuralların testlerinize uygulanmasıdır.

Birim Testleri genellikle "otomatik test" veya "bir programcı tarafından otomatik test" ile karıştırılmaktadır.

Birim Testleri küçük, bağımsız ve hızlı olmalıdır.

Bazı insanlar bunu yanlış "bir programcının yazdığı otomatik testler küçük bağımsız ve hızlı olmalı" olarak okuyorlar . Ancak bu, testleriniz küçük, bağımsız ve hızlı değilse, Birim Testleri olmadığı ve bu nedenle, Birim Testleri için bazı kuralların testleriniz için geçerli olmaması, uygulanmaması veya uygulanmaması gerektiği anlamına gelir . Önemsiz bir örnek: Birim Testlerinizi her derlemeden sonra yapmalısınız, hızlı olmayan otomatik testler için yapmamanız gerekir.

Testleriniz Ünite Testleri olmamakla birlikte, bir kuralı atlamanız ve testler arasında karşılıklı bağımlılığa sahip olmanıza izin verilmesi anlamına gelirken, aynı zamanda kaçırmış olabileceğiniz ve yeniden girmeniz gerekebilecek başka kuralların da olduğunu - başka bir sorunun kapsamı için bir şey olduğunu öğrendiniz. .


6

Yukarıda belirtildiği gibi, koştuğunuz şey bir entegrasyon testi gibi görünüyor, ancak şunu belirtiyorsunuz:

Örneğin, bir alt modül veri üretiyor, diğeri veri üzerinde sorgular çalıştırıyor. Verileri üreten alt modül bir hata içeriyorsa, alt modülün kendisi de iyi çalışsa bile, sorgu alt modülünün sınaması da başarısız olacaktır.

Ve burası yeniden düzenlemeye başlamak için iyi bir yer olabilir. Verileri sorgulayan modül, ilk (veri üreten) modülün somut bir uygulamasına bağlı olmamalıdır. Bunun yerine, bu verilere ulaşmak için yöntemleri içeren bir arayüzün enjekte edilmesi daha iyi olacaktır ve bu daha sonra sorguların test edilmesi için çözülebilir.

Örneğin

Eğer varsa:

class Queries {

    int GetTheNumber() {
        var dataModule = new Submodule1();
        var data = dataModule.GetData();
        return ... run some query on data
    }
}

Bunun yerine tercih:

interface DataModule {
    Data GetData();
}


class Queries {

    IDataModule _dataModule;

    ctor(IDataModule dataModule) {
       _dataModule = dataModule;
    }

    int GetTheNumber() {
        var data = _dataModule.GetData();
        return ... run some query on data
    }
}

Bu, veri kaynağınızdaki sorgulardan bağımlılığı ortadan kaldırır ve belirli senaryolar için kolayca tekrarlanabilir birim testleri kurmanıza olanak sağlar.


6

Diğer cevaplar, sipariş sınamalarının kötü olduğunu (çoğu zaman doğru olduğunu) belirtiyor, ancak sınama uygulamasında düzeni zorlamak için iyi bir neden var: yavaş sınamalarınızın (örneğin tümleştirme sınamalarının) daha hızlı sınamalarınızdan (sınamalar) sonra yapıldığından emin olun bu diğer dış kaynaklara dayanmaz). Bu, geri bildirim döngüsünü hızlandırabilen daha hızlı test yapmanızı sağlar.


2
Neden belirli bir birim testinin bir emri yerine uygulamak yerine yavaş çalıştığını araştırmaya daha yatkın olurdum. Birim testlerinin hızlı olması gerekiyordu.
Robbie Dee

OP, bu testlerin bazıları için yapay verilerle çalışamayacağını söyledi. Bu, bir çeşit veri tabanı isabeti anlamına gelir, tüm testleri yavaşlatır (doğal olarak hızlı çalışması gereken bazı gerçek birim testleri bile). Veritabanı isabetini gerektirmeyen başka testleri varsa, disk veya ağ isabetini gerektiren her şeyden daha hızlı bir şekilde çalışırlar.
Mike Holler

2
İkiniz de haklısınız, sanırım; Robbie, birim testlerinin küçük ve hızlı olması ve bağımlılıklardan izole edilmesi gerektiği konusunda haklıdır; bu nedenle, sipariş önemli olmamalıdır ve rastgele sıralama, bu bağımsızlığı uygulayarak daha iyi bir tasarımı teşvik eder; ve Mike ilk önce daha hızlı test yapmanın doğru, entegrasyon testleri için çok iyi . Yukarıdaki cevaplarda olduğu gibi, sorunun bir kısmı ünite ile entegrasyon testlerinin terminolojisidir.
WillC

@MikeHoller Öyleyse birim testleri değiller. Birim testlerinin ne olduğu konusunda hiçbir karışıklık olmamalıdır .
Robbie Dee

@RobbieDee Sadece OP'nin kullandığı terminolojiyi kullanıyordum. Bunların gerçek birim testleri olmadığını biliyorum. Terminoloji hakkında savaşmak istiyorsanız, OP ile gündeme getirin. (bu yüzden neden önceki
Mike Holler
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.