JAVA

Junit에 대하여

때래뚫 2023. 4. 24. 00:27

Junit에 대하여

Junit이란건 현업에 계시는 분들은 많이 아시겠지만, 저같이 아직 현업에 뛰어들지 않았거나 혹은 학원 등에서 배우고 계시지만 사용하지 못하는분들이 많으실겁니다. 그래서 이 내용에 대한 것을 오늘 강의에 대한 내용과 합하여 알아보고자 합니다.

 

Junit이란?

Junit이란 JAVA를 위한 단위 테스트 도구이며 테스트를 System.out을 통하거나 log4j로 디버깅하여 만드는 것이 아니라, 코드의 국부적인 부분을 테스트해봄으로서 해당부분이 정상 작동되는지, 혹은 정상작동이 되지않고 어느곳이 문제인지를 알아낼 때 주로 사용하는 테스터 프레임워크입니다.

 

Junit을 사용할 때 얻을 수 있는 장점은 다음과 같습니다.

 

- @DisplayName 태그등을 이용하여 무슨내용을 테스트했는지 등 문서화 작업이 용이해집니다.

- 코드의 일정 부분을 테스트 함으로서 코드의 결함을 더 쉽게 발견할 수 있습니다.

- 코드를 리팩토링할 때 테스트 코드를 통하여 더 안정성을 확보할 수 있습니다.

 

지금부터 적용하는 방법과 그에대한 특징을 하나씩 자세히 설명드리겠습니다.

우선 제가 사용하는 IntelliJ에서는 JAVA프로젝트를 생성하면 기본적으로 적용이 되어있습니다.

라이브러리를 다운받아오는 build.gradle의 코드입니다.

보시면 위 사진에 Jnit과 관련된 testImplementation이 두개 들어가있습니다.

나머지 하나 assertJ는 Junit을 사용한 테스트코드의 가독성과 간결성을 위한 라이브러리로, 다음시간에 다시 다루겠습니다. 어쨌든 저 두개가 없다면 Junit과 관련된 라이브러리를 불러올 수 없으므로, 없으시다면 MVNrepository를 통하여 소스를 받아오시면 됩니다.

 

잘 적용이 되었다면 다음 사진과 같이 External Libraries에 Junit과 관련된 라이브러리들이 있는 것을 확인하실 수 있습니다.

External Libraries

 

 

 

본 프로그램과 테스트 디렉터리

이제 해당 프레임워크를 이용하려면 따로 파일을 만들어야합니다. 하지만 본 프로그램 디렉터리에 만들면 나중에 파일을 관리하기 힘들어지므로, 따로 만들도록합니다. eclipse와 intelliJ 모두 프로젝트 생성시 main과 test용 디렉터리를 구분하여 생성됩니다.

 

test디렉터리는 비어있지만 보통 테스트 클래스를 생성할 때에는 아래 사진과 같이 테스트할 클래스와 동일하게 패키지

경로를 잡아줍니다.

저는 강의에서 비밀번호 생성과정 검증에 대한 내용을 테스트했기 때문에, PasswordValidator클래스와 동일하게 패키지명을 생성했습니다.

테스트 클래스와 테스트할 클래스 경로비교

이제는 테스트할 차례입니다.

테스트할 메소드는 비밀번호가 정해진 범위에 적합한지 검증하는 메소드이며, 8자 이상 12자 이하가 아닐경우는 예외를 발생시키게되어있습니다.

테스트할 메서드

이에 대한 테스트 클래스를 생성했습니다.

테스트 클래스

보시면 어노테이션이 두개가 붙어있습니다.

@Test는 해당 메서드가 테스트 코드임을 나타냅니다. 해당 메서드는 실행되면 테스트 코드로서 작동됩니다.

@DisplayName은 테스트 클래스나 테스트 메서드에 대한 사용자 지정이름을 나타냅니다. 위 사진과 같이 테스트할 내용을 적어놓음으로서, 누가 보아도 무슨의도로 테스트를 하는 것인지 알 수 있게 문서화 작업을 하는 것입니다.

또한 위 사진에 있는 메서드 처럼 테스트할 클래스에서 하나의 메서드만 가져와 정상적인 실행을 하는지 테스트함으로서 결함이 있는 부분의 범위를 보다 좁히고, 편하게 찾을 수 있습니다.

마지막으로 리팩토링을 해당 테스트 코드에 적용시켜 먼저 제대로 작동되는지 테스트함으로서 원 코드와 관계없이 안정성 있는 리팩토링이 가능해집니다.

 

주석묘사

