JUnit 4의 조건부 테스트 무시


365

OK, 그래서 @Ignore주석은 테스트 케이스를 실행되어서는 안된다는 표시에 좋습니다.

그러나 때로는 런타임 정보를 기반으로 한 테스트를 무시하고 싶습니다. 예를 들어 특정 수의 코어가있는 머신에서 동시성 테스트를 실행 해야하는 경우가 있습니다. 이 테스트가 단일 프로세서 컴퓨터에서 실행 되었다면 테스트를 통과하는 것이 옳지 않다고 생각합니다 (실행되지 않았기 때문에) 테스트를 실패하고 빌드를 중단하는 것이 옳지 않을 것이라고 생각합니다 .

따라서 테스트 결과가 올바른 결과처럼 보이기 때문에 런타임에 테스트를 무시하고 싶습니다 (테스트 프레임 워크가 빌드를 통과하지만 테스트가 실행되지 않았 음을 기록하기 때문에). 주석이 이러한 유연성을 제공하지 않을 것이라고 확신하며 문제의 클래스에 대한 테스트 스위트를 수동으로 만들어야한다고 생각합니다. 그러나 설명서에는 이것에 대한 언급이 없으며 API 를 통해 어떻게 프로그래밍 방식으로 수행되는지 명확하지 않습니다 (즉 Test, @Ignore주석으로 생성 된 것과 동등한 인스턴스 또는 유사한 인스턴스를 어떻게 프로그래밍 방식으로 작성 합니까?).

과거에 누군가가 비슷한 일을했거나 다른 일을 어떻게 할 수 있는지에 대한 밝은 생각을 가지고 있다면 그것에 대해 기뻐할 것입니다.

답변:


476

JUnit 방법은 런타임에 이것을하는 것입니다 org.junit.Assume.

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

@Before메소드 또는 테스트 자체에서 수행 할 수 있지만 메소드 에서는 수행 할 수 없습니다 @After. 테스트 자체에서 수행하면 @Before메소드가 실행됩니다. 당신은 또한 @BeforeClass클래스 초기화를 방지하기 위해 그것을 할 수 있습니다 .

가정 실패로 인해 테스트가 무시됩니다.

편집 : junit-ext@RunIf주석 과 비교하기 위해 샘플 코드는 다음과 같습니다.

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

Database.connect()이 방법으로 연결을 캡처하고 사용하는 것이 훨씬 쉽다는 것은 말할 것도 없습니다 .


1
@ notnoop, 그건 내 관찰이 아닙니다. 그들은 무시됩니다. IDEA 테스트 러너는 이러한 방식으로보고하고 JUnit 소스 코드를 보면 테스트가 무시 된 것으로보고 함을 알 수 있습니다.
Yishai

1
인용 : "앞으로, 이것은 변경 될 수 있으며 실패한 가정은 테스트를 무시할 수 있습니다." 실제로 4.5를 기준으로 변경되었습니다. 현재의 Javadoc은 "기본 JUnit 러너는 실패한 가정이있는 테스트를 무시 된 것으로 간주합니다. 사용자 정의 러너는 다르게 동작 할 수 있습니다." github.com/KentBeck/junit/blob/…
Yishai

4
Junit 4.8.1이 포함 된 Eclipse 3.6은 잘못된 가정을 통과 테스트로보고합니다. 개미 1.8.1과 동일합니다.
fijiaaron

8
이클립스는 전달이 버그라고 가정했다. 버그 : bugs.eclipse.org/bugs/show_bug.cgi?id=359944
Martin

1
@JeffStorey, 당신은 몇 가지를 찾고 있습니다. 하나는 @BeforeClass주석인데, 여기에서 가정을 실패하게하면 전체 클래스를 건너 뜁니다. 다른 하나는 @ClassRule(세밀한 제어를 위해, 한 번 전체 클래스에 걸쳐)입니다.
Yishai

51

Junit-ext프로젝트 를 체크 아웃해야합니다 . 그들은이 RunIf주석을 그 수행 조건 테스트, 같은 :

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

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

[자습서에서 가져온 코드 샘플]


3
이 답변에 감사드립니다. 기능에 대한 흥미로운 대안 구문이지만 Assume다른 종속성을 도입하지 않기 위해 직접 진행할 것입니다 .
Andrzej Doyle

3
개인적으로이 솔루션을 선호합니다. 동일한 조건을 기반으로 실행해야하는 테스트가 많은 경우 모든 테스트에서 가정을 사용하는 것보다 훨씬 이상적입니다. 또한, 이것이 메소드 레벨이 아닌 클래스 레벨에서 사용될 수 있다면 더욱 이상적입니다.
Richard

'cuz는 런타임에 조건부로 테스트를 실행하는 데 도움이됩니다. 여러 단위 테스트가 실행될 위치에 적합하며 특정 검사기에서 단위 테스트를 실행해야합니다. junit-ext를 maven 저장소에서 사용할 수 없다는 사실에 정말 놀랐습니다. 우리는 어떻게 maven 프로젝트에서 이것을 이용할 수 있습니까?
shambhu

4
@RunIf테스트 와 같은 주석은 테스트가 실제 테스트 코드에서 실행될 때 조건을 분리합니다. 내가 싫어하는 것은 특정 테스트 러너가 필요하다는 것입니다. 따라서 테스트를 조건부로 무시하기 위해 JUnit 규칙 을 작성했습니다 .
Rüdiger Herrmann 11

2
로컬 저장소에 junit-ext jar (여기에서 code.google.com/p/junit-ext/downloads/… )를 설치하고 @RunIf 주석을 구현 한 후 ... 아무것도! 그것은 완전히 무시되고 junit-ext가 junit 4.5에 의존하는 것처럼 보일 수 있습니다. 스프링 테스트로 인해 4.9 이상이 필요합니다. 그러니 ... 신경 쓰지 마
Marc

7

JUnit 4에서 다른 옵션은 테스트가 사용자 정의 기준을 충족해야 함을 표시하기 위해 주석을 작성한 다음 기본 러너를 사용자 자신의 기준으로 확장하고 리플렉션을 사용하여 사용자 정의 기준에 따라 결정을 내릴 수 있습니다. 다음과 같이 보일 수 있습니다.

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 */
    }
}

이 방법은 깔끔하고 깔끔하지만 JUnit4의 경우 더 이상 메소드를 BlockJUnit4ClassRunner제공하지 않으므로 현재 버전에서는 작동 하지 않습니다 isIgnored.
Dave

-2

빠른 참고 사항 : Assume.assumeTrue(condition)나머지 단계는 무시하지만 테스트는 통과합니다. 테스트에 실패하려면 org.junit.Assert.fail()조건문 내부를 사용 하십시오. 동일하게 작동 Assume.assumeTrue()하지만 테스트에 실패합니다.


5
위의 답변에서 언급했듯이 실패한 가정은 테스트를 통과 시키지 않으며 별도의 상태를 반환합니다. 일부 러너는 이것을 패스 인 것처럼 잘못보고 할 수 있지만 테스트 러너의 약점 / 버그입니다 (그리고 기본 JUnit 러너는 테스트를 무시한 것으로 표시합니다). 그리고 마지막 문장에 관해서는, 시험에 실패하는 것이 구체적으로 내가 원하는 (원하는) 것이 아닙니다.
Andrzej Doyle

오 그래. 필자의 경우 테스트가 실패한 가정을 통과했지만 실패한 것으로보고되기를 원했습니다 (Test Watcher에서 예외를 확인하고있었습니다). 실패를 강요하면 도움이되었습니다.
Tin TIn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.