Koşullu yoksayma testleri in JUnit 4


365

Tamam, bu nedenle @Ignoreek açıklama, bir test senaryosunun çalıştırılmaması gerektiğini işaretlemek için iyidir.

Ancak, bazen çalışma zamanı bilgilerine dayalı bir testi yoksaymak istiyorum. Bir örnek, belirli sayıda çekirdekli bir makinede çalıştırılması gereken bir eşzamanlılık testim varsa olabilir. Bu test bir tek işlemcili makinede yapıldıysa, sadece testi geçmenin doğru olmayacağını düşünmüyorum (çalıştırılmadığından beri) ve kesinlikle testi geçip yapıyı kırmak doğru olmaz .

Bu yüzden doğru sonuç gibi göründüğü için testler zamanında yok saymak istiyorum (çünkü test çerçevesi yapı geçmesine izin verecek ama testler çalıştırılmadı kayıt). Ek açıklamanın bana bu esnekliği vermeyeceğinden oldukça eminim ve söz konusu sınıf için test paketini manuel olarak oluşturmanız gerekeceğinden şüpheleniyorum. Bununla birlikte, belgeler bununla ilgili herhangi bir şeyden bahsetmez ve API'ye bakarak bunun programlı olarak nasıl yapılacağı da açık değildir (yani Test, @Ignoreek açıklama tarafından oluşturulana eşdeğer bir örneği veya benzerini nasıl programlı olarak nasıl oluşturabilirim ?).

Birisi geçmişte benzer bir şey yaptıysa veya başka nasıl bu konuya gidebileceğim konusunda parlak bir fikri varsa, bunu duymaktan mutluluk duyarım.

Yanıtlar:


476

JUnit yolu bunu çalışma zamanında yapmaktır org.junit.Assume.

 @Before
 public void beforeMethod() {
     org.junit.Assume.assumeTrue(someCondition());
     // rest of setup.
 }

Bir @Beforeyöntemde veya testin kendisinde yapabilirsiniz, ancak bir @Afteryöntemde yapamazsınız . Bunu testin kendisinde yaparsanız, @Beforeyönteminiz çalıştırılır. @BeforeClassSınıf başlatmayı önlemek için bunu içinde de yapabilirsiniz .

Bir varsayım hatası, testin yok sayılmasına neden olur.

Düzenleme: junit-ext@RunIf ek açıklama ile karşılaştırmak için , onların örnek kodu şöyle görünecektir:

@Test
public void calculateTotalSalary() {
    assumeThat(Database.connect(), is(notNull()));
    //test code below.
}

Database.connect()Yöntemden bağlantıyı bu şekilde yakalamak ve kullanmak çok daha kolay değildir .


1
@notnoop, bu benim gözlemim değil. Yok sayılırlar. IDEA test çalıştırıcısı onları bu şekilde rapor eder ve JUnit kaynak koduna bakıldığında testin yok sayıldığı bildirilir.
Yishai

1
Alıntılamak için: "Gelecekte bu değişebilir ve başarısız bir varsayım testin göz ardı edilmesine neden olabilir." Aslında değişti, 4.5 itibariyle inanıyorum. Geçerli javadoc şöyle diyor: "Varsayılan JUnit koşucusu, başarısız varsayımları olan testleri yok sayıldığı gibi ele alır. Özel koşucular farklı davranabilir." github.com/KentBeck/junit/blob/…
Yishai

4
Eclipse 3.6, Junit 4.8.1 ile yanlış Varsayımları geçen bir test olarak bildirir. Karınca 1.8.1 ile aynı.
fijiaaron

8
Eclipse'in başarısız olduğu varsayımlarını bildirmenin bir hata olduğu bildirildi: bugs.eclipse.org/bugs/show_bug.cgi?id=359944
Martin

1
@ JeffStorey, o zaman birkaç şey arıyorsun. Birincisi, @BeforeClasstüm sınıfı atlayacak olan varsayımınızın burada başarısız olabileceği ek açıklamadır. Bir diğeri @ClassRule(ince taneli kontrol için, ancak tüm sınıfta bir kez).
Yishai

51

Junit-extProjeyi kontrol etmelisiniz . Onlar sahip RunIfek açıklama olduğunu gerçekleştirdiği şartlı testleri, gibi:

@Test
@RunIf(DatabaseIsConnected.class)
public void calculateTotalSalary() {
    //your code there
}

class DatabaseIsConnected implements Checker {
   public boolean satisify() {
        return Database.connect() != null;
   }
}

[Eğiticiden alınan kod örneği]


3
Bu cevap için teşekkürler - işlevsellik için ilginç bir alternatif sözdizimi, ancak Assumebaşka bir bağımlılığı tanıtmamak için doğrudan devam edeceğim .
Andrzej Doyle

3
Ben şahsen bu çözümü tercih ederim. Aynı koşullara göre yapılması gereken birçok testiniz varsa, bu, her testte Assume kullanmak zorunda olmaktan çok daha ideal olacaktır. Ayrıca, bu yöntem yöntem düzeyi yerine sınıf düzeyinde kullanılabilirse, daha da ideal olacaktır.
Richard

Bunu tercih ederim, çünkü bu testin şartlı olarak çalışma zamanında yapılmasına yardımcı olur. Bir dizi birim testinin yapılacağı yere uygundur ve gereklilik, birim testlerini belirli bir denetleyicide yapmaktır. Junit-ext'in maven deposunda bulunmadığını görmek beni gerçekten şaşırttı. Bunu maven projesinde nasıl elde edebiliriz.
shambhu

4
Bir ek açıklama @RunIf, bir testin gerçek test kodundan çalıştırılması gerektiğinde durumu ayırır, ki bu iyi olduğunu düşünüyorum. Sevmediğim şey, belirli bir test koşucusu gerektirmesidir. Bu nedenle testleri koşulsuz olarak göz ardı etmek için bir JUnit kuralı yazdım .
Rüdiger Herrmann

2
Yerel depomuza junit-ext kavanozunu (burada code.google.com/p/junit-ext/downloads/… ) kurduktan ve bu @RunIf ek açıklamasını uyguladıktan sonra ... hiçbir şey! Tamamen görmezden gelinmiştir ve bence sebebi junit-ext'in junit 4.5'e bağlı gibi görünmesidir. Bahar testi nedeniyle 4.9+ 'a ihtiyacımız var. Yani ... boş ver.
Marc

7

JUnit 4'te, sizin için başka bir seçenek, testin özel ölçütlerinizi karşılaması gerektiğini belirtmek için bir ek açıklama oluşturmak, ardından varsayılan koşucuyu kendinizle genişletmek ve yansımayı kullanmak, kararınızı özel ölçütlere dayandırmak olabilir. Şuna benzeyebilir:

public class CustomRunner extends BlockJUnit4ClassRunner {
    public CTRunner(Class<?> klass) throws initializationError {
        super(klass);
    }

    @Override
    protected boolean isIgnored(FrameworkMethod child) {
        if(shouldIgnore()) {
            return true;
        }
        return super.isIgnored(child);
    }

    private boolean shouldIgnore(class) {
        /* some custom criteria */
    }
}

Bu güzel ve temiz görünse de, JUnit4 ise mevcut sürümlerle çalışmaz, çünkü artık yöntemi BlockJUnit4ClassRunnersunmamaktadır isIgnored.
Dave

-2

Kısa bir not: Assume.assumeTrue(condition)adımların geri kalanını yoksayar, ancak testi geçer. Testte başarısız olmak için org.junit.Assert.fail()koşullu deyimin içinde kullanın . Aynı şekilde çalışır, Assume.assumeTrue()ancak testi geçemez.


5
Başarısız bir varsayım yoktur, yukarıdaki cevapları belirtildiği gibi değil testi geçmek diye, bu ayrı bir statü verir. Bazı koşucular bunu bir geçişmiş gibi hatalı olarak bildirebilir , ancak bu test çalıştırıcısında bir zayıflık / hata (ve varsayılan JUnit koşucusu testi yok sayılmış olarak görüntüler). Ve son cümlenize gelince, sınavın başarısız olması özellikle yapmamı istediğim şey değildir.
Andrzej Doyle

Ah tamam. Testler benim durumumda başarısız varsayımdan geçti ama bunların başarısız olarak bildirilmesini istedim (Test Watcher'dan bir istisna kontrol ediyordum). Başarısızlığı zorlamak bana yardımcı oldu.
TIN TIn
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.