@Test 메서드가 테스트 메서드임을 나타냅니다. JUnit 4의 어노테이션과 달리, JUnit Jupiter의 테스트 확장은 자체 전용 어노테이션을 기반으로 작동하기 때문에 이 어노테이션은 어떠한 속성도 선언하지 않습니다. 이러한 메서드는 재정의되지 않는 한 상속됩니다.@Test
@ParameterizedTest 메서드가 매개 변수가 있는 테스트임을 나타냅니다. 이러한 메서드는 재정의되지 않는 한 상속됩니다.
@RepeatedTest 메서드가 반복 테스트에 대한 테스트 템플릿임을 나타냅니다. 이러한 메서드는 재정의되지 않는 한 상속됩니다.
@TestFactory 메서드가 동적 테스트를 위한 테스트 팩터리임을 나타냅니다. 이러한 메서드는 재정의되지 않는 한 상속됩니다.
@TestTemplate 메서드는 등록된 공급자가 반환한 호출 컨텍스트의 수에 따라 여러 번 호출되도록 설계된 테스트 사례의 템플릿임을 나타냅니다. 이러한 메서드는 재정의되지 않는 한 상속됩니다.
@TestClassOrder 어노테이션이 있는 테스트 클래스의 테스트 클래스에 대한 테스트 클래스 실행 순서를 구성하는 데 사용됩니다. 이러한 주석은 상속됩니다.@Nested
@TestMethodOrder 주석이 달린 테스트 클래스에 대한 테스트 메서드 실행 순서를 구성하는 데 사용됩니다. JUnit 4와 유사합니다. 이러한 주석은 상속됩니다.@FixMethodOrder
@TestInstance 주석이 추가된 테스트 클래스에 대한 테스트 인스턴스 수명 주기를 구성하는 데 사용됩니다. 이러한 주석은 상속됩니다.
@DisplayName 테스트 클래스 또는 테스트 메서드에 대한 사용자 지정 표시 이름을 선언합니다. 이러한 주석은 상속되지 않습니다.
@DisplayNameGeneration 테스트 클래스에 대한 사용자 지정 표시 이름 생성기를 선언합니다. 이러한 주석은 상속됩니다.
@BeforeEach 주석이 달린 메서드는 현재 클래스의  , , , 또는 메서드 앞에 실행되어야 함을 나타냅니다. JUnit 4와 유사합니다. 이러한 메소드는 재정의되거나 대체되지 않는 한 상속됩니다 (즉, Java의 가시성 규칙에 관계없이 서명에 의해서만 대체됨).@Test@RepeatedTest@ParameterizedTest@TestFactory@Before
@AfterEach 주석이 달린 메서드는 현재 클래스의  , , , 또는 메서드 다음에 실행되어야 함을 나타냅니다. JUnit 4와 유사합니다. 이러한 메소드는 재정의되거나 대체되지 않는 한 상속됩니다 (즉, Java의 가시성 규칙에 관계없이 서명에 의해서만 대체됨).@Test@RepeatedTest@ParameterizedTest@TestFactory@After
@BeforeAll 주석이 달린 메서드는 현재 클래스의 모든 , , , 및 메서드보다 먼저 실행되어야 함을 나타냅니다. JUnit 4와 유사합니다. 이러한 메소드는 숨겨지거나, 재정의되거나, 대체되지 않는 한(즉, Java의 가시성 규칙에 관계없이 서명에 의해서만 대체되지 않는 한) 상속되며, "클래스별" 테스트 인스턴스 수명 주기가 사용되지 않는 한 상속되어야 합니다.@Test@RepeatedTest@ParameterizedTest@TestFactory@BeforeClassstatic
@AfterAll 주석이 달린 메서드는 현재 클래스의 모든 , , , 및 메서드 후에 실행되어야 함을 나타냅니다. JUnit 4와 유사합니다. 이러한 메소드는 숨겨지거나, 재정의되거나, 대체되지 않는 한(즉, Java의 가시성 규칙에 관계없이 서명에 의해서만 대체되지 않는 한) 상속되며, "클래스별" 테스트 인스턴스 수명 주기가 사용되지 않는 한 상속되어야 합니다.@Test@RepeatedTest@ParameterizedTest@TestFactory@AfterClassstatic
@Nested 주석이 추가된 클래스가 비정적 중첩 테스트 클래스임을 나타냅니다. Java 8부터 Java 15까지, "클래스별" 테스트 인스턴스 수명 주기를 사용하지 않는 한 테스트 클래스에서 메서드를 직접 사용할 수 없습니다. Java 16부터는 테스트 인스턴스 수명 주기 모드를 사용하여 테스트 클래스에서와 같이 메소드를 선언할 수 있습니다. 이러한 주석은 상속되지 않습니다.@BeforeAll@AfterAll@Nested@BeforeAll@AfterAllstatic@Nested
@Tag 클래스 또는 메서드 수준에서 테스트를 필터링하기 위한 태그를 선언하는 데 사용됩니다. TestNG의 테스트 그룹 또는 JUnit 4의 범주와 유사합니다. 이러한 주석은 클래스 수준에서는 상속되지만 메서드 수준에서는 상속되지 않습니다.
@Disabled 테스트 클래스 또는 테스트 메서드를 비활성화하는 데 사용됩니다. JUnit 4와 유사합니다. 이러한 주석은 상속되지 않습니다.@Ignore
@Timeout 테스트, 테스트 팩토리, 테스트 템플릿 또는 라이프사이클 메서드의 실행이 지정된 기간을 초과하는 경우 해당 메서드에 실패하는 데 사용됩니다. 이러한 주석은 상속됩니다.
@ExtendWith 확장을 선언적으로 등록하는 데 사용됩니다. 이러한 주석은 상속됩니다.
@RegisterExtension 필드를 통해 프로그래밍 방식으로 확장을 등록하는 데 사용됩니다. 이러한 필드는 섀도우 처리되지 않는 한 상속됩니다.
@TempDir 라이프 사이클 방법 또는 테스트 방법에서 필드 주입 또는 매개 변수 주입을 통해 임시 디렉토리를 제공하는 데 사용됩니다. 패키지에 있습니다.org.junit.jupiter.api.io

이렇게 제가 작문한 것 말고도 수많은 Junit에 대한 어노테이션이 Junit의 문서에 나와있으며, 적용예시 역시 모두 나와있어 사용할 때 테스트해보시면 좋을 것 같습니다. 부족한내용이 있다면 지적 부탁드립니다. 감사합니다.

 

참고사이트 : JUnit 5 사용자 가이드