본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[Effective Unit Testing] Appendix B. JUnit 확장하기

by 돼지왕 왕돼지 2019. 3. 29.
반응형

[Effective Unit Testing] Appendix B. JUnit 확장하기


@ignore, @RunWith, @test(timeout = ), junit annotation, junit rule, junit runner, junit 확장, methodrule, parameterized runner, RULE, rule must be public, Suite, suite runner, TemporaryFolder, testcase, timeout, what is junit runner, what is rule junit, [Effective Unit Testing] Appendix B. JUnit 확장하기, 개별 메서드 타임아웃, 전역 타임아웃, 테스트 실행 계획

-

JUnit 4.0 버전에 와서야 junit.framework.TestCase 로부터 벗어나게 되었다.

그전까지는 모든 테스트가 TestCase 클래스를 상속해야 했기 때문에 이렇게 상속받은 동작 일부를 오버라이딩하는 것 말고는 JUnit 의 기능을 확장할 방법이 없었다.

하지만, annotation 을 적극 수용한 버전에서는 훨씬 자유롭고 유연한 annotation 을 이용해 JUnit 을 확장할 수 있도록 바뀌었다.



-

JUnit 의 기본 동작을 확장하려면 Runner 와 Rule 의 핵심 개념을 활용해야 한다.





B.1. Runner 를 통해 테스트 동작 제어하기


-

@RunWtih annotation 을 따로 명시하지 않으면 JUnit 은 항시 기본 러너를 사용한다.



-

JUnit 에 클래스 하나를 건네주며 "실행해"라고 말하면 JUnit 은 뒷주머니에서 조그마한 메모지 한장을 꺼내 든다.

메모지에는 테스트를 실행할 수 있는 도구 목록이 적혀있다.

그 도구는 모두 org.junit.runner.Runner 인터페이스를 구현한 것들이다.


JUnit 은 위에서부터 차례로 목록을 훑으며 주어진 클래스를 다룰 수 있는 러너를 찾는다.

예를 들어 목록의 최상단에 자리한 러너는 @Ignore annotation 에 부여된 클래스를 다룰 수 있다.

두번째로는 @RunWith annotation 을 가지고 있는 클래스를 다루는 러너가 적혀 있다.

기본 러너는 가장 아래에 적혀 있다.

@RunWith 에 적힌 runner 가 있다면 해당 러너에 테스트 실행을 위임한다.

JUnit 은 이 중 하나를 선택해서 테스트를 실행한다.



-

@RunWith annoation 은 JUnit 에 테스트 클래스를 어떻게 다루라고 지시할 때 사용한다.

Suite 나 Parameterized 와 같은 표준 러너뿐 아니라 우리가 직접 작성한 러너를 사용하라고 명령할 수도 있다.



-

사용자 정의 러너를 작성하는 게 JUnit 을 확장하는 가장 강력한 수단임은 분명한 사실이지만, 생각보다 벅찬 도전이 될수도 있다.

새로운 러너를 만들지 않더라도 JUnit 에 바라는 추가 기능 대부분을 해결해줄 대안이 있다.

클래스에서 테스트를 찾는 방법까지 바꾸려는 것만 아니면 사용자 정의 러너보다 Rule 을 활용하는 것이 좋다.





B.2. Rule 로 테스트 꾸미기


-

Rule 은 테스트 실행 방식을 조작하는 능력을 가졌다.

한 예로 규칙을 이용하면 테스트 실행 전후의 셋업이나 티어다운을 생략하거나 일부만 실행할 수 있다.

규칙은 클래스 단위로 적용되며 테스트 클래스 하나에 여러 규칙을 적용할 수 있다.

순서는 보장하지 않지만, JUnit 은 명시된 모든 규칙을 하나씩 적용해준다.



-

JUnit 은 테스트 클래스를 실행하기 앞서 테스트 실행 계획을 수립한다.

이 때 org.junit.rules.MethodRule 을 상속한 규칙은 수립된 실행 계획을 감싸거나 완전히 대체해 버린다.





B.3. 기본 규칙들


B.3.1. 전역 타임아웃 설정하기


-

개별 테스트 메서드의 타임아웃은 @Test(timeout = X)처럼 설정하면 된다.

만약 클래스 안의 모든 테스트 메서드에 똑같은 타임아웃을 설정하고 싶다면 rule api 로 한번에 해결할 수 있다.



-

Rule 은 public 필드로 정의해야 한다.

Rule 에는 @Rule annotation 을 적어준다.

JUnit 은 필드 이름에 신경 쓰지 않으니, 원하는 대로 짓고, 규칙의 의도만 명확히 전달하면 된다.




B.3.2. 기대하는 예외 확인하기


-

ExpectedException 을 이용해서 예외를 쉽게 확인할 수 있다.

@Rule
public ExpectedException thrown = ExpectedException.none();

@Test
public void throwsExceptionWithCorrectMsg(){
    thrown.expect(RuntimeException.class); // NullPointerException 이 RuntimeException 의 child 라 테스트 통과!
    thrown.expectMessage(“boom”);
    throw new NullPointerexception(“Ka-boom!”);
}



B.3.3. 임시 폴더 관리하기


-

단위 테스트에서는 파일시스템을 사용하지 않는 게 정석이지만, 파일시스템 상의 실제 파일을 다루는 테스트를 작성하고 싶을 때도 종종 있을 수 있다.

이럴 때는 TemporaryFolder 규칙을 사용하면 좋다.

테스트에서 간편하게 임시 파일이나 폴더를 만들 수 있게 해주고, 테스트가 끝나면 알아서 지워주는 유틸리티다.




반응형

댓글