SlideShare a Scribd company logo
1 of 160
Download to read offline
무엇을
어떻게
테스트할 것인가?
co-duck.com
co-duck.com
배달의민족 사용법
목록 진입 가게 진입 주문 결제
프론트 시스템 개편 주문 시스템 개편 결제 시스템 개편
권용근
kingbbode@gmail.com
•테스트로 얻을 수 있는 것
•무엇을 테스트할 것인가?
•어떻게 테스트할 것인가?
•Tip & Rule
테스트로부터
얻을 수 있는 것
안정감과 자신감
•현재와 미래의 나
•현재와 미래의 동료
대상은?
무엇을 테스트할 것인가?
“로또를 구현하라!”
요청
6개 숫자 생성
•6개의 숫자를 반환
•중복되지 않은 숫자
•랜덤하게 반환
요구사항을 정리해보면..
1. 구현 vs 설계
1. 빈 Set을 만들고
2. 전체 숫자들을 생성하고
3. 숫자를 Collections.shuffle 로 섞어준다.
4. 6개의 숫자가 될 때까지 add()
•6개의 숫자를 반환
•중복되지 않은 숫자
•랜덤하게 반환
•6개의 숫자를 반환
•중복되지 않은 숫자
•랜덤하게 반환
“중복에 대해서도 테스트되어야 하지 않을까요?”
“중복에 대해서도 테스트되어야 하지 않을까요?”
“저는 Set 으로 구현해서 중복이 나올 수가 없어요.”
“중복에 대해서도 테스트되어야 하지 않을까요?”
“저는 Set 으로 구현해서 중복이 나올 수가 없어요.”
구현은 언젠가 어떻게든 변할 수 있다
장애배포
편안배포
public A actA() void actATest()
구현 테스트
public A actA() void actATest()
public B actB() void actBTest()
구현 테스트
public A actA() void actATest()
public B actB() void actBTest()
public C actC() void actCTest()
구현 테스트
public A actA() void actATest()
public B actB() void actBTest()
public C actC() void actCTest()
private D actD()
!
구현 테스트
public A actA() void actATest()
public B actB() void actBTest()
public C actC() void actCTest()
private D actD()
!
구현 테스트
여기서 공감했다면
구현 테스트를 하고 있을 가능성이 매우 큼
public A actA() void actATest()
public B actB() void actBTest()
public C actC() void actCTest()
void actC2Test()
구현을
구현을 테스트
구현을 테스트
설계를
설계를 테스트
설계를 테스트
“설계를 테스트”
2. 테스트 가능한 것, 불가능한 것
“[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기” 중
Non-Testable
• Random, Shuffle, LocalDate.now()

• 외부 세계

• HTTP

• 외부 저장소
“제어할 수 없는 영역”
테스트
외부 API
테스트
외부 API
값 변경
배포
장애
테스트
외부 API
FAIL!
테스트
외부 API
FAIL!
“제어할 수 없는 영역은 멱등한 결과를 보장할 수 없다”
•6개의 숫자를 반환
•중복되지 않은 숫자
•랜덤하게 반환
•6개의 숫자를 반환
•중복되지 않은 숫자
•랜덤하게 반환테스트 불가능한 것
•6개의 숫자를 반환
•중복되지 않은 숫자
•랜덤하게 반환 의도한 전략대로 반환
“항상 성공할 수 있는 것,
항상 동일한 결과가 나올 수 있는 것을
테스트”
어떻게 테스트할 것인가?
1. 테스트 가능한 것, 불가능한 것
“[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기” 중
“[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기” 중
거리
배달팁 배달팁 할인
배달팁 계산
배달팁 계산
거리
배달팁 배달팁 할인
calculateDeliveryTip
calculateDeliveryTip caculateDiscount배달팁 계산 배달팁 할인 계산
deliveryTipController
isValid
calculateNow calculateNow
isValid
배달팁 계산
Non-Testable
• Random, Shuffle, LocalDate.now()

• 외부 세계

• HTTP

• 외부 저장소
“제어할 수 없는 영역”
calculateDeliveryTip
calculateDeliveryTip caculateDiscount배달팁 계산 배달팁 할인 계산
deliveryTipController
isValid
calculateNow calculateNow
isValidNon-Testable
배달팁 계산
calculateDeliveryTip
calculateDeliveryTip caculateDiscount
deliveryTipController
isValid
calculateNow calculateNow
isValid
Non-Testable
배달팁 계산
“[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기” 중
?
calculateDeliveryTip
calculateDeliveryTip caculateDiscount
deliveryTipController
isValid
calculateNow calculateNow
isValid
Non-Testable
배달팁 계산
calculateDeliveryTip
calculateDeliveryTip caculateDiscount
deliveryTipController
isValid(LocalDateTime)
calculateNow calculateNow
Non-Testable
isValid(LocalDateTime)
배달팁 계산
calculateDeliveryTip
calculateDeliveryTip caculateDiscount
deliveryTipController
isValid(LocalDateTime)
calculateNow(LocalDateTime) calculateNow(LocalDateTime)
Non-Testable
isValid(LocalDateTime)
배달팁 계산
•현재 시간에 해당하는 배달팁과 할인 금액 합산
특정 시간에 해당하는 배달팁과 할인 금액 합산
calculateDeliveryTip
calculateDeliveryTip caculateDiscount
deliveryTipController
isValid(LocalDateTime)
calculateAt(LocalDateTime) calculateAt(LocalDateTime)
Non-Testable
isValid(LocalDateTime)
배달팁 계산
calculateDeliveryTip
calculateDeliveryTip(LocalDateTime) caculateDiscount(LocalDateTime)
deliveryTipController
isValid(LocalDateTime)
calculateAt(LocalDateTime) calculateAt(LocalDateTime)
Non-Testable
isValid(LocalDateTime)
배달팁 계산
calculateDeliveryTip(LocalDateTime)
calculateDeliveryTip(LocalDateTime) caculateDiscount(LocalDateTime)
deliveryTipController
isValid(LocalDateTime)
calculateAt(LocalDateTime) calculateAt(LocalDateTime)
Non-Testable
isValid(LocalDateTime)
배달팁 계산
배달팁 계산
calculateDeliveryTip(LocalDateTime)
calculateDeliveryTip(LocalDateTime) caculateDiscount(LocalDateTime)
deliveryTipController
isValid(LocalDateTime)
calculateAt(LocalDateTime) calculateAt(LocalDateTime)
Non-Testable
isValid(LocalDateTime)
한 모듈로서의 의미를 지니는 가장 바깥 쪽
“테스트 불가능한 영역을 

Boundary Layer 로 올려서 

테스트 가능하도록 변경”
2. Java, Spring Framework
위에서 했었던..
“로또를 웹으로 구현하라!”
@Bean
@Service
@Compoent
Spring Framework! Bean으로 만들어야겠지?
@SpringBootTest
Test 는 Boot 로!
@SpringBootTest
Spring Context 가 필요할까?
Spring Context 가 필요없다.
Spring Context 가 필요할까?
Spring Context 가 필요없다.
Spring Context 는 느리다
빠른 피드백을 받을 수 없다.
Spring Framework에서 이 필드의 의미는?
Spring Framework에 이 필드의 의미는?
필수 의존성
Java 에서 이 필드의 의미는?
Java 에서 이 필드의 의미는?
Nullable
Spring Context 의 오용은
언어의 본질을 망각하게 할 수 있다.
Java? Spring Framework?
“Context, Framework 종속적이지 

않은 테스트를 우선”
3. Test Double
테스트 할 수 없는 영역에 대한 외부 요인을 부여할 수 있도록 도와줌
Java Mocking Framework
“무엇을 Test Double 로 처리해야할까”
1 2 3 4
테스트 하고 싶은 영역
TestDouble TestDouble TestDouble
1 2 3 4
Test Double 을 사용하는 것은
테스트가 구현을 알아야 한다는 것
TestDouble TestDouble TestDouble
1 2 3 4
TestDouble TestDouble TestDouble
1 2 3 4
반환 타입 변경
TestDouble TestDouble TestDouble
1 2 3 4
입력 값 변경
TestDouble TestDouble TestDouble
1 2 3 4
Test Double 의 남용은 구현 테스트로 유도할 수도 있다.
1 2 3 4
Boundary Context 까지
끌어올려진 Non-Testable
1 2 3 4
TestDouble
“편리하지만 사용을 의식하여 최소화”
순수 자바 어플리케이션으로는 

테스트할 수 없는 것
• 저장소 입출력 검증

• SPEC 검증

• 내부 Controller

• 외부 API
4. Embedded
Spring Data
JPA
High Level Client
Row Level Client
Spring Cloud
“Embedded 활용 가능”
RDB h2database/h2
Redis kstyrc/embedded-redis
Mongo flapdoodle-oss/de.flapdoodle.embed.mongo
Dynamo amazonaws/DynamoDBLocal
MQ softwaremill/elasticmq
SQS jojoldu/spring-boot-aws-mock
System
제어할 수 없는 영역을
System
제어 가능하도록 만들 수 있다
테스트 시작
테스트 종료
Embedded 

시스템
시작
Embedded 

시스템
종료
테스트와 Embedded 시스템은 동일한 라이프사이클을 갖도록 구성
테스트와 Embedded 시스템은 동일한 라이프사이클을 갖도록 구성
Local Embedded테스트 정확도 >
Local Embedded테스트 피드백 속도 <
Local Embedded테스트 안정성 <
5. EndPoint Test
•MockMvc
•REST Assured
•WebTestClient
Spring Framework Support
@Controller
@Service
@Repository
요청 스팩 검증 응답 스팩 검증
@Controller
@MockBean
요청 스팩 검증 응답 스팩 검증
테스트의 목적은 요청과 응답 스팩 검증만으로 제한하는게 정신 건강에 좋을 것이라고 생각
• MockMvc With RestDocs
• REST Assured With RestDocs
• WebTestClient With RestDocs
테스트와 문서를 한방에!
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications-testing-autoconfigured-rest-docs
http://woowabros.github.io/experience/2018/12/28/spring-rest-docs.html
Spring REST Docs
6. Spring Cloud Contract
[Consumer] Contract PR
[Producer] Generate Contract Test
[Producer] Test
[Producer] Test
[Consumer] Test
TIP & RULE
1. 테스트는 상호 독립적으로 작성
TEST1: 데이터 삽입
TEST2 : 데이터 수정
TEST1: 데이터 삽입
TEST2 : 데이터 수정
TEST3 : 데이터 삭제
TEST1: 데이터 삽입
TEST2 : 데이터 수정
TEST3 : 데이터 삭제
모든 테스트의 순서와 관계를 생각하며 테스트를 작성하기 어려움
공유되는 자원은 초기화하여 다른 테스트에 영향을 받지 않도록
TEST1
TEST2
@After
void tearDown {
allDataSource.clear()
}
테스트 간 서로 영향을 미치지 않도록
테스트는 상호 독립적으로 작성
단계가 필요하다면 JUnit 5의 DynamicTest 추천
2. 테스트 안에 의도와 목 이 

드러나도록 작성
@Test
{
}
어떠한 조건에서
무엇을 수행했을 때
어떤 결과가
@Test
{
}
무엇을 수행했을 때
어떤 결과가
어떠한 조건에서
Import.sql
@Before
TestConfiguration
@Test
@Test
{
}
어떤 결과가
어떠한 조건에서
무엇을 수행했을 때
Import.sql
@Before
TestConfiguration
@Test
@Test
{
}
어떠한 조건에서
무엇을 수행했을 때
어떤 결과가
테스트 코드 역시 가독이 중요
3. 테스트 코드도 리펙토링 대상
@Test
CODE
CODE
CODE @Test
@Test
CODE
CODE
CODE @Test
CODE @Test
@Test
CODE
CODE
CODE @Test
CODE @Test
@Test
@Test
CODE
CODE
CODE @Test
CODE
CODE
@Test
@Test
@Test
시간이 흐름에 따라 코드는 늘어갈 것
@Test
CODE
CODE
CODE @Test
CODE
CODE
@Test
@Test
@Test
시간이 흐름에 따라 코드 와 테스트는 늘어갈 것
@Test
CODE
CODE
CODE @Test
@Test
@Test
@Test
리펙토링!
@Test
CODE
CODE
CODE @Test
@Test
@Test
리펙토링!
@Test
CODE
CODE
CODE @Test
@Test
@Test
코드양에 대한 이야기가 아닌 가독, 안정성, 요구사항 정리 등
비지니스 코드와 동일한 수준의 리팩토링이 함께 이루어져야 한다
정리
무엇을 테스트할 것인가?

1. 설계를 테스트
2. 테스트 가능한 것을 테스트
어떻게 테스트할 것인가?

1. 테스트 불가능한 영역을 Boundary Layer 까지 올려서 테스트 가능하도록 변경
2. Context, Framework 종속적이지 않도록 테스트
3. Test Double 사용
4. Embedded System 사용
5. EndPoint Test 도구 사용하여 내부 API Spec 테스트
6. Spring Cloud Contract 로 외부 API Spec 테스트
TIP & RULE
1. 테스트는 상호 독립적으로 작성
2. 테스트 안에서 의도와 목적이 모두 드러나도록 작성
3. 테스트 코드도 리펙토링
그러나 가장 중요한 것은 안정감과 자신감
기준을 최대한 지키되 기준을 지키기 위해
안정감과 자신감을 포기할 필요는 없다.

More Related Content

What's hot

Workshop spring session 2 - La persistance au sein des applications Java
Workshop spring   session 2 - La persistance au sein des applications JavaWorkshop spring   session 2 - La persistance au sein des applications Java
Workshop spring session 2 - La persistance au sein des applications Java
Antoine Rey
 
소프트웨어 테스팅
소프트웨어 테스팅소프트웨어 테스팅
소프트웨어 테스팅
영기 김
 

What's hot (20)

JMockit Framework Overview
JMockit Framework OverviewJMockit Framework Overview
JMockit Framework Overview
 
우아한테크세미나-우아한멀티모듈
우아한테크세미나-우아한멀티모듈우아한테크세미나-우아한멀티모듈
우아한테크세미나-우아한멀티모듈
 
JUnit & Mockito, first steps
JUnit & Mockito, first stepsJUnit & Mockito, first steps
JUnit & Mockito, first steps
 
Workshop spring session 2 - La persistance au sein des applications Java
Workshop spring   session 2 - La persistance au sein des applications JavaWorkshop spring   session 2 - La persistance au sein des applications Java
Workshop spring session 2 - La persistance au sein des applications Java
 
JS Event Loop
JS Event LoopJS Event Loop
JS Event Loop
 
Writing and using Hamcrest Matchers
Writing and using Hamcrest MatchersWriting and using Hamcrest Matchers
Writing and using Hamcrest Matchers
 
API 101 event.pdf
API 101 event.pdfAPI 101 event.pdf
API 101 event.pdf
 
소프트웨어 테스팅
소프트웨어 테스팅소프트웨어 테스팅
소프트웨어 테스팅
 
[112]rest에서 graph ql과 relay로 갈아타기 이정우
[112]rest에서 graph ql과 relay로 갈아타기 이정우[112]rest에서 graph ql과 relay로 갈아타기 이정우
[112]rest에서 graph ql과 relay로 갈아타기 이정우
 
JMockit
JMockitJMockit
JMockit
 
API Testing following the Test Pyramid
API Testing following the Test PyramidAPI Testing following the Test Pyramid
API Testing following the Test Pyramid
 
API Test Automation
API Test Automation API Test Automation
API Test Automation
 
Formation jpa-hibernate-spring-data
Formation jpa-hibernate-spring-dataFormation jpa-hibernate-spring-data
Formation jpa-hibernate-spring-data
 
Mockito
MockitoMockito
Mockito
 
Asynchronous javascript
 Asynchronous javascript Asynchronous javascript
Asynchronous javascript
 
Integration Testing with a Citrus twist
Integration Testing with a Citrus twistIntegration Testing with a Citrus twist
Integration Testing with a Citrus twist
 
Introduce Katalon tool
Introduce Katalon toolIntroduce Katalon tool
Introduce Katalon tool
 
Postman Collection Format v2.0 (pre-draft)
Postman Collection Format v2.0 (pre-draft)Postman Collection Format v2.0 (pre-draft)
Postman Collection Format v2.0 (pre-draft)
 
From framework coupled code to #microservices through #DDD /by @codelytv
From framework coupled code to #microservices through #DDD /by @codelytvFrom framework coupled code to #microservices through #DDD /by @codelytv
From framework coupled code to #microservices through #DDD /by @codelytv
 
TestNG
TestNGTestNG
TestNG
 

Similar to KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"

Growing object oriented software guided by test
Growing object oriented software guided by testGrowing object oriented software guided by test
Growing object oriented software guided by test
라한사 아
 
xUnitTestPattern/chapter16
xUnitTestPattern/chapter16xUnitTestPattern/chapter16
xUnitTestPattern/chapter16
suitzero
 
Devon 2011-b-5 효과적인 레거시 코드 다루기
Devon 2011-b-5 효과적인 레거시 코드 다루기Devon 2011-b-5 효과적인 레거시 코드 다루기
Devon 2011-b-5 효과적인 레거시 코드 다루기
Daum DNA
 
TDD&Refactoring Day 03: TDD
TDD&Refactoring Day 03: TDDTDD&Refactoring Day 03: TDD
TDD&Refactoring Day 03: TDD
Suwon Chae
 
테스트 자동화의 원칙
테스트 자동화의 원칙테스트 자동화의 원칙
테스트 자동화의 원칙
codevania
 
테크데이 발표자료.pptx.pdf
테크데이 발표자료.pptx.pdf테크데이 발표자료.pptx.pdf
테크데이 발표자료.pptx.pdf
Jihoon Kim
 

Similar to KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가" (20)

테스터가 말하는 테스트코드 작성 팁과 사례
테스터가 말하는 테스트코드 작성 팁과 사례테스터가 말하는 테스트코드 작성 팁과 사례
테스터가 말하는 테스트코드 작성 팁과 사례
 
Robot framework 을 이용한 기능 테스트 자동화
Robot framework 을 이용한 기능 테스트 자동화Robot framework 을 이용한 기능 테스트 자동화
Robot framework 을 이용한 기능 테스트 자동화
 
클린코드와 테스트코드
클린코드와 테스트코드클린코드와 테스트코드
클린코드와 테스트코드
 
테스트 기발 개발, TBD(Test based developement)
테스트 기발 개발, TBD(Test based developement)테스트 기발 개발, TBD(Test based developement)
테스트 기발 개발, TBD(Test based developement)
 
TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기
 
Clean code chapter9
Clean code chapter9Clean code chapter9
Clean code chapter9
 
S66 goos-w7
S66 goos-w7S66 goos-w7
S66 goos-w7
 
아꿈사.C++ api 디자인.20140315 a
아꿈사.C++ api 디자인.20140315 a아꿈사.C++ api 디자인.20140315 a
아꿈사.C++ api 디자인.20140315 a
 
행복한 개발을 위한_테스트_케이스
행복한 개발을 위한_테스트_케이스행복한 개발을 위한_테스트_케이스
행복한 개발을 위한_테스트_케이스
 
[H3 2012] 행복한 개발을 위한 테스트 케이스
[H3 2012] 행복한 개발을 위한 테스트 케이스[H3 2012] 행복한 개발을 위한 테스트 케이스
[H3 2012] 행복한 개발을 위한 테스트 케이스
 
Growing object oriented software guided by test
Growing object oriented software guided by testGrowing object oriented software guided by test
Growing object oriented software guided by test
 
xUnitTestPattern/chapter16
xUnitTestPattern/chapter16xUnitTestPattern/chapter16
xUnitTestPattern/chapter16
 
Devon 2011-b-5 효과적인 레거시 코드 다루기
Devon 2011-b-5 효과적인 레거시 코드 다루기Devon 2011-b-5 효과적인 레거시 코드 다루기
Devon 2011-b-5 효과적인 레거시 코드 다루기
 
자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)
자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)
자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)
 
TDD&Refactoring Day 03: TDD
TDD&Refactoring Day 03: TDDTDD&Refactoring Day 03: TDD
TDD&Refactoring Day 03: TDD
 
테스트 자동화의 원칙
테스트 자동화의 원칙테스트 자동화의 원칙
테스트 자동화의 원칙
 
C++과 TDD
C++과 TDDC++과 TDD
C++과 TDD
 
JUnit 지원 라이브러리 소개
JUnit 지원 라이브러리 소개JUnit 지원 라이브러리 소개
JUnit 지원 라이브러리 소개
 
테크데이 발표자료.pptx.pdf
테크데이 발표자료.pptx.pdf테크데이 발표자료.pptx.pdf
테크데이 발표자료.pptx.pdf
 
Tdd live spring camp 2013
Tdd live spring camp 2013Tdd live spring camp 2013
Tdd live spring camp 2013
 

Recently uploaded

Console API (Kitworks Team Study 백혜인 발표자료)
Console API (Kitworks Team Study 백혜인 발표자료)Console API (Kitworks Team Study 백혜인 발표자료)
Console API (Kitworks Team Study 백혜인 발표자료)
Wonjun Hwang
 
Merge (Kitworks Team Study 이성수 발표자료 240426)
Merge (Kitworks Team Study 이성수 발표자료 240426)Merge (Kitworks Team Study 이성수 발표자료 240426)
Merge (Kitworks Team Study 이성수 발표자료 240426)
Wonjun Hwang
 

Recently uploaded (6)

Console API (Kitworks Team Study 백혜인 발표자료)
Console API (Kitworks Team Study 백혜인 발표자료)Console API (Kitworks Team Study 백혜인 발표자료)
Console API (Kitworks Team Study 백혜인 발표자료)
 
A future that integrates LLMs and LAMs (Symposium)
A future that integrates LLMs and LAMs (Symposium)A future that integrates LLMs and LAMs (Symposium)
A future that integrates LLMs and LAMs (Symposium)
 
Merge (Kitworks Team Study 이성수 발표자료 240426)
Merge (Kitworks Team Study 이성수 발표자료 240426)Merge (Kitworks Team Study 이성수 발표자료 240426)
Merge (Kitworks Team Study 이성수 발표자료 240426)
 
MOODv2 : Masked Image Modeling for Out-of-Distribution Detection
MOODv2 : Masked Image Modeling for Out-of-Distribution DetectionMOODv2 : Masked Image Modeling for Out-of-Distribution Detection
MOODv2 : Masked Image Modeling for Out-of-Distribution Detection
 
캐드앤그래픽스 2024년 5월호 목차
캐드앤그래픽스 2024년 5월호 목차캐드앤그래픽스 2024년 5월호 목차
캐드앤그래픽스 2024년 5월호 목차
 
Continual Active Learning for Efficient Adaptation of Machine LearningModels ...
Continual Active Learning for Efficient Adaptation of Machine LearningModels ...Continual Active Learning for Efficient Adaptation of Machine LearningModels ...
Continual Active Learning for Efficient Adaptation of Machine LearningModels ...
 

KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"