Junit : 분할 통합 테스트 및 단위 테스트


126

Junit 테스트를 상속 받았지만이 테스트 (실제로 작동하지 않는 것)는 실제 단위 테스트와 통합 테스트 (외부 시스템, db 등 필요)가 혼합되어 있습니다.

그래서 실제로 단위 테스트를 훌륭하고 신속하게 수행하고 그 후에 통합 테스트를 실행할 수 있도록 실제로 분리하는 방법을 생각하고 있습니다.

옵션은 ..

  1. 별도의 디렉토리로 분할하십시오.

  2. Junit4 (v3에서)로 이동하고 클래스에 주석을 달아 분리하십시오.

  3. 파일 명명 규칙을 사용하여 클래스가 무엇인지 (예 : AdapterATest 및 AdapterAIntergrationTest) 알 수 있습니다.

3에는 Eclipse에 "선택한 프로젝트 / 패키지 또는 폴더에서 모든 테스트 실행"옵션이 있습니다. 따라서 통합 테스트를 실행하기가 매우 어렵습니다.

2 : 개발자가 단위 테스트 클래스에서 통합 테스트 작성을 시작할 위험이 있으며 지저분 해집니다.

1 : 가장 까다로운 솔루션처럼 보이지만 내 직감은 더 나은 솔루션이 있어야한다고 말합니다.

그래서 제 질문입니다. 통합 테스트와 적절한 단위 테스트를 어떻게 분리합니까?


여러분의 의견을 보내 주셔서 감사합니다. 이것은 주관적인 질문이며 정답이 아니라는 것을 알고 있습니다. 그러나 당신은 내가 나열된 것 외에 다른 옵션이 없다는 것을 깨닫게 도와주었습니다. 나는 아직 디렉토리 구조를 가지고 JUnit4로 옮길 것이라고 생각하지만, 아직 주석을 나누기 위해 주석을 사용하지는 않는다.
제프 포터

답변:


10

나는 현재 조직 정책 (및 Junit 3 레거시)으로 인해 별도의 디렉토리를 사용하고 있지만 지금은 Junit 4에 있습니다.

단위 테스트 클래스에 통합 테스트를하는 개발자에 대해서는 크게 걱정하지 않을 것입니다. 필요한 경우 코딩 표준에 규칙을 추가하십시오.

주석이나 클래스를 물리적으로 분리하는 것 외에 어떤 다른 솔루션이 있는지 알고 싶습니다.


145

JUnit 카테고리와 Maven을 사용하여 매우 쉽게 분할 할 수 있습니다.

이것은 단위 및 통합 테스트를 분할하여 아래에 매우 간략하게 표시됩니다.

마커 인터페이스 정의

카테고리를 사용하여 테스트를 그룹화하는 첫 번째 단계는 마커 인터페이스를 만드는 것입니다.

이 인터페이스는 통합 테스트로 실행하려는 모든 테스트를 표시하는 데 사용됩니다.

public interface IntegrationTest {}

테스트 클래스를 표시하십시오

테스트 클래스 상단에 카테고리 주석을 추가하십시오. 새 인터페이스의 이름을 사용합니다.

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

메이븐 유닛 테스트 구성

이 솔루션의 장점은 사물의 단위 테스트 측면에서 실제로 변화가 없다는 것입니다.

우리는 통합 테스트를 무시하도록 구성을 maven surefire 플러그인에 추가하기 만하면됩니다.

<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>

mvn clean 테스트를 수행하면 표시되지 않은 단위 테스트 만 실행됩니다.

Maven 통합 테스트 구성

다시 이것에 대한 구성은 매우 간단합니다.

통합 테스트 만 실행하려면 다음을 사용하십시오.

<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>

id가있는 프로파일에서 이것을 랩핑하면을 IT사용하여 빠른 테스트 만 실행할 수 있습니다 mvn clean install. 통합 / 느린 테스트 만 실행하려면을 사용하십시오 mvn clean install -P IT.

그러나 대부분의 경우 기본적으로 빠른 테스트를 실행하고을 사용하여 모든 테스트 를 수행하려고합니다 -P IT. 이 경우 트릭을 사용해야합니다.

<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>

보시다시피, 주석이 달린 테스트는 제외합니다 java.io.Serializable. 프로파일이 확실한 플러그인의 기본 설정을 상속하기 때문에 당신이 말하는 그래서 경우에도 필요 <excludedGroups/>하거나 <excludedGroups></excludedGroups>, 값이 com.test.annotation.type.IntegrationTest사용됩니다.

none클래스 패스의 인터페이스이므로 사용할 수 없습니다 (Maven이 이것을 확인합니다).

