반응형
테스트 코드를 작성해야하는 이유
- 하나의 로직을 테스트 하기위해서 JSP와 같은 view를 작성해야함
- view단에서 발생하는에러인지 아님 비즈니스 로직으로 발생하는 에러인지 판단하기 힘듦
- 서버 환경으로 발생하는 문제까지 고려 해야하는 추가 노동이 필요
Unit 테스트
- 정의: 하나의 대상을 집중해서 작은 단위로 테스트를 진행하는 것
- 특징
- 테스트와 관심사를 분리
- view(JSP, HTML)를 추가 작업의 노동을 절약
- 의도한 대로 동작하는지 개발자가 빠르게 피드백 받을 수있음
- 자동화를 해주면 자주 반복해서 사용할 수 있음
테스트 자동화의
- 실패하는 경우 2가지 고려
- 테스트 진행하는 동안 에러발생(런타임 에러)
- 에러가 발생하지 않고 얘상한 값과 실제 값이 다른 경우
- 과거 main문을 활용한 테스트
public class UserDaoTest {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
System.out.println("UserDao 테스트 시작");
ApplicationContext context = new GenericXmlApplicationContext("/applicationContext.xml");
UserDao dao = context.getBean("userDao", UserDao.class);
User user = new User("username", "password"); // username, password
User user2 = dao.add(user);
if (!user.getPassword().equals(user2.getPassword())) {
System.out.println("테스트 실패 : password");
} else if (!user.getUsername().equals(user2.getUsername())) {
System.out.println("테스트 실패 : username");
} else {
System.out.println("테스트 성공");
}
}
}
- 솔루션 :
JUnit
Junit
Intellij 단축키 : mac os - ctrl + space, windows - ctrl + shift + t
- 정의 : Java에서 지원하는 테스트 전용 프레임 워크
- 특징
- Junit 4 까지public 형태로 정의 해야함 → 5.0부터는 안해도 됩니다.
- method 마다 @Test 애노테이션을 추가해야 합니다.
- 매번 독립적인 객체를 만드므로, 각 테스트가 독립적인 환경임을 보장해줘서 side effect를 방지할 수 있음
- 실행 순서
1)@Test
, public void, 파라미터가 없는 메소드 검색
2) 테스트 대상이 되는 클래스 Object를 하나 만든다
3)@Before
메소드가 있다면 실행
4)@Test
메소드를 하나 실행하고 결과를 저장
5)@After
메소가 있다면 실행
6) 모든@Test
메소드에 대해 2~5 단계 실행 반복
7) 테스트 결과를 취합해 반환
import org.junit.Test;
public class UserDaoTest (
@Test
public void addAndGet() throws SQLException {
ApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
UserDao dao = context.getBean("userDao" , UserDao.class);
User user = new User();
user. setld ( “gyumee") ;
user. setName(" 박성 철 ");
user.setPassword("springnol");
dao.add(user);
assertThat(user2.getName(), is(user.getName()));
assertThat(user2.getPassword(), is(user.getPassword()));
}
}
- 예외 경우 테스트
import org.junit.Test;
public class UserDaoTest (
@Test(expected=EmptyResultDataAccessException.class)
public void getUserFailure() throws SQLException {
ApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
UserDao dao = context.getBean("userDao" , UserDao.class);
dao.deleteAll();
assertThat(dao.getCount(), is(0));
dao.get("unknown_id"); // exception 발생 예상 지점
}
}
- 테스트코드 구조
단계 | 내용 | 코드 | |
조건 | 어떤 조건을 가지고 | 가져올 사용자 정보 존재하지 않는 경우 | dao.deleteAll(); asssertThat(dao.getCount(), is(0); |
행위 | 무엇을 할 때 | 존재하지 않는 id로 get()을 실행 | get("unknown_id"); |
결과 | 어떤 결과가 나온다 | 특별한 예외 던진다 | @Test(expected=EmptyResultDataAccessException.class) |
Context와 Bean의 재사용
- ApplicationContext는 초기화되고 공유 가능한 요소
- Bean은 Singleton이기 때문에 공유 가능(stateless)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/applicationContext.xml")
public class UserDaoTest {
@Autowired
private ApplicationContext context; // bean 주입
// ...
}
@RunWith(SpringJUnit4ClassRunner.class)
:테스트 컨텍스트 프레임워크
의 확장 JUnit확장기능 지정 - 테스트에서 사용할 Application Context를 만들고 관리@ContextConfiguration(locations = "/applicationContext.xml")
: 어떤 컨텍스트 설정 파일 위치 명시 - 해당 container를 공유 되고 있는 정보
테스트를 위한 수동 DI 적용
//...
@DirtiesContext
public class UserDaoTest (
@Autowired
UserDao dao;
@Before
public void setUp() (
DataSource dataSource = new SingleConnectionDataSource(
"jdbc:mysql:lllocalhost/testdb" , "spring" ’ "book" , true);
dao.setDataSource(dataSource);
}
}
- 목적: 의도적으로 기존의 DI를 사용하지 않고 새로 테스트를 위한 object를 생성하고 싶을때 사용
- 애노테이션
- @DirtiesContext : 테스트 메소드에서 애플리케이션 컨텍스트의 구성이나 상태를 변경한다는 것을 테스트 컨텍스트 프레임워크에 알려주는 애노테이션
- 장점
- xml 수정없이 테스트 코드를 통해 object 관계 재구성
- 단점
- 성능 저하 발생 : ApplicationContext를 공유하지 못하기 때문에 성능 이슈 발생
- 해결 방안 : 테스트를 위한 xml파일을새로 만들기
테스트 코드 작성 방식
- DI를 사용하지 않고 객체를 생성해서 테스트 진행하기
- DI를 무조건 사용해야하는경우 DI사용해서 작성하기
- 테스트 코드에서 특별한 상황이 발생해서 DI의 객체를 변경이 필요하면 @DirtiesContext 사용하기
TDD
- 정의 : 테스트 코드 먼저 만들고 개발 진행하는 것
학습용 테스트(Learning Test)
- 정의 : 자신이 만들지 않은 라이브러리 프레임 워크를 테스트 하고, 학습을 목적으로 만드는 테스트 코드
- 목적과 정점
- 다양한 조건에 따른 기능을 손쉽게 자동화하여 확인 가능
- 학습용 테스트 코드 작성 가능
- 라이브러리 호환등을 점검 가능
- 테스트 코드 작성 훈련 가능
버그 테스트
- 정의 : 코드에 오류가 있을 때 오류를 가장 잘 드러내는 테스트를 만드는 것이다 → 해당 테스트 코드를 통과하면 오류 해결
- 장점
- 테스트 완성도를 높여준다 : 새로우 문제가 발생하더라도 이 테스트 코드를 통해 추적 가능
- 버그의 내용을 명확하게 분석하게 해준다 : 어떤 문제가 있는지 새로 식별 가능 → 경계값, 동등 분할당 값의 범위 설정해서 테스트 하기
- 기술적인 문제를 해결하는데 도움이 된다 : 원인 파악이 안될 경우 이슈를 포럼과 공식 문서를 통해서 학습하고 실패 원인 분석할 수 있음
반응형
'Spring > 개념' 카테고리의 다른 글
Spring Test Mock 사용법 및 특징 (1) | 2021.10.30 |
---|---|
Spring Boot로 MySQL replication 연동하기 (0) | 2021.10.06 |
04 Exception (0) | 2021.05.19 |
03 템플릿 (0) | 2021.05.08 |
01 장 오브젝트와 의존관계 (0) | 2021.05.05 |