Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

2,564 views

Published on

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

Published in: Technology
  • Be the first to comment

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

  1. 1. 무엇을 어떻게 테스트할 것인가?
  2. 2. co-duck.com
  3. 3. co-duck.com
  4. 4. 배달의민족 사용법 목록 진입 가게 진입 주문 결제
  5. 5. 프론트 시스템 개편 주문 시스템 개편 결제 시스템 개편
  6. 6. 권용근 kingbbode@gmail.com
  7. 7. •테스트로 얻을 수 있는 것 •무엇을 테스트할 것인가? •어떻게 테스트할 것인가? •Tip & Rule
  8. 8. 테스트로부터 얻을 수 있는 것
  9. 9. 안정감과 자신감
  10. 10. •현재와 미래의 나 •현재와 미래의 동료 대상은?
  11. 11. 무엇을 테스트할 것인가?
  12. 12. “로또를 구현하라!”
  13. 13. 요청 6개 숫자 생성
  14. 14. •6개의 숫자를 반환 •중복되지 않은 숫자 •랜덤하게 반환 요구사항을 정리해보면..
  15. 15. 1. 구현 vs 설계
  16. 16. 1. 빈 Set을 만들고
  17. 17. 2. 전체 숫자들을 생성하고
  18. 18. 3. 숫자를 Collections.shuffle 로 섞어준다.
  19. 19. 4. 6개의 숫자가 될 때까지 add()
  20. 20. •6개의 숫자를 반환 •중복되지 않은 숫자 •랜덤하게 반환
  21. 21. •6개의 숫자를 반환 •중복되지 않은 숫자 •랜덤하게 반환
  22. 22. “중복에 대해서도 테스트되어야 하지 않을까요?”
  23. 23. “중복에 대해서도 테스트되어야 하지 않을까요?” “저는 Set 으로 구현해서 중복이 나올 수가 없어요.”
  24. 24. “중복에 대해서도 테스트되어야 하지 않을까요?” “저는 Set 으로 구현해서 중복이 나올 수가 없어요.”
  25. 25. 구현은 언젠가 어떻게든 변할 수 있다
  26. 26. 장애배포
  27. 27. 편안배포
  28. 28. public A actA() void actATest() 구현 테스트
  29. 29. public A actA() void actATest() public B actB() void actBTest() 구현 테스트
  30. 30. public A actA() void actATest() public B actB() void actBTest() public C actC() void actCTest() 구현 테스트
  31. 31. public A actA() void actATest() public B actB() void actBTest() public C actC() void actCTest() private D actD() ! 구현 테스트
  32. 32. public A actA() void actATest() public B actB() void actBTest() public C actC() void actCTest() private D actD() ! 구현 테스트 여기서 공감했다면 구현 테스트를 하고 있을 가능성이 매우 큼
  33. 33. public A actA() void actATest() public B actB() void actBTest() public C actC() void actCTest() void actC2Test()
  34. 34. 구현을
  35. 35. 구현을 테스트
  36. 36. 구현을 테스트
  37. 37. 설계를
  38. 38. 설계를 테스트
  39. 39. 설계를 테스트
  40. 40. “설계를 테스트”
  41. 41. 2. 테스트 가능한 것, 불가능한 것
  42. 42. “[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기” 중
  43. 43. Non-Testable • Random, Shuffle, LocalDate.now() • 외부 세계 • HTTP • 외부 저장소 “제어할 수 없는 영역”
  44. 44. 테스트 외부 API
  45. 45. 테스트 외부 API 값 변경 배포 장애
  46. 46. 테스트 외부 API FAIL!
  47. 47. 테스트 외부 API FAIL! “제어할 수 없는 영역은 멱등한 결과를 보장할 수 없다”
  48. 48. •6개의 숫자를 반환 •중복되지 않은 숫자 •랜덤하게 반환
  49. 49. •6개의 숫자를 반환 •중복되지 않은 숫자 •랜덤하게 반환테스트 불가능한 것
  50. 50. •6개의 숫자를 반환 •중복되지 않은 숫자 •랜덤하게 반환 의도한 전략대로 반환
  51. 51. “항상 성공할 수 있는 것, 항상 동일한 결과가 나올 수 있는 것을 테스트”
  52. 52. 어떻게 테스트할 것인가?
  53. 53. 1. 테스트 가능한 것, 불가능한 것
  54. 54. “[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기” 중
  55. 55. “[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기” 중
  56. 56. 거리 배달팁 배달팁 할인 배달팁 계산
  57. 57. 배달팁 계산 거리 배달팁 배달팁 할인
  58. 58. calculateDeliveryTip calculateDeliveryTip caculateDiscount배달팁 계산 배달팁 할인 계산 deliveryTipController isValid calculateNow calculateNow isValid 배달팁 계산
  59. 59. Non-Testable • Random, Shuffle, LocalDate.now() • 외부 세계 • HTTP • 외부 저장소 “제어할 수 없는 영역”
  60. 60. calculateDeliveryTip calculateDeliveryTip caculateDiscount배달팁 계산 배달팁 할인 계산 deliveryTipController isValid calculateNow calculateNow isValidNon-Testable 배달팁 계산
  61. 61. calculateDeliveryTip calculateDeliveryTip caculateDiscount deliveryTipController isValid calculateNow calculateNow isValid Non-Testable 배달팁 계산
  62. 62. “[OKKY 세미나] 정진욱 - 테스트하기 쉬운 코드로 개발하기” 중 ?
  63. 63. calculateDeliveryTip calculateDeliveryTip caculateDiscount deliveryTipController isValid calculateNow calculateNow isValid Non-Testable 배달팁 계산
  64. 64. calculateDeliveryTip calculateDeliveryTip caculateDiscount deliveryTipController isValid(LocalDateTime) calculateNow calculateNow Non-Testable isValid(LocalDateTime) 배달팁 계산
  65. 65. calculateDeliveryTip calculateDeliveryTip caculateDiscount deliveryTipController isValid(LocalDateTime) calculateNow(LocalDateTime) calculateNow(LocalDateTime) Non-Testable isValid(LocalDateTime) 배달팁 계산
  66. 66. •현재 시간에 해당하는 배달팁과 할인 금액 합산 특정 시간에 해당하는 배달팁과 할인 금액 합산
  67. 67. calculateDeliveryTip calculateDeliveryTip caculateDiscount deliveryTipController isValid(LocalDateTime) calculateAt(LocalDateTime) calculateAt(LocalDateTime) Non-Testable isValid(LocalDateTime) 배달팁 계산
  68. 68. calculateDeliveryTip calculateDeliveryTip(LocalDateTime) caculateDiscount(LocalDateTime) deliveryTipController isValid(LocalDateTime) calculateAt(LocalDateTime) calculateAt(LocalDateTime) Non-Testable isValid(LocalDateTime) 배달팁 계산
  69. 69. calculateDeliveryTip(LocalDateTime) calculateDeliveryTip(LocalDateTime) caculateDiscount(LocalDateTime) deliveryTipController isValid(LocalDateTime) calculateAt(LocalDateTime) calculateAt(LocalDateTime) Non-Testable isValid(LocalDateTime) 배달팁 계산
  70. 70. 배달팁 계산 calculateDeliveryTip(LocalDateTime) calculateDeliveryTip(LocalDateTime) caculateDiscount(LocalDateTime) deliveryTipController isValid(LocalDateTime) calculateAt(LocalDateTime) calculateAt(LocalDateTime) Non-Testable isValid(LocalDateTime) 한 모듈로서의 의미를 지니는 가장 바깥 쪽
  71. 71. “테스트 불가능한 영역을 
 Boundary Layer 로 올려서 
 테스트 가능하도록 변경”
  72. 72. 2. Java, Spring Framework
  73. 73. 위에서 했었던..
  74. 74. “로또를 웹으로 구현하라!”
  75. 75. @Bean @Service @Compoent Spring Framework! Bean으로 만들어야겠지?
  76. 76. @SpringBootTest Test 는 Boot 로!
  77. 77. @SpringBootTest
  78. 78. Spring Context 가 필요할까?
  79. 79. Spring Context 가 필요없다.
  80. 80. Spring Context 가 필요할까?
  81. 81. Spring Context 가 필요없다.
  82. 82. Spring Context 는 느리다 빠른 피드백을 받을 수 없다.
  83. 83. Spring Framework에서 이 필드의 의미는?
  84. 84. Spring Framework에 이 필드의 의미는? 필수 의존성
  85. 85. Java 에서 이 필드의 의미는?
  86. 86. Java 에서 이 필드의 의미는? Nullable
  87. 87. Spring Context 의 오용은 언어의 본질을 망각하게 할 수 있다.
  88. 88. Java? Spring Framework?
  89. 89. “Context, Framework 종속적이지 
 않은 테스트를 우선”
  90. 90. 3. Test Double
  91. 91. 테스트 할 수 없는 영역에 대한 외부 요인을 부여할 수 있도록 도와줌
  92. 92. Java Mocking Framework
  93. 93. “무엇을 Test Double 로 처리해야할까”
  94. 94. 1 2 3 4 테스트 하고 싶은 영역
  95. 95. TestDouble TestDouble TestDouble 1 2 3 4 Test Double 을 사용하는 것은 테스트가 구현을 알아야 한다는 것
  96. 96. TestDouble TestDouble TestDouble 1 2 3 4
  97. 97. TestDouble TestDouble TestDouble 1 2 3 4 반환 타입 변경
  98. 98. TestDouble TestDouble TestDouble 1 2 3 4 입력 값 변경
  99. 99. TestDouble TestDouble TestDouble 1 2 3 4 Test Double 의 남용은 구현 테스트로 유도할 수도 있다.
  100. 100. 1 2 3 4 Boundary Context 까지 끌어올려진 Non-Testable
  101. 101. 1 2 3 4 TestDouble
  102. 102. “편리하지만 사용을 의식하여 최소화”
  103. 103. 순수 자바 어플리케이션으로는 
 테스트할 수 없는 것
  104. 104. • 저장소 입출력 검증 • SPEC 검증 • 내부 Controller • 외부 API
  105. 105. 4. Embedded
  106. 106. Spring Data JPA High Level Client Row Level Client Spring Cloud
  107. 107. “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
  108. 108. System 제어할 수 없는 영역을
  109. 109. System 제어 가능하도록 만들 수 있다
  110. 110. 테스트 시작 테스트 종료 Embedded 
 시스템 시작 Embedded 
 시스템 종료 테스트와 Embedded 시스템은 동일한 라이프사이클을 갖도록 구성
  111. 111. 테스트와 Embedded 시스템은 동일한 라이프사이클을 갖도록 구성
  112. 112. Local Embedded테스트 정확도 > Local Embedded테스트 피드백 속도 < Local Embedded테스트 안정성 <
  113. 113. 5. EndPoint Test
  114. 114. •MockMvc •REST Assured •WebTestClient Spring Framework Support
  115. 115. @Controller @Service @Repository 요청 스팩 검증 응답 스팩 검증
  116. 116. @Controller @MockBean 요청 스팩 검증 응답 스팩 검증 테스트의 목적은 요청과 응답 스팩 검증만으로 제한하는게 정신 건강에 좋을 것이라고 생각
  117. 117. • 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
  118. 118. http://woowabros.github.io/experience/2018/12/28/spring-rest-docs.html Spring REST Docs
  119. 119. 6. Spring Cloud Contract
  120. 120. [Consumer] Contract PR
  121. 121. [Producer] Generate Contract Test
  122. 122. [Producer] Test
  123. 123. [Producer] Test
  124. 124. [Consumer] Test
  125. 125. TIP & RULE
  126. 126. 1. 테스트는 상호 독립적으로 작성
  127. 127. TEST1: 데이터 삽입 TEST2 : 데이터 수정
  128. 128. TEST1: 데이터 삽입 TEST2 : 데이터 수정 TEST3 : 데이터 삭제
  129. 129. TEST1: 데이터 삽입 TEST2 : 데이터 수정 TEST3 : 데이터 삭제
  130. 130. 모든 테스트의 순서와 관계를 생각하며 테스트를 작성하기 어려움
  131. 131. 공유되는 자원은 초기화하여 다른 테스트에 영향을 받지 않도록 TEST1 TEST2 @After void tearDown { allDataSource.clear() }
  132. 132. 테스트 간 서로 영향을 미치지 않도록 테스트는 상호 독립적으로 작성
  133. 133. 단계가 필요하다면 JUnit 5의 DynamicTest 추천
  134. 134. 2. 테스트 안에 의도와 목 이 
 드러나도록 작성
  135. 135. @Test { } 어떠한 조건에서 무엇을 수행했을 때 어떤 결과가
  136. 136. @Test { } 무엇을 수행했을 때 어떤 결과가 어떠한 조건에서 Import.sql @Before TestConfiguration @Test
  137. 137. @Test { } 어떤 결과가 어떠한 조건에서 무엇을 수행했을 때 Import.sql @Before TestConfiguration @Test
  138. 138. @Test { } 어떠한 조건에서 무엇을 수행했을 때 어떤 결과가 테스트 코드 역시 가독이 중요
  139. 139. 3. 테스트 코드도 리펙토링 대상
  140. 140. @Test CODE CODE CODE @Test
  141. 141. @Test CODE CODE CODE @Test CODE @Test
  142. 142. @Test CODE CODE CODE @Test CODE @Test @Test
  143. 143. @Test CODE CODE CODE @Test CODE CODE @Test @Test @Test 시간이 흐름에 따라 코드는 늘어갈 것
  144. 144. @Test CODE CODE CODE @Test CODE CODE @Test @Test @Test 시간이 흐름에 따라 코드 와 테스트는 늘어갈 것
  145. 145. @Test CODE CODE CODE @Test @Test @Test @Test 리펙토링!
  146. 146. @Test CODE CODE CODE @Test @Test @Test 리펙토링!
  147. 147. @Test CODE CODE CODE @Test @Test @Test 코드양에 대한 이야기가 아닌 가독, 안정성, 요구사항 정리 등 비지니스 코드와 동일한 수준의 리팩토링이 함께 이루어져야 한다
  148. 148. 정리
  149. 149. 무엇을 테스트할 것인가?
 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. 테스트 코드도 리펙토링
  150. 150. 그러나 가장 중요한 것은 안정감과 자신감 기준을 최대한 지키되 기준을 지키기 위해 안정감과 자신감을 포기할 필요는 없다.

×