노트:

  • surefire-junit47Maven이 JUnit 4 러너로 자동 전환되지 않는 경우에만 종속성 이 필요합니다. groups또는 excludedGroups요소를 사용하면 스위치가 트리거되어야합니다. 여기를 참조하십시오 .
  • 위의 코드 대부분은 Maven Failsafe 플러그인 설명서에서 가져 왔습니다. 이 페이지의 "JUnit 카테고리 사용"섹션을 참조 하십시오 .
  • 테스트하는 동안 @RunWith()주석이나 스위트 를 사용 하여 스프링 기반 테스트를 실행할 때도 작동한다는 것을 알았습니다 .

18
마지막 pom.xml 조각에 오류가 있다고 생각합니다. '테스트'단계와 동일한 스 니펫을 붙여 넣었습니다. 그것은 여전히 ​​통합 테스트를 제외하고 어떤 maven 단계에도 구속되지 않습니다.
Alex

1
실제로 마지막 pom 조각은 복사 및 붙여 넣기 실수입니다. maven-failsafe-plugin이 표시되어야합니다.
Paulo Merson

2
그렇다면 두 번째 XML은 무엇입니까? : O
Liv

당신은 당신이 기본 메이븐 프로파일을 사용하는 경우 트릭 (직렬화와 마지막 마법)을 사용할 필요가 없습니다
user831217

이것은 실제로 다른 대답을 할 곳에 대한 철학적 토론 대신 질문에 대한 해결책이기 때문에 실제로 받아 들여지는 대답이어야합니다.
Bwvolleyball

40

Maven Surefire 플러그인을 사용하여 단위 테스트를 실행하고 Maven Failsafe 플러그인을 사용하여 통합 테스트를 실행합니다. 단위 테스트는 **/Test*.java **/*Test.java **/*TestCase.java명명 규칙, 통합 테스트-를 따릅니다 **/IT*.java **/*IT.java **/*ITCase.java. 실제로 옵션 번호 3입니다.

몇 가지 프로젝트에서 우리는 TestNG를 사용하고 통합 / 단위 테스트를 위해 다른 테스트 그룹을 정의하지만 이것은 아마도 당신에게 적합하지 않을 것입니다.


1
maven + surefire + failsafe + junit 콤보의 경우 +1 안전 장치가 "IT *"를 자동으로 실행한다는 것을 몰랐습니다. 단.
PapaFreud

13

나는 그것을 가지고 있기 때문에 Junit4로 올라갈 것입니다 :)

서로 다른 테스트 스위트로 분리 할 수 ​​있습니다. Junit3에서 어떻게 구성되는지 모르겠지만 Junit4에서는 테스트 스위트를 구축하고 그 중 하나에 모든 실제 단위 테스트를 배치 한 다음 통합 테스트를 위해 두 번째 스위트를 사용하는 것이 쉬워야합니다.

이제 이클립스에서 두 제품군에 대한 실행 구성을 정의하면 단일 제품군을 쉽게 실행할 수 있습니다. 이 제품군은 자동화 된 프로세스에서 시작하여 소스가 변경 될 때마다 단위 테스트를 실행할 수 있으며 통합 테스트 (실제로 큰 경우)는 하루에 한 번 또는 한 시간에 한 번만 실행할 수 있습니다.


9

사용 IfProfileValue의 봄 주석하는 것은 가능이를 달성 할 수 없이 필요한 Maven 플러그인 또는 구성.

IfProfileValue를 사용하여 통합 테스트 클래스 또는 메소드에 주석 달기

import org.springframework.test.annotation.IfProfileValue;

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

단위 테스트 만 사용하여 실행하려면 다음을 수행하십시오.

mvn clean test

통합 테스트 및 단위 테스트를 사용하여 실행하려면 다음을 수행하십시오.

mvn clean test -Dtest-groups=integration

또한 IDE의 "모든 테스트 실행"은 단위 테스트 만 실행합니다. -Dtest-groups=integrationVM 인수에 추가 하여 통합 및 단위 테스트를 모두 실행하십시오.


이 방법은 훌륭하고 간단하지만 기본적으로 모든 테스트 (통합 테스트 포함)를 실행하고 싶습니다. 이 방법으로는 불가능합니다. 그렇지 않습니까?
csalazar

6

정답이 하나도 없습니다. 설명했듯이 작동하는 몇 가지 방법이 있습니다. 파일 이름 지정 체계와 작업을 다른 디렉토리로 나누었습니다.

그것은 다른 디렉토리로 나누는 것이 당신에게 더 효과적 일 수있는 것처럼 들립니다.

주석이 더 세밀 해 보이므로 주석을 사용하지 않을 것이라고 생각합니다. 이 두 가지 유형의 테스트를 동일한 파일에 함께 혼합 하시겠습니까? 나는하지 않을 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.