JUnit 테스트 실행하기
IDE
자바 IDE에서는 대부분 내장된 JUnit 테스트 지원 도구가 존재한다.
JUnit을 메인 메서드를 만들지 않고도 테스트를 진행할 수 있게 해주며,
테스트 정보를 표시해주는 다양한 뷰 기능도 제공한다.
빌드 툴
메이븐, 그래들 같은 빌드 툴에서 제공하는 JUnit 플러그인과 테스트가 존재한다.
HTML이나 텍스트 파일 형식으로 보기 좋게 테스트 결과를 만들어주기 때문에
개인별로는 IDE를 통해서 테스트를 실행하지만 통합 빌드 후의 테스트는
빌드 툴을 통한 테스트 결과를 파일로 전달 받는다.
일관된 테스트 결과
테스트는 외부의 상태에 따라 결과가 달라지는 일이 발생하지 않고
코드의 변화가 있지 않는한 항상 같은 결과가 나와야 한다.
이를 위해서는 테스트한 결과는 실제로 반영되지 않아야 하는데
테스트를 실행한 후에는 결과만 확인하고 초기화하는 것이 좋다.
public void andAndGet() throws SQLException {
//데이터 삭제를 통한 초기화
//초기화가 제대로 된지 검증
//db에 데이터 추가
//추가가 제대로 되었는지 검증
//추가하려는 데이터와 추가된 데이터가 일치하는지 마지막으로 검증
}
이렇게 직접 데이터를 삭제하는 메서드와 데이터의 초기화 및 추가 검증 메서드를 구현하여
테스트 메서드에서 사용하는 방법도 있지만 스프링은 더 편리한 기능을 제공한다.
하지만 아직 스프링의 기능을 충분히 배우지 못했기 때문에 나중에 다시 알아보겠다.
중요한 것은 테스트의 결과는 항상 일관되야 한다는 것이다.
포괄적인 테스트
테스트는 항상 한 가지 결과만 검증하는 것에서 끝나는 것이 아니라 다양한 상황을 염두하고
테스트를 진행해야 하는데, 테스트가 성공하지 말아야 하는 경우에 성공하는 것을 방지하기 위함이다.
한 가지 더 주의해야 할 점은 JUnit은 테스트의 실행 순서를 보장해주지 않기 때문에
테스트 코드를 작성할 때는 항상 실행 순서와 상관 없이 올바른 결과가 나오고
다른 테스트와 독립적으로 존재하게 작성해야 한다.
예외 조건에 대한 테스트
테스트 실행 도중 예외가 발생한 경우에는 특정 값을 리턴하거나 예외를 던지게 할 수 있다.
현재까지 작성한 코드는 리턴값이 있는 경우
assertThat 메서드를 통해 리턴값이 예상 결과와 일치하는지 확인하여
테스트의 성공여부를 알 수 있었다.
이번에는 예외를 사용하여 테스트 성공여부를 알 수 있는 방법을 알아볼 것인데,
예외는 assertThat을 통해서 비교를 할 수가 없지만
JUnit에서는 이러한 예외조건 테스트를 위한 기능을 제공한다.
@Test(expected=EmptyResultDataAccessException.class)
public void getUserFailure() throws SQLException {
dao.deleteAll();
assertThat(dao.getCount(), is(0));
dao.get("unknown_id");
}
위의 코드와 같이 @Test 어노테이션의 element 요소로 해당 테스트의 실행 중에
발생할 것이라 기대하는 예외 클래스를 넣어주면 되는데
기대하는 예외가 발생했을 때 테스트가 성공했음을 알려준다.
테스트 주도 개발 (Test Driven Development)
말그대로 테스트가 개발을 주도한다는 것이고 개발이 테스트에 이끌려 간다는 것이다.
실제 코드를 작성한 후에 코드가 정상적으로 실행되는지 테스트를 통해 검증하는 것이 아니라
테스트를 먼저 작성한 후에 이를 바탕으로 실제 기능을 구현하는 것으로
테스트에 맞춰 개발이 진행되는 것이다.
기능설계를 위한 테스트
테스트는 어떤 조건을 가지고 어떤 동작을 했을 때 어떤 결과가 나오는지에 대해 검증하는 행위인데
이는 메서드의 기능 정의서와 다를게 없는 구성이다.
보통의 프로그램이 기능설계 > 구현 > 테스트라는 순서로 이루어졌다면
테스트가 기능설계의 역할도 담당하고 있는 것이다.
즉, 테스트 코드를 의사 코드라고 볼 수 있다.
테스트 코드로 간단한 틀을 만들고 테스트에 필요한 메서드들을 구현하여
테스트를 수행하는 경우 성공했다면 기능이 정상적으로 구현이 된 것이고,
실패했다면 기능에 결함이 있는 것을 바로 알 수가 있는 것이 테스트 주도 개발의 장점이다.
요약하면 테스트를 먼저 만들고 테스트가 성공할 때까지 가능한 빠르게 개발하는 방법이다.
테스트 코드 리팩토링 하기
테스크 코드는 기능에 영향을 주지는 않으니 굳이 보기 좋고 효율적으로 리팩토링 할 필요가
있는지 의문을 가질 수도 있지만 모든 코드는 보기 쉽고 변경이 용이해서 나쁠 것이 없다.
반복적인 부분을 뽑아내는 메서드 추출 리팩토링 방법도 있지만
JUnit에서 이러한 반복되는 준비 작업을 별도의 메서드로 분리하고 테스트 실행 전에
자동으로 먼저 호출해주는 기능이 있다.
@Before
어노테이션의 이름부터 누가봐도 어떤 상황의 전에 실행될거만 같이 생겼다.
이 어노테이션은 실제로 @Test 메서드가 실행되기 전에 먼저 실행되어야 하는
선행 메서드를 정의할 때 사용되는 어노테이션이다.
@Before
public void setUp() {
ApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml");
this.dao = context.getBean("userDao", UserDao.class);
this.user1 = new User("아이디1", "이름1", "비밀번호1");
this.user2 = new User("아이디2", "이름2", "비밀번호2");
this.user3 = new User("아이디3", "이름3", "비밀번호3");
}
위의 코드와 같이 반복적으로 실행되는 코드를 해당 어노테이션이 붙은 메서드에 넣어주면
테스트 메서드들이 실행될 때마다 항상 해당 메서드가 실행된 후에 실행된다.
@Before 어노테이션을 보면 어떤 생각이 들 수도 있는데
Before가 있으면 당연히 정반대의 역할을 수행하는 @After 어노테이션도 존재한다.
픽스처
위의 코드에서 dao 같은 경우를 픽스처라고 할 수 있는데
테스트를 수행할 때 필요한 정보나 오브젝트를 가리키는 말이다.
'Back-End > Spring' 카테고리의 다른 글
템플릿 적용하기 (0) | 2023.06.13 |
---|---|
스프링에 테스트 적용하기 (0) | 2023.06.08 |
테스트 (0) | 2023.06.07 |
XML 설정 (0) | 2023.06.07 |
DI(Dependency Injection) (0) | 2023.06.07 |