- [ 배경 ]
- 중고거래 서비스 프로세스의 요건이 복잡해지고 소스의 양이 늘어날수록 눈으로 찾아낼 수 있는 범위는 한정되감을 느꼈습니다.
- 오류의 범위는 한정되어 있으므로 시간이 지날수록 코드의 안정성이 유지되기 힘들게 되어 서비스가 작을 때 중요한 프로세스에 대하여 자동화된 테스트 환경을 구축해놓을 필요성을 느꼈습니다.
- 중고거래 서비스는 spring-boot환경에서 개발되어 코드 품질 유지를 위해 Spring-boot-starter-test에서 자체적으로 유닛 테스트를 지원하는 라이브러리(Junit, Mockito, Hamcrest 등)를 사용하려고 합니다.
- 중고거래 서비스 프로세스의 요건이 복잡해지고 소스의 양이 늘어날수록 눈으로 찾아낼 수 있는 범위는 한정되감을 느꼈습니다.
- [ 과정 ]
- Spring-boot 환경에서 기본적으로 제공되는 spring-boot-starter-test 의존성이 있는지 확인합니다.
- Spring 환경에서는 junit과 mockito-all 의존성을 추가합니다.
- 테스트 코드 작성은 src/test/java 아래에서 작성합니다. 테스트 클래스의 생성은 특정 service class의 alt+enter키워드를 통해서 생성할 수 도있고, Navigate - Test를 선택하여 생성할 수도 있습니다.
- 테스트 코드에 쓰일 Junit, Mockito 메서드와 관련 어노테이션에 대해서 알아보겠습니다.
- Junit assert 메서드
- assertNotNul(obj)
- 객체(obj)의 Null 여부를 테스트
- assertTrue(condition), assertFalse(condition)
- 조건(condition)의 참/거짓 테스트
- assertEquals(obj1, obj2), assertNotEquals(obj1, obj2)
- obj1와 obj2의 값이 같은지 테스트
- assertSame(obj1, obj2)
- obj1와 obj2가 같은 객체인지 테스트
- assertArrayEquals(arr1, arr2)
- 배열 arr1과 arr2가 같은지 테스트
- assertThat(T actual, Matcher matcher)
- 첫 번쨰 인자에 비교대상을 넣고, 두 번째 로직에는 비교 로직을 넣어서 조건 테스트
- ex) assertThat(a, is(100)) : a의 값이 100인가? , assertThat(obj, is(nullValue())) : 객체가 널인가?
- assertNotNul(obj)
- Mockito FrameWork란?
- 유닛 테스트를 위해 가짜 객체를 지원해주는 프레임워크
- Mock객체 생성, Mock객체 동작 지정, 그리고 테스트 대상 로직이 제대로 수행되었는지 확인하는 기능을 한다.
- Mockito메서드 종류
- Mock() - 모의 객체를 생성하는 역할
- when() - 협력 객체 메서드 반환 값을 지정해주는 역할(stub)
- verify() - stub안의 협력 객체 메서드가 호출되었는지 확인
- times() - 지정한 횟수만큼 협력 객체 메서드가 호출 되었는지 확인
- never() - 호출되지 않았는지 여부 검증
- atLeastOnce() - 최소 한 번은 특정 메소드가 호출되었는지 확인
- atLeast() - 최소 지정한 횟수만큼 호출되었는지 확인
- atMost() - 최대 지정한 횟수 만큼 호출되었는지 확인
- clear() - 스텁을 초기화한다
- timeOut() - 지정된 시간 안에 호출되었는지 확인
- given() - when 대신 사용하여 Arrange 단계를 작성
- then() - verify 대신 사용하여 Assert 단계를 작성
- Junit assert 메서드
- Junit과 Mockito 메서드를 이용하여 중고거래 물품 Service에서 물품 등록 메서드와 자신의 물품 검색 메서드의 테스트 코드를 작성하였습니다.
- register 메서드에서는 given 메서드를 이용해서 물품과 유저를 각각 생성 후에 실제 productSerivce의 register 메서드를 호출하여 테스트합니다.
- updateProducts 메서드에서는 물품 생성 후 Contents 필드를 임의로 변경 후 Mapper, Service의 update 메서드 수행 후 결과 값이 정상적으로 바뀌었는지 통해 assertTrue 메서드를 통해 확인합니다.
- [ 결과 ]
- 테스트를 먼저 작성함으로써 개발하고자 하는 의도가 명확해졌고 테스트 작성과 동시에 프로젝트의 전체적인 그림을 생각하게 되었습니다.
- 테스트 작성은 영향을 끼치는 구조를 파악할 수 있고 그에 대한 피드백으로 리팩터링도 진행할 수 있었습니다.
- 다른 팀원들은 테스트 케이스 작성한 사람의 설계를 공유하면서 소스 개발에 집중할 수 있어 생산성이 높아집니다.
- 테스트를 먼저 작성함으로써 개발하고자 하는 의도가 명확해졌고 테스트 작성과 동시에 프로젝트의 전체적인 그림을 생각하게 되었습니다.
- [ 성과 ]
- 개발과정 중 미리 문제를 파악함으로써 미래 오류에 대비할 수 있습니다.
- 미래의 나, 새로운 팀원이 합류했을 때 테스트 작성, 코드 컨벤션, CI 설정에서 테스트 검사 등은 프로젝트를 유지 보수하기 좋게 만들었습니다.
- 중고거래 프로젝트 개발 시에 사용했던 API들을 단위 테스트와 통합 테스트를 적용함으로써 유지 보수성이 향상된 걸 느꼈습니다.
- 개발과정 중 미리 문제를 파악함으로써 미래 오류에 대비할 수 있습니다.
- used-market-server 중고거래 프로젝트 코드는 아래에서 확인하실 수 있습니다.
'used-market-server Project' 카테고리의 다른 글
젠킨스 CI 적용하기 (ubuntu linux 18.04) (0) | 2020.09.09 |
---|---|
대용량 트래픽 환경에서 게시글 검색시 캐싱 적용하기 (0) | 2020.09.09 |
로그인 상태 정보인 세션 객체를 분산 서버환경에서 트러블 슈팅 (0) | 2020.09.02 |
Tomcat, Jetty 에서 세션 클러스터링 방법 (0) | 2020.08.11 |
Nodejs, Redis 가 단일 쓰레드인 이유는? (0) | 2020.08.11 |