[Test] Mock(with Mockito)
·
Software Development/Test
가짜로 진짜를 테스트하기: Mock어드민 페이지에 '오늘 자 매출 통계 메일 전송' 기능을 추가한다고 해보자. 이 기능을 테스트하려면 OrderStatisticsService를 실행해야 한다.// OrderStatisticsService.javapublic boolean sendOrderStatisticsMail(LocalDate orderDate, String email) { // 1. 해당 일자의 결제완료된 주문들을 가져온다. // 2. 총매출 합계를 계산한다. // 3. 메일을 전송한다. boolean result = mailService.sendMail(..., email, ..., ...); if (!result) { throw new IllegalArgu..
[Test] Presentation Layer Test(with Spring Boot)
·
Software Development/Test
지금까지 Repository와 Service 계층을 통합 테스트하며 아래에서 위로 올라왔다. 드디어 외부 세계의 요청을 가장 먼저 마주하는 Presentation Layer(Controller) 에 도착했다.Controller를 테스트할 때는 이전과 다른 전략을 사용한다. 하위 계층(Service)은 이미 충분히 테스트했고 잘 동작한다고 가정하고, Controller의 책임에만 집중하는 것이다. 이를 위해 Mocking을 사용한다.Controller 테스트와 MockingMock은 말 그대로 '가짜' 객체다. Controller가 의존하는 Service를 가짜 객체로 대체하면, 우리는 Service의 실제 로직과 상관없이 Controller의 동작(요청 매핑, 파라미터 검증 등)만을 순수하게 테스트할 수..
[Test] Business Layer Test(with Spring Boot)
·
Software Development/Test
지난 글에서는 Persistence Layer를 테스트하며 기반을 다졌다. 이제 애플리케이션의 핵심, 비즈니스 로직을 구현하는 Business Layer(Service) 를 테스트해볼 차례다.Business Layer (Service) 테스트Service 계층은 Persistence Layer와 상호작용하며 비즈니스 로직을 전개하고, 트랜잭션을 보장해야 하는 아주 중요한 역할이다. 여기서는 하위 Repository 계층까지 아우르는 통합 테스트를 진행하며 TDD 방식으로 개발해보자.요구사항: 상품 번호 리스트를 받아 주문을 생성한다.TDD 사이클에 따라, 실패하는 테스트부터 작성한다.// OrderServiceTest.java@SpringBootTest@ActiveProfiles("test")class ..
[Test] Persistence Layer Test(with Spring Boot, JPA)
·
Software Development/Test
통합 테스트의 필요성지금까지 단위 테스트, TDD, 테스트를 문서로 활용하는 법까지 알아봤다. 그런데 실제 애플리케이션은 수많은 객체(모듈)들이 서로 협력하며 동작한다. A 모듈과 B 모듈이 만났을 때, 우리가 예상한 대로 잘 동작할까?이걸 확인하려면 통합 테스트가 필요하다. 단위 테스트만으로는 전체 기능의 신뢰성을 보장하기 어렵기 때문에, 우리는 풍부한 단위 테스트와 함께 큰 기능 단위를 검증하는 통합 테스트를 병행해야 한다.이번 시리즈에서는 스프링 부트의 계층형 아키텍처(Layered Architecture)에서 각 계층을 어떻게 테스트하는지 알아보자. 그 첫 번째 주자는 데이터를 책임지는 Persistence Layer다.Repository (Persistence Layer) 테스트Persisten..
[Test] 테스트는 '문서'다.
·
Software Development/Test
테스트는 [ 문서 ]다.테스트 코드를 단순히 프로덕션 코드를 검증하는 도구라고만 생각하면, 그 가치의 절반밖에 보지 못하는 것이다. 나는 테스트 코드가 곧 '살아있는 문서'라고 생각한다.테스트가 왜 문서가 될까?생각해보자. 우리는 항상 팀으로 일한다. 내가 짠 코드를 언젠가 다른 동료가 봐야 하고, 내가 과거에 했던 고민을 그 동료가 또 똑같이 할 필요는 없다.바로 이때 테스트 코드가 빛을 발한다.다양한 테스트 케이스는 프로덕션 코드의 기능과 정책을 설명하는 가장 정확한 설명서가 된다.과거에 누군가 했던 고민의 결과물을 팀의 자산으로 만들어준다.새로운 팀원이 들어왔을 때, 테스트 코드를 통해 시스템의 동작 방식을 빠르게 이해할 수 있다.결국 잘 짜인 테스트는 동료를 위한 가장 친절한 가이드가 된다.좋은 ..
[Test] TDD(Test Driven Development)
·
Software Development/Test
TDD: 테스트가 개발을 이끈다?우리는 지금까지 테스트의 필요성과 단위 테스트 작성법에 대해 알아봤다. 이번에는 한 걸음 더 나아가, 아예 개발 프로세스 자체를 뒤집어보는 '테스트 주도 개발(TDD)'에 대해 이야기해보려 한다.TDD(Test Driven Development)란?TDD는 말 그대로 프로덕션 코드보다 테스트 코드를 먼저 작성해서, 테스트가 전체 구현 과정을 이끌어가는 개발 방법론이다."코드를 짜기도 전에 테스트를 어떻게 만들어?" 싶겠지만, TDD는 아주 구체적이고 체계적인 단계를 따른다.TDD의 심장: RED-GREEN-REFACTOR 사이클TDD는 아래 3단계를 끊임없이 반복하며 진행된다.실패하는 테스트부터 작성한다 (RED)우선 "이 기능은 이렇게 동작해야 해"라는 기대를 담아 테스..
[Test] 단위 테스트(Unit Test)
·
Software Development/Test
단위 테스트 파헤치기지난 글에서는 테스트가 귀찮지만 왜 필요한지에 대해 알아봤다. 이번에는 '단위 테스트'에 대해 좀 더 깊게 들어가 보자.단위 테스트(Unit Test)란?말 그대로 작은 코드 단위를 독립적으로 검증하는 테스트다. 보통 클래스나 메서드 하나가 그 대상이 된다. 다른 테스트에 비해 검증 속도가 매우 빠르고 안정적이라는 장점이 있다.Java에서는 보통 JUnit5라는 테스트 프레임워크를 사용한다. 여기에 AssertJ라는 라이브러리를 곁들이면, 풍부한 API와 메서드 체이닝을 통해 테스트 코드를 훨씬 깔끔하고 읽기 쉽게 작성할 수 있다.// JUnit5의 @Test 어노테이션과 AssertJ의 assertThat을 사용한 예시class CafeKioskTest { @Test vo..
[Test] 테스트를 해야 하는 이유
·
Software Development/Test
테스트는 귀찮다. 그럼에도 왜 해야 할까?솔직히 말해보자. 테스트는 귀찮다. 그럼에도 우리는 왜 테스트 코드를 작성해야만 할까?수동 테스트의 굴레Production Code가 있다고 해보자. 제품 출시를 위해 당연히 테스트가 필요하다.나, 또는 다른 개발자, 혹은 기획자나 QA 같은 동료가 직접 테스트를 시작한다. 웹사이트의 버튼을 하나하나 누르고, 앱에서 특정 기능을 실행해보고, 여러 값을 입력해본다. 예외적인 값도 넣어보며 꼼꼼히 검증한다.좋다. 이렇게 해서 첫 기능이 무사히 검증되었다. 곧이어 새로운 기능이 추가된다. 그럼 또 누군가가 처음부터 끝까지 테스트를 반복해야 한다.시간이 흘러 또 다른 기능이 추가되었는데, 이번엔 기존 프로덕션 코드의 일부가 변경되었다. 이제 문제는 더 복잡해진다. 새로 ..