Junit: bölme entegrasyon testi ve Birim testleri


126

Bir miktar Junit testi miras aldım, ancak bu testler (çalışmayanların çoğu dışında) gerçek birim testi ve entegrasyon testlerinin bir karışımıdır (harici sistemler, db vb. Gerektirir).

Bu yüzden onları gerçekten ayırmanın bir yolunu bulmaya çalışıyorum, böylece birim testini güzel ve hızlı bir şekilde çalıştırabilirim ve bundan sonra entegrasyon testleri yapabilirim.

Seçenekler ...

  1. Bunları ayrı dizinlere ayırın.

  2. Junit4'e (v3'ten) geçin ve sınıfları ayırmak için not ekleyin.

  3. Bir sınıfın ne olduğunu söylemek için bir dosya adlandırma kuralı kullanın, örneğin AdapterATest ve AdapterAIntergrationTest.

3, Eclipse'in "Seçilen proje / paket veya klasördeki tüm testleri çalıştır" seçeneğine sahip olması sorununa sahiptir. Bu yüzden sadece entegrasyon testlerini çalıştırmak çok zor olurdu.

2: geliştiricilerin birim test sınıflarında entegrasyon testleri yazmaya başlaması riskini taşır ve işler karışır.

1: En iyi çözüm gibi görünüyor, ancak içimden gelen sesler daha iyi bir çözüm olması gerektiğini söylüyor.

Öyleyse sorum şu, entegrasyon testlerini ve uygun birim testlerini nasıl ayırırsınız?


Sadece girdileriniz için hepinize teşekkür etmek istiyorum, bunun öznel bir soru olduğunu ve tek bir doğru cevap olmadığını biliyorum. Ama listelediklerimden başka seçenek olmadığını anlamama yardım ettin. Sanırım şimdilik dizin yapısına gideceğim ve JUnit4'e geçeceğim, ancak henüz onları bölmek için ek açıklamaları kullanmayacağım.
jeff porter

Yanıtlar:


10

Şu anda kurumsal politika (ve Junit 3 eski) nedeniyle ayrı dizinler kullanıyorum ancak şu anda 4 Hazirandayım.

Geliştiricilerin birim test sınıflarınıza entegrasyon testleri koyması konusunda fazla endişelenmem - gerekirse kodlama standartlarınıza bir kural ekleyin.

Ek açıklamalar veya sınıfları fiziksel olarak ayırmanın dışında ne tür başka çözümler olabileceğini bilmekle ilgileniyorum.


145

JUnit kategorilerini ve Maven'i kullanarak bunları çok kolay bir şekilde bölebilirsiniz.

Bu, aşağıda bölme birimi ve entegrasyon testleri ile çok, çok kısaca gösterilmiştir.

Bir Marker Arayüzü Tanımlayın

Kategorileri kullanarak bir testi gruplandırmanın ilk adımı, bir işaretleyici arabirimi oluşturmaktır.

Bu arayüz, çalıştırılmasını istediğiniz tüm testleri entegrasyon testleri olarak işaretlemek için kullanılacaktır.

public interface IntegrationTest {}

Test sınıflarınızı işaretleyin

Kategori açıklamasını test sınıfınızın en üstüne ekleyin. Yeni arayüzünüzün adını alır.

import org.junit.experimental.categories.Category;
@Category(IntegrationTest.class)
public class ExampleIntegrationTest{
  @Test
  public void longRunningServiceTest() throws Exception {
  }
}

Maven Birim Testlerini Yapılandırın

Bu çözümün güzelliği, şeylerin birim testi tarafında gerçekten hiçbir şeyin değişmemesidir.

