2008-12-08 35 views
23

Bazı (sınanmış) web servisinde bazı işlev testleri yapmak istiyorum. Testsuite, her biri web servisinde bir kaç HTTP isteği gerçekleştiren bir dizi test vakası içerir. Doğal olarak, web servisinin çalışması gerekir veya testler başarısız olacaktır. :-)JUnit 4: Testler çalıştırılmadan önce bir test paketinde (bir testin @BeforeClass yöntemi gibi, sadece bir test paketi için) bir şeyleri kurun

Web servisinin başlatılması birkaç dakika sürer (bazı ağır veri kaldırma işlemleri yapar), bu yüzden mümkün olduğunca seyrek başlatmak istiyorum (en azından hizmetten yalnızca GET kaynaklarının paylaşabileceği tüm test durumları).

Testler, bir test vakasının @BeforeClass yönteminde olduğu gibi testler yapılmadan önce, test paketindeki bombayı ayarlamak için bir yol var mı?

cevap

1

jUnit bu tür bir şey yapamaz - TestNG'de @BeforeSuite ve @AfterSuite ek açıklamaları bulunur. Normalde, yapım sisteminizin bunu yapmasını sağlarsınız. Maven'de, "ön entegrasyon testi" ve "post-entegrasyon testi" aşamaları vardır. ANT'de, sadece görev için gereken adımları ekleyin.

Sorunuz, hemen hemen Before and After Suite execution hook in jUnit 4.x numaralı dosyanın bir kopyasıdır, bu yüzden önerileri inceleyeceğim. Bir kenara

+0

Neden BeforeSuite ve AfterSuite çalışmaz:

İlk süit tanımı:

import org.junit.*; import org.junit.rules.ExternalResource; import org.junit.runners.Suite; import org.junit.runner.RunWith; @RunWith(Suite.class) @Suite.SuiteClasses({ RuleTest.class, }) public class RuleSuite{ private static int bCount = 0; private static int aCount = 0; @ClassRule public static ExternalResource testRule = new ExternalResource(){ @Override protected void before() throws Throwable{ System.err.println("before test class: " + ++bCount); sss = "asdf"; }; @Override protected void after(){ System.err.println("after test class: " + ++aCount); }; }; public static String sss; } 

Ve şimdi Test sınıf tanımı? – guerda

-3

, aslında dış vs.

Birim testleri çalıştırmak için süper hızlı olmalı webservices, veritabanları gibi kaynaklar ve bir gecikme 'bir çift dakika' çağıran birim testleri için kötü bir fikirdir Suite'in her koşusu için, gerektiği kadar koşmayacağı anlamına gelecektir.

Benim tavsiyem: EasyMock gibi bir şey (http://www.easymock.org/) ile birim testlerinde dış bağımlılıkları alay de

bak.

Fitnesse (http://fitnesse.org/) veya test ortamına karşı çalışan ve sürekli olarak devam eden bir evde yetiştirilen çözümle ayrı bir bütünleştirme testleri paketi oluşturun.

+0

Merhaba nick, benim birim testlerim bu tür şeyler yapmıyor ve superquick. İşlevsel testler hakkında konuşuyordum :-) –

0

Bir seçenek, birim test paketinizi başlatmak için Apache Ant gibi bir şey kullanmaktır. senin webservice başlatmak ve durdurmak için önce ve junit hedefinin sonra Ardından bir hedef çağırmayı koyabilirsiniz:

<target name="start.webservice"><!-- starts the webservice... --></target> 
<target name="stop.webservice"><!-- stops the webservice... --></target> 
<target name="unit.test"><!-- just runs the tests... --></target> 

<target name="run.test.suite" 
     depends="start.webservice, unit.test, stop.webservice"/> 

Ardından karınca kullanarak paketi (veya tercih ettiğiniz entegrasyon aracı) çalıştırın. Çoğu IDE'nin Ant desteği vardır ve testlerinizi sürekli bir entegrasyon ortamına taşımayı çok daha kolay hale getirir (birçoğu kendi testlerini tanımlamak için Ant hedeflerini kullanır).

21

Yanıt, şimdi süitinizde @ClassRule oluşturmaktır. Kural, her test sınıfının çalıştırılmasından önce veya sonra (nasıl uyguladığınıza bağlı olarak) çalıştırılacaktır. Uzatabileceğiniz/uygulayabileceğiniz birkaç farklı temel sınıf vardır. Sınıf kuralları hakkında hoş olan şey, onları anonim sınıflar olarak uygulamamanız halinde kodu tekrar kullanabilmenizdir! İşte http://java.dzone.com/articles/junit-49-class-and-suite-level-rules

kullanımlarını göstermek için örnek kod: Burada

onlar hakkında bir makale. Evet, önemsiz, ama başlamanız için yaşam döngüsünü yeterince iyi göstermelidir.

import static org.junit.Assert.*; 

import org.junit.ClassRule; 
import org.junit.Rule; 
import org.junit.Test; 
import org.junit.rules.ExternalResource; 

public class RuleTest { 

    @Test 
    public void asdf1(){ 
     assertNotNull("A value should've been set by a rule.", RuleSuite.sss); 
    } 

    @Test 
    public void asdf2(){ 
     assertEquals("This value should be set by the rule.", "asdf", RuleSuite.sss); 
    } 
} 
+0

"Kural, her bir test sınıfının çalıştırılmasından önce veya sonra çalıştırılacak (her bir test sınıfı çalıştırılıyor" - Bunu doğrulayamıyorum. Suite'e iki Test dersi eklemiş olmama rağmen, ClassRule'ımın() yönteminin yalnızca bir kez çağrıldı. –

+0

Gerçekten de, kural, belirli bir uygulamaya bağlı olarak test sınıfından önce veya sonra çalıştırılacaktır. ** @ ArtB ** tarafından sağlanan örnekte kural, süit düzeyinde uygulanmaktadır. Bu nedenle, suitteki tüm testlerin çalıştırılmasından önce bir kez çağrılacak ve süitdeki tüm testler bir kez çalıştırıldıktan sonra bir kez çağrılacaktır. Yani ** @ ArtB ** 'nin cevabı iyi çalışıyor. – flaz14