테스트 코드 작성 관련해서 슥슥 정리한다.
테스트 코드 작성은 현업에서 매우 중요하다고 익히 들어왔다.
더 익숙해지도록 자주 보고 실제 프로젝트 할 때 스스로 정성스럽게 작성해보자는 다짐을 하며..
시 to the 쟉
∨ 테스트 코드 작성
예상 시나리오대로 테스트 코드를 작성하여 결과를 검증한다.
성공 또는 실패 결과에 따라 코드를 수정하게 된다.
* 다양한 상황에 맞춰 테스트 코드를 작성한다. 이것을 곧 테스트 케이스라고 한다.
* 테스트케이스는 크게 성공과 실패로 나뉜다.
테스트 코드 성공 => 리팩터링하여 코드 개선
테스트 코드 실패 => 디버깅을 통해 코드 고치기
∨ TDD
이전에 TDD에 대해 정리해뒀던 글이다 :
2022.07.14 - [web +a] - 테스트 주도 개발 (TDD)
테스트코드를 먼저 작성하고 이를 통과하는 최소한의 코드만 구현하기 시작해 점진적으로 개선하고 확장해나가는 개발 방법이다.
참고사항
∨ @SpringBootTest : 스프링 부트와 연동해서 테스트 하겠다는 어노테이션
ㄴ 테스트 돌리는 데 조금 시간이 걸린다.
∨ ArticleService의 index() 메서드에 대한 테스트를 하고 싶으면,
마우스 우클릭 후 Generate => Test 클릭 후 index() 를 선택하면 편하게 Test코드의 틀을 생성할 수 있다.
테스트 작성 예시
ex) 모든 목록을 조회하는 index()에 대한 테스트를 작성해보자.
// 예상 : 이러이러한 목록이 예상된다
// 실제 : 실제로 ArticleService에서 가져온 목록은 이렇다
// 검증 : assertEquals(예상.toString(), 실제.toString())과 같이 검증할 수 있다
ex) show() 메서드에 대한 테스트 코드를 작성해볼 건데, 성공 케이스와 실패 케이스를 나눠 작성해보자.
@Test
void show_성공____존재하는_id_입력() {
// 예상 : 이 id가 들어올 때 이러한 Entity가 기대된다
// 실제 : 실제로 Service에서 show(id)로 꺼내온Entity는 이렇다
// 검증 : assertEquals(예상.toString(), 실제.toString());
}
@Test
void show_실패____존재하지_않는_id_입력() {
// 예상 : 이 id가 들어올 때 null이 기대된다
// 실제 : 실제로 Service에서 show(id)로 꺼내온Entity는 이렇다
// 비교 : assertEquals(expected, article);
}
ex) ArticleService의 create() 테스트도 해보자.
@Test
void create_성공____title과_content만_있는_dto_입력() {
// 예상 : title과 content만 있는 dto가 있다고 하자.
// 이 경우 expected는 new Article(4L, title, content)의 반환값이다.
// 실제 : Service에서 create(dto)한 실제 결과
// 비교 :
assertEquals(expected.toString(), article.toString()) 검증
}
@Test
void create_실패____id가_포함된_dto_입력() {
// 예상 : id값이 포함되어 있는 dto로 create할 경우 null을 기대한다.
// 실제 : id값이 포함되어 있는 dto로 실제 Service에서 create(dto)한 실제 값
// 비교
assertEquals(expected, article) 검증
}
테스트시 트랜잭션 처리 주의
문제가 되는 상황 :
- 클래스 단위로 Test를 진행하고 있다.
- 선행되는 Test인 create() 테스트에서 DB의 insert가 실행되었다.
- 후행되는 Test인 index()에서 Entity 목록에 대한 검증이 일어났다. Entity 3개를 기대하지만 앞 테스트에서 insert하여 실제 Service는 4개의 Entity 목록을 가져온 상황이다. 의도치 않게 테스트 검증 실패가 일어났다.
* 반면 index()를 단독으로 테스트하면 전혀 문제가 되지 않는다.
문제의 이유는 트랜잭션 롤백 처리를 하지 않았기 때문이다.
DB가 변경되는 create, delete 등의 Test는 트랜잭션 단위로 관리해주어 롤백이 일어나게 해야 한다.
이전에 했듯이 테스트 코드에도 @Transactional을 붙여 트랜잭션 처리를 해주자!
개인 실습 - update에 대한 테스트코드 스스로 작성해보기
음.. 실제 코딩은 안하고 내용만 보고 있었는데 이런 셀프스터디를 내주셨당..
아쉽지만 틀만 간단히 슥슥 작성해보자..↓
실제 프로젝트 할 때 실컷 연습하지 모..
@Test
@Transactional
void update_성공____존재하는_id와_title_content가_있는_dto_입력() {
// 예상 : 그러한 dto가 들어왔을 때 해당 내용으로 업데이트 된 Entity를 정상 반환
// 실제 : Service에서 update(dto) 수행시 반환한 실제 Entity
// 검증 : assertEquals(예상.toString(), 실제.toString())
}
@Test
@Transactional
void update_성공____존재하는_id와_title만_있는_dto_입력() {
// 예상 : 그러한 dto가 들어왔을 때 title만 업데이트 & content는 그대로인 Entity를 반환
// 실제 : Service에서 update(dto) 수행시 반환한 실제 Entity
// 검증 : assertEquals(예상.toString(), 실제.toString())
}
@Test
@Transactional
void update_실패____존재하지_않는_id의_dto_입력() {
// 예상 : 그러한 dto가 있으면 null값을 기대
// 실제 : Service에서 update(dto)시 반환한 실제 Entity
// 검증 : assertEquals(예상, 실제)
}
@Test
@Transactional
void update_실패____id만_있는_dto_입력() {
// 예상 : 그러한 dto가 있으면 null값을 기대
// 실제 : Service에서 update(dto)시 반환한 실제 Entity
// 검증 : assertEquals(예상, 실제)
}
@Test
@Transactional
void delete_성공____존재하는_id_입력() {
// 예상 : 해당 id에 대해 delete된 Entity 반환
// 실제 : Service에서 delete(id)시 성공적으로 반환한 실제 Entity
// 검증 : assertEquals(예상.toString(), 실제.toString())
}
@Test
@Transactional
void delete_실패____존재하지_않는_id_입력() {
// 예상 : 해당 id에 대해 delete시 null을 예상
// 실제 : Service에서 delete(id)시 반환한 실제 Entity
// 검증 : assertEquals(예상, 실제)
}
수술한 my eyes를 위해 이제 컴 끈닷
화면 글씨 짱 키우고 선글라스 끼고 블루라이트 차단하고
눈 안건조하게 가볍게 하구 있는데..
오빠한테 문자로 혼나고 엄마한테 컴퓨터 하지말라며 양쪽으루 혼났다 ㅋㅅㅋ
헷.. 걱정해줘서 고맙습니댯... ㅋㅅㅋ
'web +a' 카테고리의 다른 글
스프링부트 ~23 | 댓글 CRUD를 위한 Controller & Service (+ 댓글 Rest API 완성하기) (0) | 2022.07.27 |
---|---|
스프링부트 ~22 | 댓글 CRUD를 위한 Entity, Repository & Test (0) | 2022.07.26 |
스프링부트 ~20 | 서비스 계층 추가 & 트랜잭션 처리 (0) | 2022.07.25 |
스프링부트 ~19 | REST API를 적용하여 CRUD 구현하기 (0) | 2022.07.21 |
스프링부트 ~18 | REST API와 JSON (0) | 2022.07.21 |