[데브코스] 소프트웨어 테스팅
Updated: Categories: TILW4D1 - 테스팅레벨에 대해 공부하고 단위,통합테스트를 실제로 구현해보자!
소프트웨어 테스팅
테스팅 레벨
- 단위(Unit) 테스트 : 모듈단위 테스트
- 통합(Integration) 테스트 : 내부 모듈 간 연동 + 외부 서비스와의 연동을 테스트
- 시스템(System) 테스트
- 인수(Acceptance) 테스트 : UI, End to End Test
- 아래로 갈수록 많은 시간과 노력이 들어가므로, 아래는 테스트 적게 위에는 테스트 많이
단위 테스트
SUT
(System Under Test) : 하나의 클래스라고 생각하면 된다- 클래스 단위로 하나씩 고립된 환경에서 테스트를 진행함
- 다른 객체와 협력관계가 맺어져 있는 경우 실제로 그 객체를 만들지 않고
test double
로 대신하게 된다. - 지속적인 변경상황에서 테스트를 통해 무결성을 보장받기 위함이다
Test Double
- 테스트 객체와 의존관계가 있는 객체의 역할을 대신해주는
가짜
객체이다. Mock
: 행위 검증에 사용한다.Stub
: 상태 검증에 사용한다.
JUnit
- 단위 테스트 프레임워크이며, SpringBoot 2.2부터
JUnit 5
가 default임 - 단위 테스트마다 테스트 클래스의 인스턴스가 생성 (독립적 환경)
- 테스트 라이플 사이클 관리를 위한 어노테이션 제공
- Assert를 통한 테스트 케이스 수행 결과 판별
JUnit 5
Platform
: JVM에 테스팅 프레임워크를 실행시키는 엔진Jupitor
: 5버전용 엔진의 실제 구현체임. Jupiter API를 사용하여 테스트 코드 작성Vintage
: JUnit4로 작성된 테스트 코드 실행시 사용
IntelliJ 단위 테스트
- 클래스명에 alt + enter 누르면 테스트 클래스 생성을 선택할 수 있음
- 테스트 클래스 생성시 test 패키지에 해당 클래스와 동일한 패키지 구조가 복사되며 만들어짐
- test 메소드는 항상 void여야 한다.
메소드 Annotation
@Test
: 테스트 메소드에 달아줌@DisplayName(설명)
: 테스트 설명 적기@BeforeAll
: 테스트 클래스 실행되자마자 한번 실행@BeforeEach
: 테스트 메소드 실행시마다 실행@AfterAll
: 테스트 클래스 끝나면 한번 실행@AfterEach
: 테스트 메소드가 끝날때마다 실행- Before/After 관련 메소드는 static 함수로 작성해야함
@Disabled(설명)
: 해당 테스트를 건너뛴다@Order(순서)
: 테스트 메소드에 순서를 지정- 테스트 클래스에
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
어노테이션을 달아줘야함
- 테스트 클래스에
Jupiter Assertions Method
assertEquals(기대값, 테스트값)
: 테스트 결과값이 기대값과 같아야 통과assertThrows(예외 클래스 타입, 잘못된 행위)
: 잘못된 행위를 했을때, 적절한 예외 클래스가 발생했는가?
Hamcrest - matcher
- 컬렉션을 검증해야할 땐
Hamcrest
를 사용하는 것이 용이하다. assertThat(테스트값, 검사로직)
: 검사로직에 다양한 matcher 메소드를 사용할 수 있음is
,hasItem
,hasSize
,everyItem
등등…
Test Double flow
Given
: stub/mock 객체를 정의해주고sut
를 생성한다.When
: (sut
를 사용해 메소드 실행) 테스트할 객체를 생성. (이 행위를 정의)Then
: 해당 객체를 가지고 다양한 메소드를 테스트한다.
Stub
- 상태 검증에 사용된다
- 테스트 코드에서 stub 생성이 필요할 땐 의존관계의 객체가 추상체일 경우임
- 테스트 클래스에서 해당 인터페이스를 가짜로 구현해준다.
Mock
- 행위 검증에 사용되며
Mockito
모듈을 사용한다. mock(클래스.class)
: 해당 클래스의 mock 객체를 생성when().thenReturn()
: mock 객체 메소드의 리턴값을 임시로 정의한다.inOrder(mock객체, ...)
: 해당 mock 객체의 메소드를 순서대로 테스트할 수 있게 묶어줌verify(mock객체).메소드
: When의 행위에서 해당 mock의 메소드들이 실행되었는지 검사함
IntelliJ 통합 테스트
테스트 클래스 정의
@SpringJUnitConfig
@ActiveProfiles("")
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class 클래스명{
...
}
- ⬆ 모듈(Bean)간 연결성을 테스트하는 것이므로 IoC 컨테이너를 테스트하기 위한 클래스
@SpringJUnitConfig
: 테스트용 AppContext를 생성할 수 있게 해줌@ActiveProfiles
: 프로필 필터링하기@TestInstance
: 클래스 내부에서 static 메소드를 사용하기 위해 객체 하나만 만들어지도록 함
@Autowired
ApplicationContext context;
- ⬆
@Autowired
를 통해 AppContext와 Bean 객체 생성를 생성할 수 있다. - 이렇게 설정해주고 나면 테스트 코드에서 컨테이너 객체들을 가져다 쓰면 됨
테스트용 App Context 정의
@Configuration
static class Config {
@Bean
[bean 정의 ...]
}
- ⬆ Bean 정의용 static 클래스를 만들어주거나
@Configuration
@ComponentScan
static class Config {
}
- ⬆ 그냥 컴포넌트 스캔해도 된다. (이렇게 쓰자)