테스트
스프링의 핵심인 IoC
와 DI
는 오브젝트의 설계와 생성, 관계, 사용에 관한 기술이다.
애플리케이션은 계속 변하고 복잡해져 간다. 그 변화에 대응하는 첫 번째 전략이 확장
과 변화
를 고려한 객체지향적 설계
와 그것을 효과적으로 담아낼 수 있는 IoC/DI
같은 기술이라면, 두 번째 전략은 만들어진 코드를 확신할 수 있게 해주고 변화에 유연하게 대처할 수 있는 자신감을 주는 테스트 기술
이다.
스프링으로 개발을 하면서 테스트를 만들지 않는다면 이는 스프링이 지닌 가치의 절반을 초기하는 셈이다.
UserDaoTest 다시 보기
UserDaoTest의 특징
이 테스트 코드의 내용을 정리해보면 다음과 같다.
main()
메소드를 이용한다.UserDao
의 오브젝트를 가져와 메소드를 호출한다.테스트에 사용할 입력 값(
User 오브젝트
)을 직접 코드에서 만들어 넣어준다.테스트의 결과를 콘솔에
출력
해준다.각 단계의 작업이 에러 없이 끝나면
콘솔
에 성공 메시지로 출력해준다.
웹을 통한 DAO 테스트 방법의 문제점
이렇게 웹 화면을 통해 값을 입력하고, 기능을 수행하고 결과를 확인하는 방법은 가장 흔히 쓰이는 방법이지만 DAO
에 대한 테스트로서는 단점
이 너무 많다. 모든 레이어
의 기능을 다 만들고 나서야 테스트가 가능하다는 점이 가장 큰 문제다. 하나의 테스트를 수행하는 데 참여하는 클래스
와 코드
가 너무 많기 때문이다.
작은 단위의 테스트
테스트는 가능하면 작은 단위로 쪼개서 집중해서 할 수 있어야 한다. 관심사의 분리
라는 원리가 여기에도 적용된다. 이렇게 작은 단위의 코드에 대해 테스트를 수행한 것을 단위 테스트(Unit Test
)라고 한다. 충분히 하나의 관심에 집중해서 효율적으로 테스트할 만한 범위의 단위라고 보면 된다.
때로는 단위 테스트
없이 바로 이런 긴 테스트만 하는 경우도 있다. 이때는 문제의 원인을 찾기가 매우 힘들다.
UserDaoTest의 문제점
수동 확인 작업의 번거로움
콘솔
에 나온 값을 보고 등록
과 조회
가 성공적으로 되고 있는지를 확인하는 건 사람의 책임
이다. UserDaoTest는 간단하지만 검증해야 하는 필드 양이 많고 복잡해지면 역시 불편함
을 느낄 수밖에 없다.
실행 작업의 번거로움
만약 DAO
가 수백 개
가 되고 그에 대한 main()
메소드도 그만큼 만들어진다면, 전체 기능을 테스트해보기 위해 main()
메소드를 수백 번 실행하는 수고가 필요하다.
UserDaoTest 개선
테스트의 효율적인 수행과 결과 관리
JUnit 테스트로 전환
프레임워크
는 개발자가 만든 클래스에 대한 제어 권한을 넘겨받아서 주도적
으로 애플리케이션의 흐름을 제어한다. 개발자가 만든 클래스의 오브젝트
를 생성하고 실행하는 일은 프레임워크에 의해 진행된다.
테스트 메소드 전환
메소드를
public
으로 선언돼어야 한다.@Test
라는 애노테이션을 붙여주어야 한다.main 메소드에 Test 실행 클래스 정보를 넣어준다.
검증 코드 전환
if
문장의 기능을 JUnit
이 제공해주는 assertThat
이라는 스태틱 메소드를 이용해 다음과 같이 변경할 수 있다.
테스트 결과의 일관성
반복적
으로 테스트를 했을 때 테스트가 실패하기도 하고 성공하기도 한다면 이는 좋은 테스트라고 할 수가 없다. 가장 좋은 해결책은 addAndGet()
테스트를 마치고 나면 테스트가 등록한 사용자 정보를 삭제해서, 테스트를 수행하기 이전 상태로 만들어주는 것이다. (일일이 테스트 실행 후 롤백하는 코드를 구현하였다..ㅜㅜ)
테스트 주도 개발
테스트 코드
를 먼저 만들고, 테스트를 성공
하게 해주는 코드를 작성하는 방식의 개발 방법이 있다. 이를 테스트 주도 개발이라고 한다.
TDD
는 아예 테스트를 먼저 만들고 그 테스트가 성공하도록 하는 코드만 만드는 식으로 진행하기 때문에 테스트를 빼먹지 않고 꼼꼼하게 만들어낼 수 있다.
테스트 코드 개선
JUnit
은 @Test
가 붙은 메소드를 실행하기 전과 후에 각각 @Before
와 @After
가 붙은 메소드를 자동으로 실행한다. 공통적인 준비 작업과 정리 작업은 @Before
나 @After
가 붙은 메소드에 넣어두면 JUnit
이 자동으로 메소드를 실행해 준다.
@BeforeClass, @AfterClass
테스트 클래스 실행 전과 실행 후 한번씩만 수행되는 메소드도 지원된다.
스프링 테스트 적용
@RunWith
JUnit
프레임워크의 테스트 실행 방법을 확장할 때 사용하는 애노테이션이다. SpringJUnit4ClassRunner
라는 JUnit용 테스트 컨텍스트 프레임워크 확장 클래스를 지정해주면 JUnit
이 테스트를 진행하는 중에 테스트가 사용할 애플리케이션 컨텍스트
를 만들고 관리하는 작업을 진행해준다.
@ContextConfiguration
@ContextConfiguration
은 자동으로 만들어줄 애플리케이션 컨텍스트의 설정파일 위치를 지정한 것이다.
@DirtiesContext
테스트 메소드에서 애플리케이션 컨텍스트의 구성이나 상태를 변경한다는 것을 테스트 컨텍스트 프레임워크에 알려준다.
테스트에 필요한 빈 설정을 다르게 하고 싶다면 테스트용 applicationcontext.xml 파일을 생성하여 지정해줄 수 도 있다.
정리
테스트는
자동화
돼야 하고, 빠르게 실행할 수 있어야 한다.main()
테스트 대신JUnit
프레임워크를 이용한 테스트 작성이 편리하다.테스트 결과는
일관성
이 있어야 한다. 코드의 변경 없이 환경이나 테스트 실행 순서에 따라서 결과가 달라지면 안 된다.테스트는
포괄적
으로 작성해야 한다.충분한 검증
을 하지 않는 테스트는 없는 것보다 나쁠수 있다.코드 작성
과테스트 수행
의 간격이 짧을수록 효과적이다.테스트하기 쉬운 코드가 좋은 코드다.
테스트를 먼저 만들고 테스트를 성공시키는 코드를 만들어가는
테스트 주도 개발 방법
도 유용한다.@Before
,@After
를 사용해서 테스트 메소드들의공통 준비 작업
과정리 작업
을 처리할 수 있다.오류가 발견될 경우 그에 대한
버그 테스트
를 만들어두면 유용하다.
Last updated