Herhangi bir entegrasyon testini göz ardı etmesini sağlamak için maven surefire eklentisine bazı konfigürasyonlar ekliyoruz.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.11</version>
  <dependencies>
   <dependency>
     <groupId>org.apache.maven.surefire</groupId>
     <artifactId>surefire-junit47</artifactId>
     <version>2.12</version>
   </dependency>
  </dependencies>
  <configuration>
    <includes>
      <include>**/*.class</include>
    </includes>
    <excludedGroups>com.test.annotation.type.IntegrationTest</excludedGroups>
  </configuration>
</plugin>

Bir mvn temizleme testi yaptığınızda, yalnızca işaretlenmemiş birim testleriniz çalışacaktır.

Maven Entegrasyon Testlerini Yapılandırın

Yine bunun için konfigürasyon çok basit.

Yalnızca entegrasyon testlerini çalıştırmak için şunu kullanın:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.11</version>
  <dependencies>
   <dependency>
     <groupId>org.apache.maven.surefire</groupId>
     <artifactId>surefire-junit47</artifactId>
     <version>2.12</version>
   </dependency>
  </dependencies>
  <configuration>
    <groups>com.test.annotation.type.IntegrationTest</groups>
  </configuration>
</plugin>

Bunu kimliğiyle bir profile sararsanız IT, yalnızca kullanarak hızlı testleri çalıştırabilirsiniz mvn clean install. Yalnızca entegrasyon / yavaş testleri çalıştırmak için mvn clean install -P IT.

Ancak çoğu zaman, hızlı testleri varsayılan olarak ve tüm testleri ile çalıştırmak isteyeceksiniz -P IT. Durum buysa, bir numara kullanmanız gerekir:

<profiles>
    <profile>
        <id>IT</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <excludedGroups>java.io.Serializable</excludedGroups> <!-- An empty element doesn't overwrite, so I'm using an interface here which no one will ever use -->
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

Gördüğünüz gibi, ile not verilen testleri hariç tutuyorum java.io.Serializable. Profil, Surefire eklentisinin varsayılan yapılandırmasını devralacağı için bu gereklidir, bu nedenle <excludedGroups/>veya deseniz bile <excludedGroups></excludedGroups>değer com.test.annotation.type.IntegrationTestkullanılacaktır.

Ayrıca none, sınıf yolunda bir arayüz olması gerektiğinden de kullanamazsınız (Maven bunu kontrol edecektir).

Notlar:

  • Bağımlılık surefire-junit47yalnızca Maven JUnit 4 çalıştırıcısına otomatik olarak geçmediğinde gereklidir. Kullanılması groupsveya excludedGroupseleman anahtarını tetikler. Buraya bakın .
  • Yukarıdaki kodun çoğu, Maven Failsafe eklentisinin belgelerinden alınmıştır. Bu sayfadaki "JUnit Kategorilerini Kullanma" bölümüne bakın .
  • Testlerim sırasında, @RunWith()paketleri veya Bahar tabanlı testleri çalıştırmak için ek açıklamaları kullandığınızda bile bunun işe yaradığını gördüm .

18
Sanırım son pom.xml parçanızda bir hata var. "test" aşamasıyla aynı pasajı yapıştırdınız. yine de entegrasyon testlerini hariç tutar ve ayrıca herhangi bir maven aşamasına bağlı değildir.
Alex

1
Nitekim, son pom parçası bir kopyala ve yapıştır hatasıdır. Maven-failsafe eklentisini göstermelidir.
Paulo Merson

2
Öyleyse ikinci xml ne olmalı? : O
Liv

Varsayılan Maven profilini kullanıyorsanız, hileyi (Serileştirilebilir ile son sihir) kullanmak zorunda değilsiniz
user831217

Bu gerçekten kabul edilen cevap olmalı çünkü bu, farklı testlerin nereye yerleştirileceğine dair felsefi bir tartışma yerine aslında sorunun çözümü.
Bwvolleyball

40

Birim testlerini çalıştırmak için Maven Surefire Eklentisini ve entegrasyon testlerini çalıştırmak için Maven Failsafe Eklentisini kullanıyoruz. Birim testleri **/Test*.java **/*Test.java **/*TestCase.javaadlandırma kurallarını, entegrasyon testlerini takip eder -**/IT*.java **/*IT.java **/*ITCase.java . Yani aslında üçüncü seçeneğiniz.

Birkaç projede TestNG kullanıyoruz ve entegrasyon / birim testleri için farklı test grupları tanımlıyoruz, ancak bu muhtemelen sizin için uygun değildir.


1
Maven + surefire + failsafe + junit combo için +1. Arıza güvenliğinin otomatik olarak "BT *" çalıştıracağını bilmiyordum. Tatlı.
PapaFreud

13

Junit4'e sadece sahip olduğum için geçecektim :)

Bunları farklı test süitlerine ayırabilirsiniz. Junit3'te nasıl organize edildiklerini bilmiyorum ama Junit4'te sadece test takımları oluşturmak ve tüm gerçek birim testlerini bunlardan birine koymak ve sonra entegrasyon testleri için ikinci bir paket kullanmak kolay olmalı.

Şimdi tutulmadaki her iki süit için bir çalıştırma yapılandırması tanımlayın ve tek bir paketi kolayca çalıştırabilirsiniz. Bu paketler ayrıca, kaynak her değiştiğinde birim testlerini ve belki entegrasyon testlerini (gerçekten büyükse) yalnızca günde bir kez veya saatte bir kez çalıştırmanıza olanak tanıyan otomatik bir süreçten başlatılabilir.


9

Kullanılması IfProfileValue bahar ek açıklama mümkün bunu başarmak için yapar olmadan gerekli bir maven eklenti veya yapılandırma.

IfProfileValue kullanarak entegrasyon testi sınıflarına veya yöntemlerine açıklama ekleyin

import org.springframework.test.annotation.IfProfileValue;

@IfProfileValue(name="test-groups", value="integration")
public class ExampleIntegrationTest{
    @Test
    public void longRunningServiceTest() throws Exception {
    }
} 

Yalnızca birim testlerini kullanarak çalıştırmak için:

mvn clean test

Entegrasyon testi ve birim testleri kullanarak çalıştırmak için:

mvn clean test -Dtest-groups=integration

Ayrıca, bir IDE'deki "Tüm testi çalıştır" yalnızca birim testini çalıştırır. -Dtest-groups=integrationHem entegrasyon hem de birim testlerini çalıştırmak için VM bağımsız değişkenlerine ekleyin .


Bu yaklaşım güzel ve basit, ancak bulduğum sorun, varsayılan olarak tüm testleri (entegrasyon testleri dahil) çalıştırmak istemem. Bu yaklaşımla bu mümkün değil, değil mi?
csalazar

6

Tek bir doğru cevap yok. Açıkladığınız gibi, işe yarayacak birkaç yolu vardır. Hem dosya adlandırma şemasını hem de işleri farklı dizinlere böldüm.

Bir şeyi farklı dizinlere bölmek sizin için daha iyi olabilir gibi geliyor ve bu bana biraz daha net geliyor, bu yüzden buna eğiliyorum.

Ek açıklamaları deneyeceğimi sanmıyorum çünkü bu bana daha ayrıntılı görünüyor. Bu iki tür testin aynı dosyada karıştırılmasını gerçekten istiyor musunuz? Yapmazdım.

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.