├── LICENSE ├── README.md ├── image ├── agile │ ├── scrum-nexus.png │ └── scrum.png ├── ci-cd │ ├── aws-ci-cd.png │ ├── continuous-delivery-deployment.png │ └── redhat-ci-cd.png ├── tdd-global-lifecycle.png └── xp-circles.jpg └── reference ├── agile ├── ci-cd.md ├── continuous-integration.md └── user-story.md ├── commit-message.md ├── object └── elegant-object.md ├── refactoring-2.md ├── the-software-craftsman.md └── unit-testing-junit.md /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2021 TDD Kata 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TDD 2 | 3 | - [TDD](#tdd) 4 | - [참고 자료](#참고-자료) 5 | - [Book](#book) 6 | - [Article](#article) 7 | - [Video](#video) 8 | - [Language](#language) 9 | - [Java](#java) 10 | - [Go](#go) 11 | - [Javascript](#javascript) 12 | - [Python](#python) 13 | - [같이 보기](#같이-보기) 14 | - [개념](#개념) 15 | - [TDD 리듬(Rhythm)](#tdd-리듬rhythm) 16 | - [관련 용어](#관련-용어) 17 | - [간접 입력 (Indirect Input)](#간접-입력-indirect-input) 18 | - [간접 출력 (Indirect Output)](#간접-출력-indirect-output) 19 | - [`SUT`](#sut) 20 | - [`DOC`](#doc) 21 | - [Test Fixture (Test Context)](#test-fixture-test-context) 22 | - [Test Suite](#test-suite) 23 | - [테스트 유형](#테스트-유형) 24 | - [Unit Test](#unit-test) 25 | - [Integration Test](#integration-test) 26 | - [Functional Test](#functional-test) 27 | - [End to End Test](#end-to-end-test) 28 | - [Acceptance Test](#acceptance-test) 29 | - [Customer Test](#customer-test) 30 | - [테스트 더블 test double](#테스트-더블-test-double) 31 | - [Dummy](#dummy) 32 | - [Fake](#fake) 33 | - [Stub](#stub) 34 | - [Spy](#spy) 35 | - [Mock](#mock) 36 | 37 | ## 참고 자료 38 | 39 | ### Book 40 | 41 | | 제목 | 저자 | 링크 | 42 | | ----------------------------------------------------------------------------------------------------- | -------------------------- | --------------------------------------------------------------------------------- | 43 | | [소프트웨어 장인](books/the-software-craftsman.md) | 산드로 만쿠소 | [9791186659489](https://www.gilbut.co.kr/book/view?bookcode=BN001288) | 44 | | 테스트 주도 개발 - [Money 예제](https://github.com/tdd-kata/java/blob/main/money-kent-beck/README.md) | 켄트 벡 | [9788966261024](https://www.aladin.co.kr/shop/wproduct.aspx?ISBN=9788966261024) | 45 | | xUnit 테스트 패턴 | 제라드 메스자로스 | [Website for Book](http://xunitpatterns.com/index.html) | 46 | | [리팩터링 2판](books/refactoring-2.md) | 마틴 파울러 | [9791162242742](https://www.hanbit.co.kr/store/books/look.php?p_code=B6952616555) | 47 | | 패턴을 활용한 리팩터링 | 조슈아 케리에브스키 | [9788991268920](https://www.aladin.co.kr/shop/wproduct.aspx?ISBN=9788991268920) | 48 | | 코드 컴플리트 2 | 스티브 맥코넬 | [9791158390600](https://wikibook.co.kr/code-complete-2/) | 49 | | 테스트 주도 개발로 배우는 객체 지향 설계와 실천 | 스티브 프리먼, 냇 프라이스 | [9788966260843](http://ebook.insightbook.co.kr/book/19) | 50 | | 클린 코드 | 로버트 C. 마틴 | [9788966262724](http://ebook.insightbook.co.kr/book/79) | 51 | | 클린 코더 | 로버트 C. 마틴 | [9788960778818](http://www.acornpub.co.kr/book/clean-coder) | 52 | | 클린 소프트웨어 | 로버트 C. 마틴 | [9791185890852](https://jpub.tistory.com/682) | 53 | 54 | ### Article 55 | 56 | - [Mocks, Fakes, Stubs and Dummies](http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html) - xUnit Patterns 57 | - [The different types of software testing](https://www.atlassian.com/continuous-delivery/software-testing/types-of-software-testing) - Atlassian CI/CD 58 | - [Test 관련 용어 정리](https://johngrib.github.io/wiki/test-terms/) - 이종립 (기계인간 John Grib) 59 | - [정말로 테스트 대역이 필요한가](https://gyuwon.github.io/blog/2020/05/10/do-you-really-need-test-doubles.html) - 이규원 60 | - [TestDouble](https://www.martinfowler.com/bliki/TestDouble.html) - Martin Fowler 61 | - [Mocks Aren't Stubs](https://www.martinfowler.com/articles/mocksArentStubs.html) - Martin Fowler ([번역](https://sites.google.com/a/jabberstory.net/testing/mocksArentStubs)) 62 | 63 | ### Video 64 | 65 | | 제목 | 저자 | 링크 | 66 | | ------------------------------------------ | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | 67 | | TDD 리팩토링 | 자바지기 박재성 | [Youtube](https://youtu.be/bIeqAlmNRrA) | 68 | | 현실 세상의 TDD | 이규원 | [fastcampus](https://www.fastcampus.co.kr/dev_red_ygw), [GitHub](https://github.com/gyuwon/TDDHandsOn) | 69 | | 자바와 JUnit을 활용한 실용주의 단위 테스트 | 제프 랭어, 앤디 헌트, 데이브 토마스 | [9791160508383](https://www.aladin.co.kr/shop/wproduct.aspx?ISBN=9791160508383) | 70 | | JUnit in Action (3rd) | 피터 타치브, 펠리페 레미, 빈센트 마솔, 게리 그레고리 | [9781617297045](https://www.manning.com/books/junit-in-action-third-edition) | 71 | 72 | ### Language 73 | 74 | #### Java 75 | 76 | | 제목 | 저자 | 링크 | 77 | | ---------------------------------------- | ------------------------------- | ----------------------------------------------------------------------------------- | 78 | | 테스트 주도 개발 시작하기 | 최범균 | [9788980783052](https://www.aladin.co.kr/shop/wproduct.aspx?ISBN=9788980783052) | 79 | | Test Driven Development with Spring Boot | Sannidhi Jalukar, Madhura Bhave | [Youtube](https://youtu.be/s9vt6UJiHg4) | 80 | | Java TDD 실습 | 아샬 | [Youtube](https://www.youtube.com/playlist?list=PLbdtsbZUwdeRirBYnWrMSvKYS4CcmXCeU) | 81 | 82 | #### Go 83 | 84 | | 제목 | 저자 | 링크 | 85 | | ------------------- | ----------- | ----------------------------------------------------------------- | 86 | | Learn Go with Tests | Chris James | [Git Book](https://github.com/MiryangJung/learn-go-with-tests-ko) | 87 | 88 | #### Javascript 89 | 90 | | 제목 | 저자 | 링크 | 91 | | ------------------------------------------------- | ------ | --------------------------------------- | 92 | | 프론트엔드에서 TDD가 가능하다는 것을 보여드립니다 | 최수형 | [Youtube](https://youtu.be/L1dtkLeIz-M) | 93 | 94 | #### Python 95 | 96 | | 제목 | 저자 | 링크 | 97 | | ----------------------------------- | ---------------- | ------------------------------------------------------------------------------- | 98 | | 우아하게 준비하는 테스트와 리팩토링 | 한성민 | [Youtube](https://youtu.be/S5SY2pkmOy0) | 99 | | 클린 코드를 위한 테스트 주도 개발 | 해리 J.W. 퍼시벌 | [9788994774916](https://www.aladin.co.kr/shop/wproduct.aspx?ISBN=9788994774916) | 100 | 101 | ### 같이 보기 102 | 103 | | 제목 | 저자 | 링크 | 104 | | ------------------------------ | ------------------------------ | ------------------------------------------------------------------------------------------------------------------- | 105 | | 함께 자라기 | 김창준 | [9788966262373](http://ebook.insightbook.co.kr/book/65) | 106 | | 실용주의 프로그래머 | 데이비드 토머스, 앤드류 헌트 | [9788966261031](https://www.aladin.co.kr/shop/wproduct.aspx?ISBN=9788966261031) | 107 | | 실용주의 사고와 학습 | 앤디 헌트 | [9788992939362](https://wikibook.co.kr/pragmatic-thinking-and-learning/) | 108 | | 프로그래머의 길, 멘토에게 묻다 | 데이브 후버, 애디웨일 오시나이 | [8991268803](https://www.aladin.co.kr/shop/wproduct.aspx?ISBN=8991268803) | 109 | | 클린 아키텍처 | 로버트 C. 마틴 | [9788966262472](https://blog.insightbook.co.kr/2019/08/08/%ED%81%B4%EB%A6%B0-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98/) | 110 | | Clean Architecture and Design | 로버트 C. 마틴 | [amara (한글 자막)](https://amara.org/ko/videos/0AtjY87egE3m/ko/796487/) | 111 | | 객체 지향의 사실과 오해 | 조영호 | [9788998139766](https://wikibook.co.kr/object-orientation/) | 112 | | 오브젝트 | 조영호 | [9791158391409](https://wikibook.co.kr/object/) | 113 | 114 | ## 개념 115 | 116 | > "TDD의 이름 자체에 '테스트'가 들어 있기는 하지만 사실 **TDD는 설계에 대한 실행 관례다.**" - <소프트웨어 장인> 117 | 118 | ![tdd-global-lifecycle](image/tdd-global-lifecycle.png) 119 | 120 | _출처: [위키피디아](https://en.wikipedia.org/wiki/Test-driven_development)_ 121 | 122 | ### TDD 리듬(Rhythm) 123 | 124 | <테스트 주도 개발>, 켄트 벡 125 | 126 | 1. 재빨리 **작은** 테스트를 하나 추가합니다. 127 | 2. 🔴 모든 테스트를 실행하고, 실패하는 것을 확인합니다. 128 | 3. 코드에 변화를 줍니다. 129 | 4. 🟢 모든 테스트를 실행하고, 성공하는 것을 확인합니다. 130 | - 가짜로 구현하기: 상수로 반환하게 만들고 진짜 코드를 얻을 때까지 단계적으로 상수를 변수로 바꾸어 갑니다. 131 | - 명백한 구현 사용하기: 실제 구현을 입력합니다. 132 | - 삼각측량(triangulation): 두 개 이상의 예제를 통해 코드를 일반화합니다. 어떻게 리팩토링해야 하는지 전혀 감이 안 올 때만 삼각측량을 사용합니다. 133 | 5. 🔵 중복을 제거하기 위해 리팩토링합니다. 134 | 135 | ## 관련 용어 136 | 137 | ### 간접 입력 (Indirect Input) 138 | 139 | 입력된 의존성 인터페이스를 통한 입력을 말합니다(의존성 관점에서는 출력). 140 | SUT의 동작이 SUT에서 사용하는 다른 서비스 컴포넌트에서 리턴하는 값에 영향을 받을 때 141 | 이런 값들을 SUT의 간접 입력이라 합니다. 142 | 143 | ### 간접 출력 (Indirect Output) 144 | 145 | 입력된 의존성 인터페이스를 통한 출력을 말합니다(의존성 관점에서는 입력). 146 | SUT의 동작에 따른 효과를 public 애플리케이션 인터페이스(API)에서는 볼 수 없고 147 | 다른 시스템이나 애플리케이션 컴포넌트에서만 볼 수 있을 때 이런 효과를 SUT의 간접 출력이라 합니다. 148 | 149 | ### `SUT` 150 | 151 | [System Under Test](http://xunitpatterns.com/SUT.html). 152 | "테스트하려는 대상"을 의미합니다. 153 | SUT는 항상 테스트를 기준으로 정의됩니다. 154 | 단위 테스트를 작성할 때 SUT는 테스트하려는 클래스(CUT), 오브젝트(OUT) 또는 메서드(MUT)가 됩니다. 155 | [고객 테스트](https://explainagile.com/agile/xp-extreme-programming/practices/customer-tests/)를 작성할 때 156 | SUT는 아마도 애플리케이션 전체(AUT)이거나 적어도 주요 서브 시스템일 것입니다. 157 | 애플리케이션에서 특정 테스트의 검증 대상이 아닌 부분도 여전히 158 | 의존 컴포넌트(`DOC`)로서 테스트와 연관돼 있을 수 있습니다. 159 | 160 | ### `DOC` 161 | 162 | [depended-on component](http://xunitpatterns.com/DOC.html). 163 | SUT가 의존하는 개별 클래스나 느슨한 컴포넌트(large-grained component)를 말합니다. 164 | 의존은 보통 메소드 호출을 통해 위임하는 방식 중 하나입니다. 165 | 테스트 자동화에서 완벽한 테스트 커버리지를 얻으려면 주로 DOC와 SUT 간의 상호작용을 보고 제어할 수 있어야 합니다. 166 | 167 | ### Test Fixture (Test Context) 168 | 169 | 테스트 픽처란 SUT의 동작을 검증하기 위해 테스트를 실행하려 할 때 갖춰야 하는 모든 것을 말합니다. 170 | 171 | ### Test Suite 172 | 173 | 테스트 스위트란 같이 실행하고 싶은 테스트들의 모음(composite)에 이름을 붙여주는 방법을 말합니다. 174 | 175 | ### [테스트 유형](https://www.atlassian.com/continuous-delivery/software-testing/types-of-software-testing) 176 | 177 | | - | Unit Test | Acceptance Test | 178 | | ------------------------------------- | -------------------------- | -------------------------------------- | 179 | | 관점 | 최종 클라이언트 | 프로그래머 | 180 | | 검증 대상 | 시스템의 일부(하위 시스템) | 배치된 시스템 | 181 | | 안정감 (전체 시스템 이상 여부 신뢰도) | 상대적으로 낮음 | 높음 | 182 | | 비용 (작성/관리/실행) | 낮음 | 높음 | 183 | | 피드백 품질 | 높음 | 낮음 (현상은 드러나지만 원인은 숨겨짐) | 184 | 185 | _출처: 현실 세상의 TDD - 이규원_ 186 | 187 | #### Unit Test 188 | 189 | 단위 테스트는 애플리케이션 내부의 한 부분이 의도한 대로 동작하는지 검증합니다. 190 | 191 | #### Integration Test 192 | 193 | 통합 테스트는 애플리케이션에서 사용하는 여러 모듈 또는 서비스가 함께 잘 작동하는지 확인합니다. 194 | 여기서 모듈은 모든 모듈이 아닌 해당 테스트가 의존하는 모듈만을 일컫습니다. 195 | 통합 테스트는 단순히 데이터베이스를 쿼리 할 수 ​​있는지 확인합니다. 196 | 197 | #### Functional Test 198 | 199 | 기능 테스트는 애플리케이션 최종 사용자의 기능에 대한 블랙박스 테스트를 말합니다. 200 | 201 | #### End to End Test 202 | 203 | 통합 테스트가 몇 가지 애플리케이션 간 동작을 테스트한다면 204 | E2E 테스트는 소프트웨어가 사용자의 단계별 행동을 그대로 시뮬레이션하고 테스트합니다. 205 | 206 | #### Acceptance Test 207 | 208 | 인수 테스트(승인 테스트)는 시스템이 비즈니스 요구 사항을 충족하는지 확인하기 위해 수행되는 테스트입니다. 209 | 애플리케이션이 프로그래머가 생각한 대로가 아닌 고객이 의도한 대로 동작하는 것을 증명하는 것이 목적입니다. 210 | 211 | #### Customer Test 212 | 213 | 고객 테스트는 전체 시스템 중에서 눈에 보이는 기능의 일부분에 대한 동작을 검증하는 테스트입니다. 214 | 215 | ### [테스트 더블](http://xunitpatterns.com/Test%20Double.html) test double 216 | 217 | - 테스트 코드를 작성할 때 실제 DOC를 사용할 수 없다면, DOC 대신 테스트 더블로 대체할 수 있습니다. 218 | - 테스트 더블은 실제 DOC와 똑같이 행동하지 않아도 되며, 똑같은 API만 제공하면 됩니다. 219 | - 테스트 더블은 테스트 목적을 위해 프로덕션 객체를 다른 무언가로 교체하는 모든 경우를 표현하는 용어입니다. 220 | 221 | #### Dummy 222 | 223 | SUT 메서드 인자에 구현이 전혀 안 돼 있는 객체를 전달합니다. 224 | SUT 준비를 위해 해결되어야 하는 의존성이 테스트 대상 논리에 의해 사용되지 않는 경우에 의존 요소를 대신하는 테스트 대역입니다. 225 | 226 | #### Fake 227 | 228 | 실제로 작동하는 구현이지만 일반적으로 프로덕션에는 적합하지 않은 꼼수(shortcut)를 사용합니다. 229 | ([InMemoryTestDatabase](https://www.martinfowler.com/bliki/InMemoryTestDatabase.html)가 좋은 예) 230 | 실행할 수 없는 테스트를 빠르게 실행하기 위해 사용됩니다. 231 | 232 | #### Stub 233 | 234 | 테스트 중에 호출되면 미리 준비된 결과를 제공합니다. 235 | 즉, 실제 객체를 테스트용 객체로 교체해 SUT에 원하는 **간접 입력**을 보냅니다. 236 | 237 | #### Spy 238 | 239 | SUT로부터 다른 컴포넌트로의 **간접 출력**을 갈무리했다가 뒤에 테스트에서 검증합니다. 240 | 241 | #### Mock 242 | 243 | 호출했을 때 사전에 정의된 명세대로의 결과를 돌려주도록 미리 프로그램 되어 있습니다. 244 | 예상치 못한 호출이 있을 경우 예외를 던질 수 있으며, 모든 호출이 예상된 것이었는지 확인할 수 있습니다. 245 | SUT 내부의 행위를 검증합니다. 246 | SUT의 **간접 출력**을 검증하기 위해 사용됩니다. 247 | -------------------------------------------------------------------------------- /image/agile/scrum-nexus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpdojo/docs/da871cd8fc4e59736a5f5ab5a44908534505b29f/image/agile/scrum-nexus.png -------------------------------------------------------------------------------- /image/agile/scrum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpdojo/docs/da871cd8fc4e59736a5f5ab5a44908534505b29f/image/agile/scrum.png -------------------------------------------------------------------------------- /image/ci-cd/aws-ci-cd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpdojo/docs/da871cd8fc4e59736a5f5ab5a44908534505b29f/image/ci-cd/aws-ci-cd.png -------------------------------------------------------------------------------- /image/ci-cd/continuous-delivery-deployment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpdojo/docs/da871cd8fc4e59736a5f5ab5a44908534505b29f/image/ci-cd/continuous-delivery-deployment.png -------------------------------------------------------------------------------- /image/ci-cd/redhat-ci-cd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpdojo/docs/da871cd8fc4e59736a5f5ab5a44908534505b29f/image/ci-cd/redhat-ci-cd.png -------------------------------------------------------------------------------- /image/tdd-global-lifecycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpdojo/docs/da871cd8fc4e59736a5f5ab5a44908534505b29f/image/tdd-global-lifecycle.png -------------------------------------------------------------------------------- /image/xp-circles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xpdojo/docs/da871cd8fc4e59736a5f5ab5a44908534505b29f/image/xp-circles.jpg -------------------------------------------------------------------------------- /reference/agile/ci-cd.md: -------------------------------------------------------------------------------- 1 | # CI/CD 2 | 3 | - [CI/CD](#cicd) 4 | - [참고 자료](#참고-자료) 5 | - [지속적 통합(CI, Continuous Integration)](#지속적-통합ci-continuous-integration) 6 | - [지속적 제공(CD, Continuous Delivery)](#지속적-제공cd-continuous-delivery) 7 | - [지속적 배포(CD, Continuous deployment)](#지속적-배포cd-continuous-deployment) 8 | 9 | ## 참고 자료 10 | 11 | - [지속적인 통합](continuous-integration.md) - 폴 M. 듀발, 스티븐 M. 마티야스, 앤드류 글로버 12 | - [하루에 1000번 배포하는 조직 되기](https://blog.banksalad.com/tech/become-an-organization-that-deploys-1000-times-a-day/) - 뱅크샐러드 13 | - [CI/CD 5분 개념 정리 (현업에서 쓰는 개발 프로세스)](https://www.youtube.com/watch?v=0Emq5FypiMM) - 드림코딩 14 | - [Continuous integration](https://en.wikipedia.org/wiki/Continuous_integration) - Wikipedia 15 | - [Continuous Integration](https://martinfowler.com/articles/continuousIntegration.html) - Martin Fowler 16 | - [Continuous Integration](https://continuousdelivery.com/foundations/continuous-integration/) - Jez Humble 17 | - [What is CI/CD?](https://www.redhat.com/en/topics/devops/what-is-ci-cd) - Red Hat 18 | - [It’s not CI, it’s just CI theatre](https://www.gocd.org/2017/05/16/its-not-CI-its-CI-theatre/) - gocd (안티 패턴: CI 극장) 19 | - [CI/CD Best Practices](https://www.jetbrains.com/teamcity/ci-cd-guide/ci-cd-best-practices/) - JetBrains 20 | - [How to get started with Continuous Integration](https://www.atlassian.com/continuous-delivery/continuous-integration/how-to-get-to-continuous-integration) - Atlassian 21 | - [Daily Build and Smoke Test](https://stevemcconnell.com/articles/daily-build-and-smoke-test/) - IEEE Software, Vol. 13, No. 4, July 1996, Steve McConnell 22 | - [CI Team responsibilities](https://www.thoughtworks.com/continuous-integration) - Thoughtworks 23 | - [CI (Continuous Integration)이란?](https://www.nextree.co.kr/p10799/) - 넥스트리소프트 24 | 25 | ![redhat-ci-cd](../../image/ci-cd/redhat-ci-cd.png) 26 | 27 | *[What is CI/CD?](https://www.redhat.com/en/topics/devops/what-is-ci-cd), Red Hat* 28 | 29 | ![aws-ci](../../image/ci-cd/aws-ci-cd.png) 30 | 31 | *[What is Continuous Integration?](https://aws.amazon.com/devops/continuous-integration/), AWS* 32 | 33 | ## 지속적 통합(CI, Continuous Integration) 34 | 35 | > 이규원님 [피드 1](https://www.facebook.com/gyuwon.yi/posts/4292538720789318) 36 | > 37 | > 최근 며칠 다음의 것들에 대한 의문을 접했다. 38 | > 39 | > - 200줄 이하의 운영 코드가 추가되는 PR 40 | > - 3개 이하의, 되도록 1개의, 커밋을 담는 PR 41 | > - 숨쉬듯한 Git 리베이스 42 | > 43 | > 이것들이 현실성 없게 느껴지는 이유는 CI 극장(CI theatre)이다. 44 | > 45 | > CI 극장이 아니라 CI를 하고 있다면 어색하지 않고 어쩌면 당연하게 느껴질 것들이다. 46 | > 47 | > CI를 하려면 팀의 모든 코더가 최소 매일 메인 브랜치에 커밋 해야 한다. 48 | > 그리그 그 커밋들은 빌드와 모든 테스트를 통과해야 한다. 49 | > 이것이 실현되려면 PR은 리뷰 하기 쉽게 작아야 하며 완료된 로컬 히스토리는 푸시되기 전에 원자적이고 무결한 형태로 가공되어야 한다. 50 | > 51 | > Git 공식 문서에 다음 내용이 있다. 52 | > 53 | > Don’t push your work until you’re happy with it. 54 | > 55 | > One of the cardinal rules of Git is that, since so much work is local within your clone, you have a great deal of freedom to rewrite your history locally. 56 | > However, once you push your work, it is a different story entirely, and you should consider pushed work as final unless > you have good reason to change it. 57 | > In short, you should avoid pushing your work until you’re happy with it and ready to share it with the rest of the world. 58 | > 59 | > CI가 운영되는 팀의 안정감과 쾌적함은 경험자만이 알 수 있다. 60 | 61 | > 이규원님 [피드 2](https://www.facebook.com/photo?fbid=4294786600564530) 62 | > 63 | > ### 공통 정책 64 | > 65 | > - Pull request 완료는 리베이스 병합만 허용한다. 66 | > - 자동 완료를 허용한다. 자동 완료가 활성화된 pull request는 완료에 필요한 모든 조건이 충족되면 자동으로 완료된다. 67 | > - Pull request가 완료되면 브랜치를 자동으로 삭제한다. 68 | > - Pull request 대화는 대화를 시작한 사람이 완료 책임을 갖는다. 69 | > 예를 들어 코드 수정 요청 댓글을 달았다면 댓글 작성자가 코드가 잘 수정되었는지 확인한 후 대화를 완료시켜야 한다. 70 | > 코드를 수정한 사람이 대화를 완료시키면 안된다. 71 | > - 하나의 pull request는 200줄 이하의 운영 코드 추가가 권장된다. 72 | > 운영 코드 추가가 200줄을 초과할 때는 분명한 이유가 있어야 한다. 73 | > - 추가된 운영 코드가 100줄이 넘어가면 코드를 리뷰하기 어려워지기 시작한다. 74 | > 코드 리뷰가 어려우면 리뷰 품질이 낮아진다. 75 | > 이 수치에 100줄의 여유를 반영해 200줄 이하의 기준을 정한다. 76 | > - 하나의 pull request는 하나의 커밋을 포함하는 것이 가장 권장되며 3개 이하의 커밋이 권장된다. 77 | > 커밋이 3개를 초과할 때는 분명한 이유가 있어야 한다. 78 | > Pull request의 커밋 관리는 `commit --amend`와 `rebase`를 적극 활용하자. 79 | > - Pull request에 복수의 커밋이 포함된다는 것은 커밋이 무결하지 않거나 또는 하나의 pull request가 둘 이상의 주제를 다룬다는 신호다. 80 | > 두 경우 모두 코드 리뷰를 어렵게 만든다. 81 | > 82 | > ### `main` 브랜치 정책 83 | > 84 | > - 그 누구도 커밋 권한을 갖지 않는 것이 원칙이다. 85 | > - Pull request를 통해서만 커밋을 추가할 수 있다. 86 | > - 심각한 장애 등 긴급한 상황에서만 일시적으로 커밋 권한을 관련된 인원에게 부여한다. 87 | > - 1명 이상의 승인을 받아야 pull request를 완료할 수 있다. 88 | > - ⚠ Pull request 승인자는 코드 작성자 만큼의 책임을 가진다. 89 | > 편의를 위해 동료의 pull request를 승인하지 말자. 90 | > - Pull request에 새 커밋이 추가되면 기존 승인은 취소된다. 91 | > - 모든 대화가 해결되어야 pull request를 완료할 수 있다. 92 | > 93 | > ### [`rebase`는 Git의 꽃이다](https://www.facebook.com/photo?fbid=4291246567585200) 94 | > 95 | > 우선 모든 팀원의 main 브랜치 커밋 권한을 제거하고 PR을 통해서만 커밋할 수 있게 합니다. 96 | > PR 병합은 리베이스만 가능하게 합니다. 97 | > 그럼 작업 브랜치는 `force push`를 하던 말던 개인의 자유입니다. 98 | 99 | > [It’s not CI, it’s just CI theatre](https://www.gocd.org/2017/05/16/its-not-CI-its-CI-theatre/), gocd (안티 패턴: CI 극장) 100 | > 101 | > - "[CI 극장](https://www.thoughtworks.com/radar/techniques/ci-theatre)"은 실제로 지속적 통합(CI)을 실천하지 않으면서 실천하고 있다는 환상을 말합니다. CI 극장의 모습은 다음과 같습니다. 102 | > - CI를 실천하고 있냐는 질문에 "우리는 CI 서버가 있습니다", "x 도구를 사용합니다"라고 대답합니다. 103 | > - 하나의 브랜치를 오래 사용하고, 트렁크 브랜치(main, master)를 정기적으로 체크인하지 않습니다. 104 | > - 브랜치를 병합할 때 불안과 피로를 느낍니다. 105 | > - 테스트 커버리지가 낮은 빌드를 실행하고, 오랫동안 빌드 상태가 빨간색이도록 방치합니다. 106 | > - CI 극장이 되지 않으려면 107 | > - 더 자주 커밋 (최소한 매일) 108 | > - 트렁크 기반 개발 109 | > - 자동화 110 | 111 | > [Continuous Integration](https://martinfowler.com/articles/continuousIntegration.html), Martin Fowler 112 | > 113 | > 일반적으로 모든 개발자가 **적어도 매일** 통합하여 **하루에 여러 번 통합합니다**. 114 | > 각 통합은 가능한 한 빨리 통합 오류를 감지하기 위해 **자동화된 빌드(테스트 포함)에 의해 검증**됩니다. 115 | > 많은 팀은 이 접근 방식이 통합 문제를 크게 줄이고 팀이 응집력 있는 소프트웨어를 보다 신속하게 개발할 수 있게 해준다는 것을 알게 되었습니다. 116 | 117 | > [Continuous Integration](https://continuousdelivery.com/foundations/continuous-integration/), Jez Humble 118 | > 119 | > CI 개발자는 정기적으로(**최소한 매일**) **모든 작업을 트렁크(메인라인 또는 마스터라고도 함)에 통합**합니다. 120 | 121 | > [What is CI/CD?](https://www.redhat.com/en/topics/devops/what-is-ci-cd), Red Hat 122 | > 123 | > CI를 성공적으로 구현할 경우 새로운 코드 변경 사항이 124 | > 정기적으로 빌드 및 테스트되어 공유 리포지토리에 통합되므로 125 | > 여러 명의 개발자가 동시에 코드 작업을 할 경우 126 | > 서로 충돌할 수 있는 문제를 해결할 수 있습니다. 127 | > 128 | > 그러나 조직에서 특정한 날([merge day](https://thedailywtf.com/articles/Happy_Merge_Day!))을 정해 모든 분기 소스 코드를 병합하는 경우, 129 | > 결과적으로 반복적인 수작업(resolve conflicts 등)에 많은 시간을 소모하게 됩니다. 130 | 131 | > [CI Team responsibilities](https://www.thoughtworks.com/continuous-integration), Thoughtworks 132 | > 133 | > - Check in frequently (자주 기록하세요) 134 | > - Don’t check in broken code (망가진 코드를 기록하지 마세요) 135 | > - Don’t check in untested code (테스트되지 않은 코드를 기록하지 마세요) 136 | > - Don’t check in when the build is broken (실패한 빌드를 기록하지 마세요) 137 | > - Don’t go home after checking in until the system builds (기록한 후 빌드가 완료될 때까지 집에 가지 마세요) 138 | 139 | > [CI (Continuous Integration)이란?](https://www.nextree.co.kr/p10799/), 넥스트리소프트 140 | > 141 | > 코드 컴플리트(Code Complete)라는 책을 쓴 Steve McConnell은 142 | > 1996년 'Daily Build and Smoke Test'라는 글에서 Microsoft사에서 일일 빌드 체계를 통해서 통합에 대한 위험을 격감시키고, 143 | > Smoke Testing을 통해서 품질을 확보하고 있다는 내용을 언급하고 있습니다. 144 | > 특히, 일일 빌드는 프로젝트에서 심장 박동(heartbeat)에 비유한 Jim MacCarthy의 말을 인용하여 일일 빌드(daily build)를 하지 않는다면, 145 | > 그 프로젝트는 죽은 것과 같다고 표현하고 있습니다. 1990년대 후반부터는 XP(Extreme Programming)에서 CI를 기법으로 146 | > [채용](http://www.extremeprogramming.org/rules/integrateoften.html)했으며), Martin Fowler의 147 | > [Continuous Integration](https://www.martinfowler.com/articles/originalContinuousIntegration.html)이라는 글에서 본격적인 CI 기법에 대한 기본 원칙이 만들어지기 시작헀습니다. 148 | > 149 | > 이 글에서 Fowler는 자동화된 일일 빌드에 대한 기본 원칙을 다음과 같이 4가지로 설명합니다. 150 | > 151 | > - 모든 소스 코드가 살아있고(현재 실행되고) 어느 누구든 현재의 소스를 접근할 수 있는 단일 지점을 유지할 것 152 | > - 빌드 프로세스를 자동화시켜서 어느 누구든 소스로부터 시스템을 빌드하는 단일 명령어를 사용할 수 있게 할 것 153 | > - 테스팅을 자동화시켜서 단일 명령어를 통해서 언제든지 시스템에 대한 건전한 테스트 수트를 실핼할 수 있게 할 것 154 | > - 누구나 현재 실행 파일을 얻으면 지금까지 최고의 실행파일을 얻었다는 확신을 하게 만들 것 155 | 156 | ## 지속적 제공(CD, Continuous Delivery) 157 | 158 | ![continuous-delivery-deployment](../../image/ci-cd/continuous-delivery-deployment.png) 159 | 160 | *[What's the difference between Continuous Delivery and Continuous Deployment?](https://www.gocd.org/2017/10/17/difference-between-continuous-delivery-continuous-deployment-infographic.html), gocd* 161 | 162 | > [What is CI/CD?](https://www.redhat.com/en/topics/devops/what-is-ci-cd), Red Hat 163 | > 164 | > 운영 서버 배포 전 개발팀이나 QA팀에서 한번 더 확인한 후 수동으로 배포하는 방식입니다. 165 | > 166 | > 변경 사항이 버그 테스트를 거쳐 리포지토리(예: GitHub 또는 컨테이너 레지스트리)에 자동으로 업로드되는 것을 뜻하며, 운영팀은 이 리포지토리에서 애플리케이션을 실시간 프로덕션 환경으로 배포할 수 있습니다. 167 | 168 | > [What is Continuous Delivery?](https://continuousdelivery.com/) 169 | > 170 | > - 저위험 릴리스 171 | > - 시장 출시 시간 단축 172 | > - 더 높은 품질 173 | > - 비용 절감 174 | > - 더 나은 제품 175 | > - 더 행복한 팀 176 | 177 | ## 지속적 배포(CD, Continuous deployment) 178 | 179 | > [What is CI/CD?](https://www.redhat.com/en/topics/devops/what-is-ci-cd), Red Hat 180 | > 181 | > 변경 사항을 리포지토리에서 고객이 사용 가능한 프로덕션 환경까지 자동으로 릴리스하는 것을 의미합니다. 182 | > 이는 애플리케이션 제공 속도를 저해하는 수동 프로세스로 인한 운영팀의 프로세스 과부하 문제를 해결합니다. 183 | -------------------------------------------------------------------------------- /reference/agile/continuous-integration.md: -------------------------------------------------------------------------------- 1 | # 지속적인 통합 2 | 3 | > [졸트상 수상]\ 4 | 폴 M. 듀발, 스티븐 M. 마티야스, 앤드류 글로버 5 | 6 | - [지속적인 통합](#지속적인-통합) 7 | - [CI의 특징 (p12)](#ci의-특징-p12) 8 | - [질문](#질문) 9 | - [CI의 가치 (p29)](#ci의-가치-p29) 10 | - [CI를 도입하지 못하는 이유 (p32)](#ci를-도입하지-못하는-이유-p32) 11 | - [효과적인 CI 실천 방법 (p39)](#효과적인-ci-실천-방법-p39) 12 | - [질문](#질문-1) 13 | - [위험 요소 (p62)](#위험-요소-p62) 14 | - [질문](#질문-2) 15 | - [완전한 기능을 갖춘 CI 시스템 만들기](#완전한-기능을-갖춘-ci-시스템-만들기) 16 | - [지속적인 빌드 (변경될 때마다 소프트웨어 빌드하기)](#지속적인-빌드-변경될-때마다-소프트웨어-빌드하기) 17 | - [실천 방법](#실천-방법) 18 | - [질문](#질문-3) 19 | - [지속적인 데이터베이스 통합](#지속적인-데이터베이스-통합) 20 | - [실천 방법](#실천-방법-1) 21 | - [질문](#질문-4) 22 | - [지속적인 테스트 (Testing)](#지속적인-테스트-testing) 23 | - [실천 방법](#실천-방법-2) 24 | - [질문](#질문-5) 25 | - [지속적인 검사 (Inspection)](#지속적인-검사-inspection) 26 | - [실천 방법](#실천-방법-3) 27 | - [질문](#질문-6) 28 | - [지속적인 배포](#지속적인-배포) 29 | - [실천 방법](#실천-방법-4) 30 | - [질문](#질문-7) 31 | - [지속적인 피드백](#지속적인-피드백) 32 | - [질문](#질문-8) 33 | 34 | 지속적인 통합(CI, Continuous Integration)은 팀 구성원들이 자신이 한 일을 자주 통합하는 소프트웨어 개발 실천 방법인데, 보통 각자 하루에 적어도 한 번 꼴로 통합합니다. 각 통합은 테스트를 포함한 자동화된 빌드가 검증하여 최대한 빨리 통합 오류를 탐지해냅니다. 이런 접근 방법을 사용하면 통합 문제를 상당히 줄일 수 있고 응집력 있는 소프트웨어를 개발할 수 있다는 사실을 많은 팀이 알게 됐습니다. 35 | 36 | 프로젝트의 버전 관리 시스템(Version Control System, VCS)에 변경 사항이 커밋될 때마다 자동화된 빌드를 돌리면, 팀이 다음과 같은 질문에 대답할 수 있게 됩니다. 37 | 38 | - [ ] 모든 소프트웨어 컴포넌트가 함께 작동합니까? 39 | - [ ] 코드 복잡도는 얼마나 됩니까? 40 | - [ ] 팀이 정해진 코딩 표준을 잘 지킵니까? 41 | - [ ] 자동화된 테스트가 적용되는 코드가 얼마나 됩니까? 42 | - [ ] 가장 최근의 변경 사항을 반영한 후에 모든 테스트가 성공했습니까? 43 | - [ ] 애플리케이션이 성능 요구사항을 여전히 충족시킵니까? 44 | - [ ] 마지막 배포에 아무런 문제가 없었습니까? 45 | 46 | 위와 같은 질문들에 대답하지 못하고 도구를 설치해서 VCS에 변경 사항이 있는지 폴링하고 컴파일하는 정도만 수행하고 있다면 지속적인 통합이 아닌 **지속적인 컴파일**이다.(p35) 47 | 48 | ## CI의 특징 (p12) 49 | 50 | - 소스 코드 컴파일 51 | - 데이터베이스 통합 52 | - 테스트 (Testing) 53 | - 검사 (Inspection) 54 | - 배포 55 | - 문서화와 피드백 56 | 57 | ### 질문 58 | 59 | - [ ] 버전 관리 저장소(소프트웨어 형상 관리 도구)를 사용합니까? 60 | - [ ] 빌드 과정이 자동화되고 똑같이 반복될 수 있습니까? 사람이 개입하지 않아도 빌드 과정이 완전히 작동합니까? 61 | - [ ] 자동화된 테스트를 작성해서 돌립니까? 62 | - [ ] 빌드 과정의 일부로써 테스트를 실행합니까? 63 | - [ ] 코딩 및 설계 표준을 어떻게 강제합니까? 64 | - [ ] 자동화시킨 피드백 메커니즘에는 어떤 게 있습니까? 65 | - [ ] 소프트웨어를 빌드할 때 별도의 통합 빌드 머신을 사용합니까? 66 | 67 | ## CI의 가치 (p29) 68 | 69 | - 위험을 줄여준다. 70 | - 반복적인 수작업을 줄여준다. 71 | - 언제 어느 때라도 배포할 수 있는 소프트웨어를 생성해낸다. 72 | - 프로젝트 가시성을 보다 좋게 해준다. 73 | - 개발 팀이 소프트웨어 제품에 대해 보다 큰 자신감을 갖게 해준다. 74 | 75 | ## CI를 도입하지 못하는 이유 (p32) 76 | 77 | - CI 시스템을 유지보수하기 위한 추가적인 과부하 78 | - 변경할 게 많음 79 | - 빌드 실패 횟수가 너무 많음 80 | - 추가적인 하드웨어 및 소프트웨어 비용 81 | - 개발자들이 이런 활동을 수행해야 함 82 | 83 | ## 효과적인 CI 실천 방법 (p39) 84 | 85 | - 코드를 자주 커밋하세요. 적어도 하루에 한 번은 버전 관리 저장소에 코드를 커밋하세요. 86 | - 깨진 코드를 커밋해선 안 됩니다. 다른 코드와 함께 컴파일되지 않거나 테스트를 깨먹는 코드를 커밋하지 마세요. 87 | - 빌드가 깨지면 즉시 고치세요. 팀의 책임일지라도, 최근에 코드를 커밋한 개발자가 깨진 빌드를 고치는 일에 관여해야 합니다. 88 | - 자동화된 개발자 테스트를 작성하세요. 소프트웨어가 작동하는지 자동화된 개발자 테스트를 사용해 검증하세요. 자동화된 빌드와 함께 개발자 테스트를 돌리고, 지속적인 통합을 이용해 개발자 테스트를 돌리세요. 89 | - 테스트와 검사는 모두 통과해야 합니다. 버전 관리 저장소에 코드르 커밋하기에 앞서 90%나 95%가 아닌 모든 테스트가 통과해야 합니다. 90 | - 개인 빌드를 돌리세요. 통합 빌드가 실패하지 않도록, 저장소에서 가장 최근의 변경 사항을 가져오고, 로컬에서 개인 시스템 빌드라 알려진 완전한 통합 빌드를 돌리세요. 91 | - 깨진 코드는 가져오지 마세요. 빌드가 실패했는데, 저장소에서 코드를 가져오면 시간을 낭비하게 될 겁니다. 코드가 바뀌길 기다리거나, 개발자가 빌드 실패를 고치는 일을 돕고 나서 최신 코드를 가져오세요. 92 | 93 | ### 질문 94 | 95 | - [ ] 평균적으로 팀의 모든 사람이 적어도 하루에 한 번은 코드를 커밋합니까? 코드를 자주 커밋하기 쉽게 해줄 기법을 쓰고 있습니까? 96 | - [ ] 하루에 하는 통합 빌드 중 몇 퍼센트가 성공합니까? (가장 최근에 돌린 빌드는 통과했습니까?) 97 | - [ ] 팀의 모든 사람이 저장소에 커밋하기 전에 개인 빌드를 돌려서 통합 오류를 줄이고 있습니까? 98 | - [ ] 테스트나 검사 중 하나라도 실패하면 빌드가 실패하도록 스크립트화했습니까? 99 | - [ ] 깨진 통합 빌드를 고치는 일을 우선적으로 하고 있습니까? 100 | - [ ] 빌드가 깨졌을 때 버전 관리 저장소에서 최신 코드를 가져오지 않습니까? 101 | - [ ] 자동화된 프로세스를 빌드와 지속적인 통합 시스템에 추가할 생각을 얼마나 자주 합니까? 지속적으로 하나요? 아니면 주기적으로라도 하나요? 102 | 103 | ## 위험 요소 (p62) 104 | 105 | - 배포 가능한 소프트웨어의 부재 106 | - 완화 방법: CI 시스템을 이용해 언제라도 배포 가능한 소프트웨어를 빌드하세요. 버전 관리 저장소에 소프트웨어 자산을 모두 올려놓고, 되풀이할 수 있는 빌드 프로세스를 구축하세요. 107 | - 뒤늦은 결함 발견 108 | - 완화 방법: 소프트웨어가 변경될 때마다 개발자 테스트를 포함해 빌드하세요. 그러면 소프트웨어 생명 주기상 이른 시기에 결함을 발견할 수 있습니다. 109 | - 프로젝트 가시성의 부재 110 | - 완화 방법: 빌드를 주기적으로 돌려서 소프트웨어의 건강 상태를 항상 파악하세요. 지속적인 통합을 효과적으로 적용하면 프로젝트의 상태를 궁금해하지 않아도 됩니다. 111 | - 저품질의 소프트웨어 112 | - 완화 방법: 소프트웨어가 변경될 때마다 테스트와 검사를 돌리세요. 소프트웨어의 복잡도, 중복, 설계, 코드 적용범위 등과 같은 요소를 알게 되어 코드 베이스에 발생할지 모르는 잠재적 결함을 발견해낼 수 있습니다. 113 | 114 | ### 질문 115 | 116 | - [ ] 프로젝트를 하면서 결함을 주로 발견하는 시기는 언제입니까? 생명 주기 초기입니까? 아니면 나중입니까? 117 | - [ ] 품질을 어떤 식으로 파악합니까? 품질을 측정할 수 있나요? 118 | - [ ] 어떤 과정을 사람이 직접 하나요? 자동화할 수 있거나 또는 자동화해야 하는 프로세스는 어느 것인지 파악해본 적이 있습니까? 119 | - [ ] 데이터베이스와 데이터를 다시 빌드할 때 필요한 스크립트를 모두 버전 관리 저장소에 넣어놨나요? 빌드하는 와중에 데이터베이스와 테스트 데이터를 다시 빌드할 수 있습니까? 120 | - [ ] 소프트웨어가 변경될 때마다 회귀 테스트를 수행할 수 있습니까? 기능, 통합, 부하 및 성능 테스트를 비롯한 다양한 유형의 회귀 테스트를 돌릴 수 있나요? 121 | - [ ] 어떤 소스 코드에 그에 상응하는 테스트가 없는지 파악할 역량이 있습니까? 테스트 적용범위 도구를 사용합니까? 122 | - [ ] 소프트웨어 중 몇 퍼센트가 중복 코드인지 압니까? 그 양을 줄여보려 노력합니까? 123 | - [ ] 어느 시점에서라도 그 때의 소스 코드가 소프트웨어 아키텍처에 부합하는지 여부를 검증할 수 있습니까? 124 | - [ ] 빌드 산출물이나 배포 산출물이 테스트할 준비가 됐다는 걸 어떻게 알립니까? 의사소통 메커니즘 중 어느 부분을 사람이 직접 맡고 있는지, 그리고 어느 부분을 자동화해야 하는지 알고 있습니까? 125 | - [ ] 소프트웨어의 지금 구조를 다이어그램으로 보일 수 있습니까? 프로젝트에 들어온 신참 개발자에게 소프트웨어의 아키텍처를 어떻게 전달합니까? 126 | 127 | # 완전한 기능을 갖춘 CI 시스템 만들기 128 | 129 | ## 지속적인 빌드 (변경될 때마다 소프트웨어 빌드하기) 130 | 131 | ### 실천 방법 132 | 133 | - 빌드를 자동화하세요. IDE와 분리된 빌드 스크립트를 만드세요. 그런 후에 저장소가 변경될 때마다 소프트웨어를 빌드하도록 CI 시스템이 빌드 스크립트를 돌리도록 합니다. 134 | - 명령어 하나로 빌드를 수행하세요. 필요한 도구를 모두 다운로드 받았다는 걸 전제로 하고, 명령어 하나를 치는 것만으로 빌드 스크립트를 실행시켜서, 최신 코드를 가져와서 빌드 전체를 돌릴 수 있어야 합니다. 135 | - IDE에서 빌드 스크립트를 분리해내세요. IDE가 없어도 자동화된 빌드를 돌릴 수 있어야 합니다. 136 | - 소프트웨어 자산을 중앙 집중화하세요. 의존성이 깨지는 횟수를 줄이려면, 모든 소프트웨어 자산을 중앙 집중화해야 합니다. 이렇게 하면 다른 컴퓨터로 옮길 때 빌드가 깨질 염려가 줄어듭니다. 137 | - 일관성 있는 디렉터리 구조를 만드세요. 일관성 있고 논리적인 디렉터리 구조를 만드세요. 그러면 소프트웨어를 빌드하기 쉬워집니다. 138 | - 빌드를 빨리 실패하게 만드세요. 피드백이 빨리 올수록, 문제를 빨리 고칠 수 있습니다. 가장 실패할 법한 것부터 빌드 활동을 실행시키세요. 139 | - 어떤 환경에서라도 빌드하세요. 필요하다면 개인 컴퓨터든, 통합 빌드 머신이든, 어떤 플랫폼 환경에서라도 자동화된 빌드를 똑같이 돌릴 수 있어야 합니다. 140 | - 전용 통합 빌드 머신을 사용하세요. 컴퓨터 하나를 전용으로 사용해 빌드를 돌리세요. 지난 빌드 때 나온 산출물로부터 자유로운 위치에서 통합을 하세요. 141 | - 지속적인 통합 서버를 사용하세요. 사람이 직접 통합 빌드를 돌리는 것에 더해, 또는 그 대안으로써 CI 서버를 사용하여, 자동으로 버전 관리 변경 내역을 폴링하고 별도의 컴퓨터에서 통합 빌드를 돌리세요. 142 | - 사람이 직접 통합 빌드를 실행하세요. 자동화된 빌드를 이용해 사람이 직접 순차적인 통합 빌드를 돌리는 접근 방법을 통해 통합 빌드의 오류를 줄이세요. 이러한 접근 방법을 CI 서버 대용으로 쓰는 사람도 있습니다. 143 | - 빌드 시간을 짧게 만드세요. 컴퓨터 자원을 늘리고, 느린 테스트를 덜어내고, 검사를 덜어내거나 줄이고 단계별 빌드를 돌림으로써 통합 빌드가 10분 이내에 끝나게 만들어보세요. 144 | - 빌드를 여러 단계로 나누세요. 컴파일하고 단위 테스트를 실행하며 배포하는 가벼운 '커밋' 빌드를 돌리고 난 후 에 컴포넌트, 시스템, 그리고 그보다 느린 테스트와 검사를 포함하는 무거운 '2차' 빌드를 돌리세요. 145 | 146 | ### 질문 147 | 148 | - [ ] 빌드를 자동화했습니까? IDE가 없어도 빌드를 돌릴 수 있나요? 149 | - [ ] 모든 소프트웨어 자산을 버전 관리 저장소에 모아놨습니까? 버전 관리 저장소에서 필요한 파일을 모두 가져와서 빌드를 온전히 수행할 수 있나요? 150 | - [ ] 가장 실패할 법한 빌드 태스크를 빌드 스크립트의 앞부분에 놓아서 빌드 실패 통지를 신속히 받을 수 있게 해놓았습니까? 151 | - [ ] 소프트웨어 빌드 프로세스를 위한 '통합 버튼'이 있습니까? 데이터베이스 통합을 자동화해 놨습니까? 테스트는요? 검사는요? 배포는 어떤가요? 빌드 프로세스로부터 피드백을 받아서 사용하고 있나요? 152 | - [ ] 별도의 컴퓨터에서 통합 빌드 프로세스를 수행합니까? 153 | - [ ] 통합 빌드에 걸리는 시간이 얼마나 됩니까? 빌드 시간을 짧게 줄여서 피드백을 개선할 방법을 찾고 있나요? 154 | - [ ] CI 서버를 사용해서 소프트웨어를 통합하고 있습니까? 혹은 사람이 직접 빌드를 통합하기 위한 체계 잡힌 프로세스를 갖추고 있나요? 155 | - [ ] 통합 빌드를 얼마나 자주 수행합니까? 매주마다? 저녁마다? 매시간마다? 아니면 변경될 때(지속적으로)마다 합니까? 156 | 157 | ## 지속적인 데이터베이스 통합 158 | 159 | ### 실천 방법 160 | 161 | - 데이터베이스 통합을 자동화하세요. 자동화된 빌드를 써서 데이터베이스를 다시 빌드하고 테스트 데이터를 삽입하세요. 162 | - 로컬 데이터베이스 샌드박스를 쓰세요. 개발자 모두가 SQL 스크립트로 생성할 수 있는 자신만의 데이터베이스 복사본을 가져야 합니다. 자신의 컴퓨터에 데이터베이스 복사본이 있어도 되고 개발 서버 한 곳에 있어도 상관 없습니다. 공유 서버에 자신만의 복사본을 갖고 있기만 하다면요. 163 | - 버전 관리 저장소를 써서 데이터베이스 자산을 공유하세요. DDL과 DML 스크립트를 버전 관리 시스템에 커밋해 넣고, 다른 개발자가 똑같은 스크립트를 써서 데이터베이스와 테스트 데이터를 다시 만들 수 있게 하세요. 164 | - 개발자에게 데이터베이스를 수정할 수 있는 권한을 주세요. 한두 사람만 데이터베이스를 변경할 수 있을 때 벌어지는 DBA 병목 현상을 피하세요. 개발자에게 DDL 및 DML 스크립트를 수정하고, 그렇게 수정한 스크립트를 버전 관리 저장소에 커밋해 넣을 권한을 주세요. 165 | - DBA를 개발팀의 일원으로 만드세요. DBA도 개발자가 쓰는 것과 똑같은 자동화된 빌드(여기엔 데이터베이스를 다시 만드는 기능도 포함됩니다)를 돌리면 일관성을 보장해나갈 수 있습니다. DBA를 개발팀의 일원으로 만들면, DBA와 개발자의 경험을 공유하게 되고, 데이터베이스 팀과 개발 팀 양측에 도움이 됩니다. 166 | 167 | ### 질문 168 | 169 | - [ ] 자동화된 빌드 프로세스를 써서 데이터베이스를 다시 만들어낼 수 있습니까? "버튼 하나만 누르면" 데이터베이스를 다시 빌드할 수 있나요? 170 | - [ ] 데이터베이스 통합 자동화에 관련된 스크립트(빌드 및 SQL)를 버전 관리 저장소에 커밋해넣습니까? 171 | - [ ] 프로젝트 구성원 모두가 자동화된 빌드 프로세스를 써서 데이터베이스를 다시 만들어낼 수 있습니까? 172 | - [ ] 개발 도중에 버전 관리 저장소를 사용하여 이전 버전의 데이터베이스로 되돌아갈 수 있습니까? 173 | - [ ] 데이터베이스 통합 프로세스가 지속적입니까? 변경한 코드를 버전 관리 저장소에 적용할 때마다 소프트웨어 코드 변경 내역이 최신의 데이터베이스 코드와 함께 통합되고 테스트됩니까? 174 | - [ ] 테스트를 돌려서 데이터베이스 저장 프로시저나 트리거의 행동을 검증합니까? 175 | - [ ] 자동화된 데이터베이스 통합 프로세스의 설정을 쉽게 바꿀 수 있습니까? 사용자 아이디, 유일한 데이터베이스 식별자, 테이블 공간 크기 및 기타 사항을 하나의 설정 파일만으로 수정할 수 있나요? 176 | 177 | ## 지속적인 테스트 (Testing) 178 | 179 | ### 실천 방법 180 | 181 | - 단위 테스트를 자동화하세요. 마음에 드는 NUnit이나 JUnit 같은 단위 테스트 프레임워크를 골라 단위 테스트를 자동화하세요. 단위 테스트에는 파일 시스템이나 데이터베이스 같은 외부 의존성이 없어야 합니다. 182 | - 컴포넌트 테스트를 자동화하세요. 데이터베이스를 사용한다면 JUnit, NUnit, DbUnit, NDbUnit 같은 단위 테스트 프레임워크를 이용해 컴포넌트 테스트를 자동화하세요. 컴포넌트 테스트는 단위 테스트보다 더 많은 객체들이 관여하고 보통 실행 시간도 더 깁니다. 183 | - 시스템 테스트를 자동화하세요. 시스템 테스트는 컴포넌트 테스트보다 실행 시간이 길고 일반적으로 다수의 컴포넌트들이 관여합니다. 184 | - 기능 테스트를 자동화하세요. 기능 테스트는 Selenium(웹 애플리케이션용)이나 GUI 애플리케이션용 Abbot 같은 도구를 사용하여 자동화할 수 있습니다. 기능 테스트는 사용자의 관점에서 동작하며 보통 자동화된 테스트 수트 중에서 실행 시간이 가장 깁니다. 185 | - 개발자 테스트를 여러 범주로 나누세요. 테스트들을 각각의 유형으로 뚜렷이 나눔으로써, 실행이 느린 테스트(예, 컴포넌트)를 실행이 빠른 테스트(예, 단위)와 주기를 달리 하여 실행시킬 수 있습니다. 186 | - 실행 시간이 짧은 테스트부터 돌리세요. 컴포넌트, 시스템, 기능 테스트보다 단위 테스트를 먼저 돌리세요. 테스트들을 여러 범주로 나누면 이렇게 할 수 있습니다. 187 | - 결함 검사용 테스트를 작성하세요. 결함을 새로 발견할 때마다 테스트를 작성하고 결함이 다시는 수면 위로 드러나지 않도록 함으로써 코드 적용범위를 늘리세요. 188 | - 컴포넌트 테스트를 반복 가능하게 만드세요. 데이터베이스 테스트 프레임워크를 이용해 데이터가 '우리가 아는 상태'로 준비되게 하세요. 그러면 컴포넌트 테스트를 반복 가능하게 만드는 데 도움이 됩니다. 189 | - 테스트 케이스 하나에 어썰트 하나로 제한하세요. 자동화된 테스트를 테스트 하나에 어썰트 하나로 제한함으로써 테스트 실패의 원인을 추적하는 시간을 줄일 수 있습니다. 190 | 191 | ### 질문 192 | 193 | - [ ] 단위 테스트, 컴포넌트 테스트, 시스템 테스트, 기능 테스트 같은 자동화된 테스트들을 여러 범주로 나누었습니까? 194 | - [ ] 지속적인 통합 시스템을 조정하여 각 테스트 범주를 각기 다른 빌드 때 돌리고 있습니까? 195 | - [ ] 각 결함마다 자동화된 단위 테스트를 작성하고 있습니까? 196 | - [ ] 테스트 케이스 하나하나에 어썰트가 얼마나 많이 있습니까? 테스트 케이스 하나에 어썰트 하나로 제한하고 있습니까? 197 | - [ ] 테스트들을 자동화할 수 있습니까? 자동화된 개발자 테스트를 버전 관리 저장소에 커밋해 넣었습니까? 198 | 199 | ## 지속적인 검사 (Inspection) 200 | 201 | ### 실천 방법 202 | 203 | - 코드 복잡도를 줄이세요. 복잡도가 높은 코드 영역을 찾아내는 JavaNCSS나 CCMetrics 같은 자동화된 검사기를 활용하여 코드 베이스의 순환 복잡도(Cyclomatic Complexity)를 낮추세요. 204 | - 설계 검토를 지속적으로 수행하세요. 다른 패키지에 의존하는 정도가 심하거나 아키텍처를 깨뜨릴지 모르는 패키지/어셈블리를 찾아내는 일에 도움이 될 만한 도구를 사용하세요. 205 | - 코드 심사(Audit)를 하여 조직에서 정한 표준을 잘 지키게 하세요. 코딩 표준 위반 사례를 보고하는 PMD나 FxCop 같은 도구를 자동화된 빌드에서 돌리세요. (Snyk 같은 Vulnerability Scanner 포함) 206 | - 중복 코드를 줄이세요. 사용자가 정한 임계치에 따라 코드 중복 정도가 더한 영역을 꼭 집어내는 Simian이나 CPD 같은 도구를 돌려서 코드 베이스의 중복 코드량을 줄이세요. 207 | - 코드 적용 범위를 평가하세요. NCover, Cobertura 또는 Clover 같은 도구를 활용하여 라인 커버리지와 브랜치 커버리지를 알아내세요. 이렇게 알아낸 값을 활용하여 테스트가 더 필요한 영역을 찾아내세요. 208 | 209 | ### 질문 210 | 211 | - [ ] 단위 테스트를 어쩌다 한 번 수행하나요? 아니면 주기적으로 수행하나요? 그렇지 않으면 지속적으로 수행하나요? 얼마나 자주 단위, 컴포넌트 그리고 시스템 테스트 적용범위 검토를 전부 다 돌려보나요? 212 | - [ ] 코드 복잡도를 감시합니까? 213 | - [ ] JDepend나 NDepend 같은 도구를 써서 자동화된 설계 검토를 지속적으로 수행하나요? 214 | - [ ] PMD, CheckStyle이나 FxCop 같은 도구를 써서 코드 심사를 자동화했나요? 215 | - [ ] 코드 중복을 감시합니까? 216 | - [ ] 코드 적용범위를 평가할 수 있습니까? 그 결과에 어떻게 대응하나요? 217 | - [ ] 그에 상응하는 테스트를 가진 코드가 몇 퍼센트나 되는지 압니까? 218 | - [ ] 적용범위 보고서를 만들도록 빌드를 적절히 설정했나요? 219 | 220 | ## 지속적인 배포 221 | 222 | ### 실천 방법 223 | 224 | - 작동하는 소프트웨어를 언제 어느 곳에서든 릴리즈하세요. 컴파일, 테스트, 검사, 패키징, 배포를 포함해서 완전히 자동화된 빌드를 돌림으로써, 어느 시점에서든 어느 환경에서든 잘 작동하는 소프트웨어를 릴리즈할 능력을 확보하게 됩니다. 225 | - 저장소 안의 자산에 꼬리표(Label)를 붙이세요. 버전 관리 저장소에 들어있는 프로젝트 관련 파일에 꼬리표를 붙이세요. 보통 이러한 활동은 프로젝트 이정표 끝무렵에 합니다. 226 | - 깨끗한 환경을 만드세요. 통합 빌드 머신에서 파일이나 설정 변경 또는 서버 등을 모두 제거하고, 다시 빌드했을 때 통합 빌드가 성공했던 상태를 재현할 수 있는지 확인하세요. 이러한 과정을 스크립트화하면 할수록 더 좋습니다. 227 | - 각 빌드에 꼬리표를 붙이세요. 버전 관리 저장소에 들어 있는 바이너리 산출물에 꼬리표를 붙이세요. 228 | - 테스트를 모두 돌리세요. 모든 테스트를 돌리세요. 여기에는 단위 테스트, 컴포넌트 테스트, 시스템 테스트, 기능 테스트, 그리고 경우에 따라선 성능 테스트나 부하 테스트를 비롯해 소프트웨어가 인도될 준비가 됐는지 확인시켜줄 다른 유형의 테스트가 포함됩니다. 229 | - 빌드 피드백 보고서를 만드세요. 가장 최근 빌드 때 만들어진 변경 내역을 목록으로 만드세요. 이렇게 하면 품질 보증 같은 인도 과정에서 다른 팀에게 도움이 될 수 있습니다. 230 | - 릴리즈를 롤백할 수 있는 능력을 확보하세요. 언제라도 잘못될 수가 있습니다. 그러니 버전 관리 저장소에 커밋되선 안 됐던 변경 사항을 롤백하기 위해 빌드 꼬리표를 사용하세요. 231 | 232 | ### 질문 233 | 234 | - [ ] 릴리즈를 롤백할 수 있는 능력이 있습니까? 235 | - [ ] 버전 관리 시스템에 들어있는 빌드에 꼬리표를 붙이고 있습니다. 236 | - [ ] 릴리즈 후보를 사람이 직접 테스트한 후에 돌릴 자동화된 테스트를 제대로 갖췄습니까? 237 | - [ ] 여러분의 팀은 릴리즈 수정을 어떻게 다룹니까? 238 | - [ ] 버전 관리 꼬리표와 빌드 버전이 연관되어 있습니까? 239 | - [ ] 빌드를 할 때 피드백 보고서를 생산합니까? 240 | - [ ] 명령줄에서 명령어 하나만 치면 소프트웨어를 배포할 수 있습니까? 241 | - [ ] 버전 관리 저장소에서 배포할 걸 만들어낼 수 있습니까? 242 | - [ ] 다양한 환경을 위해 배포 설정을 바꿀 수 있습니까? 사용자 환경과 똑같은 '깨끗한' 환경에서 소프트웨어를 적절히 설치하고 돌리고 있나요? 243 | - [ ] 버그 추적 시스템이 있습니까? 그 버그 추적 시스템은 보고서를 만들어낼 수 있습니까? 244 | 245 | ## 지속적인 피드백 246 | 247 | ### 질문 248 | 249 | - [ ] 피드백 프로세스를 자동화했습니까? 250 | - [ ] 피드백이 CI 시스템에 들어있어서 피드백을 사람이 직접 보낼 필요가 없습니까? 251 | - [ ] 적절한 사람에게 통지를 보내고 있습니까? 너무 많은 사람에게 너무 자주 통지를 보내고 있진 않습니까? 252 | - [ ] 시의 적절하게 피드백을 보내나요? 문제가 드러났을 때 곧바로 프로젝트 구성원들이 그에 대한 피드백을 받고 있나요? 253 | - [ ] 프로젝트 구성원들에게 알맞은 분량의 정보를 보내고 있습니까? 254 | - [ ] 팀이 지역적으로 분산되어 있습니까? 정보 방열기를 자동화했나요? 255 | - [ ] 피드백을 재미있게 만들었습니까? 소리나 앰비언트 오브(수정구처럼 생겼으며, 입력값에 따라 다양한 색상을 나타내주는 장치) 같은 장치를 피드백 프로세스에 넣었나요? 256 | -------------------------------------------------------------------------------- /reference/agile/user-story.md: -------------------------------------------------------------------------------- 1 | # 사용자 스토리 2 | 3 | > 사용자 스토리: 고객 중심의 요구사항 기법 - 마이크 콘 4 | 5 | - [사용자 스토리](#사용자-스토리) 6 | - [1부. 시작하기](#1부-시작하기) 7 | - [🎯개요](#개요) 8 | - [좋은 스토리의 6가지 특성 (INVEST)](#좋은-스토리의-6가지-특성-invest) 9 | - [(Independent) 독립적이다](#independent-독립적이다) 10 | - [(Negotiable) 협상 가능하다](#negotiable-협상-가능하다) 11 | - [(Valuable) 사용자와 고객 혹은 구매자에게 가치 있다](#valuable-사용자와-고객-혹은-구매자에게-가치-있다) 12 | - [(Estimatable) 추정 가능하다](#estimatable-추정-가능하다) 13 | - [(Small) 작다](#small-작다) 14 | - [(Testable) 테스트 가능하다](#testable-테스트-가능하다) 15 | - [사용자 역할 모델링](#사용자-역할-모델링) 16 | - [사용자 역할 목록을 만들기 위한 절차](#사용자-역할-목록을-만들기-위한-절차) 17 | - [도움이 되는 기법 2가지](#도움이-되는-기법-2가지) 18 | - [스토리 수집하기](#스토리-수집하기) 19 | - [스토리 수집 기법](#스토리-수집-기법) 20 | - [좋은 스토리를 위한 지침](#좋은-스토리를-위한-지침) 21 | - [목적 스토리로 시작하라](#목적-스토리로-시작하라) 22 | - [케이크 자르듯 나누어라](#케이크-자르듯-나누어라) 23 | - [닫힌 스토리를 작성하라](#닫힌-스토리를-작성하라) 24 | - [제약사항 기록하기](#제약사항-기록하기) 25 | - [스토리의 크기는 시간축에 맞추어라](#스토리의-크기는-시간축에-맞추어라) 26 | - [되도록 사용자 인터페이스를 배제하라](#되도록-사용자-인터페이스를-배제하라) 27 | - [스토리에 사용자 역할을 포함하라](#스토리에-사용자-역할을-포함하라) 28 | - [한 명의 사용자를 대상으로 작성하라](#한-명의-사용자를-대상으로-작성하라) 29 | - [능동태로 작성하라](#능동태로-작성하라) 30 | - [고객이 작성하라](#고객이-작성하라) 31 | - [스토리 카드에 번호를 부여하지 말라](#스토리-카드에-번호를-부여하지-말라) 32 | - [목적을 잊지 말라](#목적을-잊지-말라) 33 | - [2부. 추정과 계획](#2부-추정과-계획) 34 | - [스토리 점수](#스토리-점수) 35 | - [추정하기](#추정하기) 36 | - [델파이 법(Wideband Delphi)](#델파이-법wideband-delphi) 37 | - [삼각측량](#삼각측량) 38 | - [스토리가 크면 정확성이 떨어진다](#스토리가-크면-정확성이-떨어진다) 39 | - [3부. 자주 논의하는 것](#3부-자주-논의하는-것) 40 | - [스토리가 아닌 것](#스토리가-아닌-것) 41 | - [User Story는 IEEE 830이 아니다](#user-story는-ieee-830이-아니다) 42 | - [User Story는 Use Case가 아니다](#user-story는-use-case가-아니다) 43 | - [User Story는 Scenario가 아니다](#user-story는-scenario가-아니다) 44 | - [왜 사용자 스토리인가?](#왜-사용자-스토리인가) 45 | - [스토리 냄새 카탈로그](#스토리-냄새-카탈로그) 46 | - [스크럼에서 사용자 스토리 사용하기](#스크럼에서-사용자-스토리-사용하기) 47 | - [XP와 마찬가지로 스크럼은 반복적이고 점진적인 프로세스다.](#xp와-마찬가지로-스크럼은-반복적이고-점진적인-프로세스다) 48 | - [스크럼의 기본](#스크럼의-기본) 49 | - [스크럼에 스토리 추가하기](#스크럼에-스토리-추가하기) 50 | 51 | ## 1부. 시작하기 52 | 53 | ### 🎯개요 54 | 55 | > 바쁘면 이 부분만 읽는다.\ 56 | 시간이 좀더 남는다면 책에서 '4부 예제'를 본다. 57 | 58 | - 사용자 스토리는 소프트웨어의 사용자나 구매자에게 가치를 줄 수 있는 기능을 서술한 것이다. 59 | - 사용자 스토리는 다음 세 측면으로 구성된다. 60 | - 서술(written description): 스토리는 서술 형태로 기록되며, 계획하거나 기억하기 위한 단서로 사용된다. 61 | - 대화(conversation): 스토리는 대화를 통해 세부사항을 구체화한다. 62 | - 테스트(test): 스토리는 테스트를 통해 세부사항을 문서화하고 전달하며, 스토리의 완료 여부를 판단한다. 63 | - 사용자 스토리의 서술은 관행적으로 종이 인덱스 카드에 손으로 작성하기 때문에, 론 제프리즈(Ron Jeffries)는 위 세 개의 측면에 카드(Card), 대화(Conversation), 확인(Confirmation)이라는 근사한 두운을 가진 이름을 붙였다. 64 | - '카드'는 스토리의 본문(text)을 담고 있지만, 세부사항은 '대화'를 통해 결정되며 구현을 '확인'하기 위한 테스트를 포함한다. 65 | - 사용자 스토리는 사용자에게 가치를 평가 받을 수 있도록 기능을 표현해야 한다. 66 | - 스토리가 너무 큰 경우에 가끔 에픽(epic)이라고 말하기도 한다. (Jira에서는 '큰 틀'이라고 번역된다) 67 | - 에픽은 더 작은 스토리로 나눌 수 있다. 68 | - 예를 들어 '사용자는 채용 정보를 검색할 수 있다'는 에픽은 다음과 같이 3개로 나눌 수 있다. 69 | > 사용자는 위치, 급여 수준, 직업명 등의 속성값으로 채용 정보를 검색할 수 있다.\ 70 | 사용자는 검색 조건과 일치하는 채용 정보를 볼 수 있다.\ 71 | 사용자는 채용 정보를 게시한 기업에 대한 세부 정보를 볼 수 있다. 72 | - 고객팀(customer team)에는 소프트웨어가 사용자의 요구를 만족하는지 보증해 줄 사람들이 포함된다. 73 | - 여기에는 테스터, 제품 관리자(PM, Product Manager), 실제 사용자, 상호작용 설계자(Interaction Designer) 등이 포함될 것이다. 74 | - 개발자 대신 고객팀이 사용자 스토리를 작성하는 데는 두 가지 주된 이유가 있다. 75 | 1. 각 스토리는 기술적 전문 용어가 아닌 비즈니스 언어로 작성해야 한다. 그래야 고객팀에서 스토리를 어느 이터레이션(Iteration)이나 릴리즈(Release)에 포함시킬지 우선순위를 결정할 수 있다. 76 | 2. 제품의 주된 기획 주체로서 고객팀은 제품의 동작을 가장 잘 설명할 수 있다. 77 | - 개발팀과 고객팀이 합의한 내용은 스토리가 정확하게 개발되었는지를 증명하는 테스트 형태로 문서화된다. 78 | > 사용자는 검색 조건과 일치하는 채용 정보를 볼 수 있다.\ 79 | \ 80 | 주) 마르코는 설명, 급여, 위치 정보를 보여 주어야 한다고 함. 81 | - 테스트 서술은 간결해야 한다. 테스트는 어느 때라도 추가하거나 제거할 수 있다. 82 | - 릴리즈는 하나 이상의 이터레이션으로 이루어진다. 83 | - 이터레이션 계획(iteration planning)은 이번 이터레이션에 포함할 스토리를 선택하는 일을 말한다. 84 | - 릴리즈 계획(release planning)은 프로젝트 일정과 구현할 기능 집합의 균형을 결정하는 일이다. 85 | - 릴리즈 계획은 고객 팀이 스토리에 우선순위를 매기는 것으로 시작한다. 우선순위를 부여할 때 다음 사항들을 고려해야 한다. 86 | - 사용자나 고객 다수가 원하는 기능인가? 87 | - 다수는 아니지만 중요한 사용자나 고객이 바라는 기능인가? 88 | - 이 스토리가 다른 스토리들과 응집성(cohesiveness)이 있는가? 예를 들어 도면 조회 시스템에서 'zoom out' 기능의 스토리는 그 자체로 우선순위가 높지 않지만 'zoom in' 기능의 스토리는 우선순위가 높을 경우, 둘의 상호 보완적 관계 때문에 두 스토리 모두 우선순위를 높게 다룰 수 있다. 89 | - 스토리 개발에 드는 비용 역시 우선순위를 부여할 때 고려할 요인이다. 90 | - 스토리 개발 비용은 개발자들이 스토리에 부여하는 추정치다. 91 | - 각 스토리에 '스토리 점수(story point)'를 추정치로 할당한다. 92 | - 한 이터레이션에서 스토리 점수 4점으로 추정한 것은, 그 스토리를 개발하는 데는 2점으로 추정한 다른 스토리보다 두 배 정도 시간이 걸릴 것을 예상한다는 의미다. 93 | - 인수 테스트(6장)는 스토리를 개발한 뒤 그것이 고객이 기대하는 대로 정확히 동작하는지를 입증하는 과정이다. 94 | - '사용자는 장바구니에 담긴 아이템을 구매할 때 신용 카드로 결제할 수 있다'는 스토리를 보자. 95 | - 고객은 스토리 카드 뒷면에 다음과 같은 간단한 테스트들을 작성한다. 96 | > 비자, 마스터카드, 아메리칸익스프레스카드 테스트(통과).\ 97 | 다이너스클럽카드 테스트(실패).\ 98 | 비자직불카드 테스트(통과).\ 99 | 정상/비정상 카드 ID 테스트. 분실 카드 ID 테스트.\ 100 | 유효 기간 만료된 카드 테스트.\ 101 | 다양한 구매액 테스트(카드 한도 초과액 포함). 102 | 103 | ### 좋은 스토리의 6가지 특성 (INVEST) 104 | 105 | #### (Independent) 독립적이다 106 | 107 | - 가능하면 스토리 간에 의존성을 배제하도록 신경 써야 한다. 108 | - 스토리 사이에 의존성이 있으면 우선순위 결정과 계획 수립에 문제를 야기한다. 109 | > 기업은 채용 공고를 게시할 때 비자카드로 결제할 수 있다.\ 110 | 기업은 채용 공고를 게시할 때 마스터카드로 결제할 수 있다.\ 111 | 기업은 채용 공고를 게시할 때 아메리칸익스프레스카드로 결제할 수 있다. 112 | - 이런 형태의 의존성이 나타날 때에는 두 가지 방법을 시도해 볼 수 있다. 113 | - 의존성이 있는 스토리들을 합쳐 좀더 큰 하나의 독립적인 스토리로 만든다. 114 | > 기업은 채용 공고를 게시할 때 신용카드로 결제할 수 있다. 115 | - 스토리들을 다른 방식으로 분리한다. 116 | > 고객은 한 종류의 신용카드로 결제할 수 있다.\ 117 | 고객이 결제할 수 있는 신용카드는 두 종류가 더 있다. 118 | 119 | #### (Negotiable) 협상 가능하다 120 | 121 | - 스토리는 계약서나 요구사항 명세서처럼 꼭 구현해야 한다고 기록된 것이 아니다. 122 | - 스토리는 기능에 대한 짧은 설명일 뿐, 세부사항은 고객과 개발 팀이 **대화**를 통해 협상해야 한다. 123 | - 스토리 카드는 대화를 이끌기 위한 단서지, 그 자체로 완성된 상세한 요구사항이 아니기 때문에, 필요한 모든 세부사항까지 포함할 필요가 없다. 124 | 125 | #### (Valuable) 사용자와 고객 혹은 구매자에게 가치 있다 126 | 127 | - 소프트웨어를 직접 사용하는 '사용자(user)'와 소프트웨어를 구매하는 '구매자(purchaser)'가 다를 수 있다. 128 | - 스토리는 사용자 혹은 구매자에게 가치가 평가되어야 한다. 129 | - 작성하지 말아야 하는 스토리는 개발자에게만 가치 있는 스토리다. 130 | > 모든 데이터베이스 연결은 커넥션풀을 통해 이루어져야 한다.\ 131 | 모든 에러 처리 및 로그 생성은 공통 클래스들을 통해 이루어져야 한다. 132 | - 각 스토리가 고객이나 사용자에게 가치 있도록 하는 가장 좋은 방법은 고객이 직접 스토리를 작성하게 하는 것이다. 133 | 134 | #### (Estimatable) 추정 가능하다 135 | 136 | - 개발자들은 각 스토리의 크기 혹은 작업 소요 시간을 추정(적어도 추측)할 수 있어야 한다. 137 | - 추정이 쉽지 않은 경우는 보통 다음의 세 가지 이유다. 138 | 1. 해당 분야의 지식(도메인 지식)이 부족하다. 139 | - 해당 스토리를 작성한 고객과 직접 의논해야 한다. 140 | 2. 기술적인 지식이 부족하다. 141 | - 한두 명의 개발자를 '스파이크(spike)'를 수행하도록 한다. 142 | - spike? 개발 예상 기간 추정이 어렵거나 리스크가 높은 스토리를 대상으로 완전하지 않지만 처음부터 끝까지 문제 영역을 살펴보는 작업. 143 | 3. 스토리가 너무 크다. 144 | 145 | #### (Small) 작다 146 | 147 | - 스토리가 너무 크거나 너무 작으면 계획 단계에서 사용할 수 없기 때문에 스토리의 크기는 아주 중요하다. 148 | - 스토리 나누기 149 | - 에픽은 다음 두 가지 중 하나다. 150 | - 복합적인 스토리: 작은 스토리를 여러 개 포함하는 에픽이다. 복합적인 스토리를 나누는 방법은 많다. 151 | - 복잡한 스토리: 크기가 크면서도 작은 스토리들로 나누기가 쉽지 않다. 152 | - 스토리 합치기 153 | - 너무 작은 스토리란 것은, 그것을 작성하고 작업량을 추정하는 것이 내용을 변경하는 것보다 더 오래 걸릴 것 같은 스토리다. 154 | - 주로 버그 리포팅이나 UI 변경에 대한 스토리들이 여기에 해당한다. 155 | - 이런 작은 스토리들을 취급해야 한다면, 이것들을 더 큰 스토리로 합쳐서 반나절에서 며칠 정도의 작업량이 되도록 만든다. 156 | 157 | #### (Testable) 테스트 가능하다 158 | 159 | - 테스트를 성공적으로 통과해야 그 스토리가 성공적으로 개발되었다고 말할 수 있다. 160 | - 가능하면 테스트를 자동화할 수 있도록 작성해야 한다. 161 | 162 | ### 사용자 역할 모델링 163 | 164 | 사용자들은 제각기 다른 배경과 목적으로 소프트웨어를 사용하겠지만, 165 | 비슷한 유형의 사용자들을 모아 '사용자 역할(user role)'로 부를 수 있을 것이다. 166 | 사용자 역할은 특정 사용자 집단이 시스템과 어떤 상호작용을 하는지 규정하는 속성의 집합이다. 167 | 168 | #### 사용자 역할 목록을 만들기 위한 절차 169 | 170 | - 사용자 역할 목록 초안을 위한 브레인스토밍 171 | - 목록 초안 조직화 172 | - 역할 통합하기 173 | - 역할 다듬기 174 | 175 | #### 도움이 되는 기법 2가지 176 | 177 | - 등장인물(Persona) 178 | - 등장인물은 사용자 역할을 대표할 만한 가상 인물이다. 179 | - 등장인물을 만들기로 결정했다면, 등장인물이 실제 대상 고객을 왜곡하지 않고 나타내도록 180 | 시장 및 인구통계에 근거해 충분한 조사가 선행되어야 함을 명심한다. 181 | - 극단적 인물 182 | - 새로운 시스템을 설계할 때에는 극다적 인물을 사용하라. 극단적인 인물을 고려하면 여러분이 지나칠 수도 있는 스토리를 발견하게 된다. 183 | - 극단적 인물을 고려하면 새로운 사용자 스토리를 찾을 수 있지만, 이것들이 제품에 포함되어야 하는지를 판단하기란 쉽지 않다. 184 | 185 | ### 스토리 수집하기 186 | 187 | - 애자일 프로세스는 요구사항을 처음부터 다 얻어낼 수 없다는 것을 인정한다. 188 | - 릴리즈를 시작할 때에는 쉽게 찾아낼 수 있는 사용자 스토리를 작성하는 것으로 시작하는 것이 좋다. 189 | - 한 가지 방법에 지나치게 의존하기보다는 여러 방법들을 같이 적용함으로써 가장 좋은 결과를 얻을 수 있다. 190 | 191 | #### 스토리 수집 기법 192 | 193 | - 사용자 인터뷰 194 | - 가장 유용한 답변을 얻기 위해서는 개방형 질문, 문맥 무관 질문을 해야 한다. 195 | - 개방형 질문 (open-ended, 자유 응답 질문): 응답자가 자유롭게 응답하도록 하는 형태 196 | - 폐쇄형 질문: 질문자가 가능한 응답 목록을 미리 지정해 놓은 형태(Y/N, 객관식 등) 197 | - 문맥 무관 질문 (context-free): 암시적으로 특정 답변을 유도하지 않아야 하며, 질문자의 선호도가 나타나지 않아야 한다. 198 | - "얼마나 빨리 검색되어야 하나요?"보다는 "애플리케이션에서 성능이 더 중요한 부분이 있나요?" 199 | - "제목으로 채용 정보를 검색하시나요?"보다는 "채용 정보를 어떻게 검색하고 싶은지 말씀해주세요." 200 | - 설문 201 | - 이미 가지고 있는 스토리에 대한 정보를 수집하는 효과적인 기법이다. 큰 사용자 집단을 대상으로 한다면, 설문은 스토리에 우선순위를 매기기 위한 정보를 수집하는 아주 훌륭한 방법이다. 202 | - 관찰 203 | - 스토리 작성 워크숍 204 | 205 | ### 좋은 스토리를 위한 지침 206 | 207 | #### 목적 스토리로 시작하라 208 | 209 | 한번에 하나씩 사용자 역할을 선택하여 그 사용자가 새 시스템을 사용하는 주 목적을 식별하는 것이 가장 효과적이었다. 210 | 211 | #### 케이크 자르듯 나누어라 212 | 213 | 큰 스토리를 만났을 때에는 그것을 작은 스토리 조각으로 나눌 수 있다는 사실을 명심하자. 214 | 215 | #### 닫힌 스토리를 작성하라 216 | 217 | 닫힌 스토리는 의미 있는 목적을 달성하는 형태로 작성되어 사용자로 하여금 무언가를 해냈다고 느끼게 하는 스토리를 말한다. 218 | 219 | - 스토리를 수집할 때 개방향 질문을 통해 스토리를 찾는 것과 비교해 볼 수 있다. 새 스토리를 찾으려면 고객이나 사용자에게 개방형, 즉 열린 질문을 하고, 스토리를 작성할 때에는 닫힌 형태로 작성하여야 한다. 220 | 221 | #### 제약사항 기록하기 222 | 223 | 어떤 스토리가 직접 구현될 내용은 아니지만 시스템이 꼭 지켜야 하는 내용인 경우 '제약사항'이라는 표식(제약사항 스토리 카드)을 달아둔다. 224 | 225 | #### 스토리의 크기는 시간축에 맞추어라 226 | 227 | 먼 나중에 일어날 일이 아닌 가까운 미래에 일어날 중요한 일에 더 집중한다. 228 | 229 | #### 되도록 사용자 인터페이스를 배제하라 230 | 231 | 사용자 인터페이스에 관한 세부사항은 소프트웨어가 좀더 구체적인 모양을 갖추고 스토리가 기존 기능을 수정하거나 확장하는 것을 의미하게 될 때다. 232 | 233 | 스토리가 새로운 기능을 의미할 때에는 구현 세부사항을 배제한다. 234 | 235 | #### 스토리에 사용자 역할을 포함하라 236 | 237 | 사용자 역할을 식별해 냈다면 '사용자는 이력서를 작성할 수 있다'고 하는 대신 '구직자는 이력서를 작성할 수 있다'고 작성한다. 238 | 239 | #### 한 명의 사용자를 대상으로 작성하라 240 | 241 | '구직자들(Job Seekers)은 사이트에서 이력서를 삭제할 수 있다'는 스토리를 보자. 이는 어떤 구직자가 자신의 이력서뿐만 아니라 다른 사람들의 이력서도 지울 수 있는 것으로 해석될 수 있다. 242 | 243 | #### 능동태로 작성하라 244 | 245 | '이력서는 구직자에 의해 게시될 수 있다'고 하기보다 '구직자는 이력서를 게시할 수 있다'고 작성하는 것이 더 이해하기 쉽다. 246 | 247 | #### 고객이 작성하라 248 | 249 | 고객에게는 이터레이션을 시작할 때 스토리의 우선순위를 매겨야 하는 책임이 있기 때문에 고객은 반드시 각 스토리를 이해하고 있어야 한다. 가장 잘 이해하는 방법은 직접 작성하는 것이다. 250 | 251 | #### 스토리 카드에 번호를 부여하지 말라 252 | 253 | 보통 쉽게 추적하기 위해 카드에 일련번호를 부여한다. 하지만 무의미한 업무 부담만 늘리고 구체적인 기능을 논의하는 데 불필요한 추상성을 개입시키는 문제가 있다. 254 | 255 | - 스토리 카드에 번호를 부여해야 한다는 의무감 같은 것이 느껴진다면, 그 대신 카드에 짧은 제목을 붙이고 다음부터 그 스토리를 지칭할 때 사용한다. 256 | 257 | #### 목적을 잊지 말라 258 | 259 | 스토리 카드의 주 목적은 구현할 기능을 논의하기 위한 단서 역할이라는 점을 잊지 말아야 한다. 단서는 간결해야 한다. 카드에는 나중에 대화를 재개하기 위해 기억하면 될 정도의 세부사항만을 써넣도록 하며, 너무 많은 세부사항을 써넣어 카드가 대화를 대신하지 않게 한다. 260 | 261 | ## 2부. 추정과 계획 262 | 263 | ### 스토리 점수 264 | 265 | 개발자들이 스토리에 부여하는 이상적인 경과 시간 추정치다. 스토리 점수는 팀마다 자신들에게 맞는 정의를 채택하여 사용할 수 있다는 장점이 있다. 266 | 267 | ### 추정하기 268 | 269 | #### 델파이 법(Wideband Delphi) 270 | 271 | #### 삼각측량 272 | 273 | #### 스토리가 크면 정확성이 떨어진다 274 | 275 | 스토리 점수로 추정할 때의 문제점은 수치 상의 차이를 설명하기 어렵다는 것이다. 팀은 추정치를 아래와 같이 미리 정의된 수치로만 한정할 수 있을 것이다. 276 | 277 | > 1/2, 1, 2, 3, 5, 8, 13, 20, 40, 80 278 | 279 | 추정치가 크다는 것은 그만큼 스토리를 잘 모르기 때문이라는 사실을 반영하여 값이 커질수록 간격도 커진다는 것을 확인할 수 있다. 에픽을 추정할 때는 40점인지 80점인지만 결정하면 된다. 79점인지 80점인지 고민할 필요는 없다. 280 | 281 | ## 3부. 자주 논의하는 것 282 | 283 | ### 스토리가 아닌 것 284 | 285 | User Story는 IEEE 830 명세서나 Use Case와는 달리 분석 작업의 결과물이 아니다. 286 | 287 | #### User Story는 IEEE 830이 아니다 288 | 289 | IEEE 컴퓨터 학회에서는 소프트웨어 요구사항 명세서 작성에 관한 가이드라인을 출판하였다(IEEE 1999). 'IEEE 표준 830'이라 알려진 이 문서의 가장 두드러진 특징은 기능 요구사항(functional requirements)을 작성할 때 '시스템은 ...해야 한다(The system shall...)' 형태의 문장을 사용한다는 점이다. 290 | 291 | > 시스템은 기업이 채용 공고를 게시할 때 신용카드로 결제할 수 있어야 한다.\ 292 | 시스템은 비자, 마스타, 아메리칸익스프레스카드 등을 처리할 수 있어야 한다.\ 293 | 시스템은 웹 사이트에 채용 공고가 게시되기 전에 결재를 먼저하도록 해야 한다.\ 294 | 시스템은 사용자에게 고유의 확인 번호를 부여해야 한다. 295 | 296 | 시스템의 요구사항을 이러한 수준으로 자세하게 문서화하다 보면 장황해지기 쉽고 실수하기도 쉬우며 시간도 많이 든다. 게다가, 솔직히 말해서 이런 문서는 읽기에 지루하다. 297 | 298 | IEEE 830 스타일의 요구사항 기술방식은 사용자의 목적보다는 요구사항 목록 자체에 주의를 기울이게 하기 때문에 프로젝트가 방향을 잃는 경우가 많았다. 299 | 300 | #### User Story는 Use Case가 아니다 301 | 302 | - 범위(scope): 둘 다 비즈니스 가치를 기술하는데 적합한 크기지만 User Story는 제약 조건(개발하는 데 열흘이 넘지 않도록)을 두어, 일정 계획에 사용하기 편리하도록 작은 범위를 다룬다. 303 | - 완전성: 스토리 카드에 인수 테스트를 더해야 Use Case와 동일하다. 304 | - 수명(longevity): Use Case는 개발 기간이나 유지보수 기간에 계속 사용된다. 반면 User Story는 그것을 개발한 이터레이션 후에는 유지할 필요가 없다. 305 | - 구현 세부사항: Use Case는 사용자 인터페이스에 관한 세부사항을 포함하는 경우가 많다. (그렇게 하지 말 것을 권장함에도 불구하고) 306 | - 목적: Use Case는 개발자와 고객이 그것을 논의하고 거기에 동의하기 위해 작성된다. User Story는 릴리즈를 계획하거나 대화를 통해 상세한 요구사항을 찾기 위한 매개체로 사용된다. 307 | 308 | #### User Story는 Scenario가 아니다 309 | 310 | 시나리오는 사용자 스토리보다 훨씬 상세한 내용을 담고 있으며 보통 여러 사용자 스토리를 포함한다. 311 | 312 | ### 왜 사용자 스토리인가? 313 | 314 | - 사용자 스토리는 문서보다 구두 의사소통을 강조한다. 315 | - 사용자 스토리는 이해하기 쉽다. 고객이나 개발자 모두 이해할 수 있다. 316 | - 사용자 스토리는 계획 수립에 적합한 크기다. 317 | - 사용자 스토리는 반복적 개발(iterative development)에 효과적이다. 318 | - 사용자 스토리는 세부사항을 나중에 고려할 수 있게 해준다. 319 | - 사용자 스토리는 기회주의적 개발을 지원한다. 320 | - 사용자 스토리는 참여적 설계를 유도한다. 321 | - 사용자 스토리는 암묵적 지식을 구축한다. 322 | 323 | ### 스토리 냄새 카탈로그 324 | 325 | - 너무 작은 스토리 326 | - 증상: 추정치를 빈번히 조정해야 함. 327 | - 상호 의존적인 스토리 328 | - 증상: 스토리들 간의 의존성 때문에 이터레이션을 계획하기가 어려움. 329 | - 금도금(goldplating) 330 | - 증상: 개발자들이 이터레이션 계획에 포함되지 않은 기능을 추가하거나 스토리를 마음대로 해석하여 그 스토리를 구현하는 데 필요한 것 이상의 작업을 하고 있다. 331 | - 너무 상세한 스토리 332 | - 증상: 스토리 구현에 앞서 세부사항들을 모으는 데 시간을 과도하게 소비한다. 또는 스토리에 대해 이야기 나누는 것보다 스토리를 작성하는 데 시간을 더 많이 소비한다. 333 | - 사용자 인터페이스와 관련된 세부사항을 너무 일찍 포함시키기 334 | - 증상: 프로젝트(특히 신제품 개발 프로젝트) 초기에 작성된 스토리들이 사용자 인터페이스와 관련된 세부사항들을 포함한다. 335 | - 너무 앞서 생각하기 336 | - 증상: 이 냄새는 여러 가지 증상으로 확인할 수 있다. 스토리들을 인덱스 카드에 기록하기 어렵다거나, 팀의 규모나 위치 조건 때문에 어쩔 수 없는 경우가 아닌데도 인덱스 카드보다 소프트웨어를 활용하려고 한다거나, 누군가가 세부사항들까지 잡아내기 위한 스토리 템플릿을 제안한다거나, 더 상세한 (예를 들어 일 단위 대신 시간 단위의) 추정치를 부여할 것을 제안하는 등의 증상이 있다. 337 | - 스토리를 너무 많이 나누기 338 | - 증상: 이터레이션을 계획할 때 작업량을 맞추기 위해 스토리를 나누는 경우가 많다. 339 | - 고객이 우선순위 부여를 어려워 함 340 | - 증상: 스토리를 선택하고 우선순위를 부여하는 일은 어렵다. 때로는 스토리에 우선순위를 부여하는 것이 너무나 어려워 거기서 냄새가 날 수도 있다. 341 | - 고객이 스토리를 작성하거나 우선순위를 부여하지 않으려고 함 342 | - 증상: 고객이 스토리를 작성하고 거기에 우선순위를 부여하는 책임을 지지 않으려고 한다. 343 | 344 | ### 스크럼에서 사용자 스토리 사용하기 345 | 346 | #### XP와 마찬가지로 스크럼은 반복적이고 점진적인 프로세스다. 347 | 348 | - 반복적(iterative) 프로세스는 계속적인 정련(refine) 작업을 통해 진행되는 프로세스를 의미한다. 349 | - 점진적(incremental) 프로세스는 소프트웨어를 여러 부분으로 나누어 각 부분을 개별적으로 개발하고 전달하는 프로세스를 의미한다. 350 | 351 | #### 스크럼의 기본 352 | 353 | - 스크럼 프로젝트는 스프린트(sprint)라 불리는 30일 단위의 이터레이션을 통해 진행된다. 354 | - 각 스프린트를 시작할 때, 스크럼 팀은 그 스프린트 동안 수행할 작업량을 결정한다. 355 | - 수행할 작업들은 제품 백로그(product backlog)라 불리는 우선순위가 매겨진 목록에서 선택한다. 356 | - 스크럼 팀이 해당 스프린트동안 완료하기 위해 선택한 작업들은 제품 백로그에서 스프린트 백로그(sprint backlog)라는 목록으로 옮겨진다. 357 | - 매일 열리는 일일 스크럼 회의(Daily Scrum Meeting)에서는 현재 진행 상황을 파악하고 대처할 수 있도록 한다. 358 | 359 | ![[https://www.scrum.org/resources/what-is-scrum](https://www.scrum.org/resources/what-is-scrum)](../../image/agile/scrum.png) 360 | 361 | [scrum.org](https://www.scrum.org/resources/what-is-scrum) 362 | 363 | ![[http://www.controlchaos.com/scaled-professional-scrum/](http://www.controlchaos.com/scaled-professional-scrum/)](../../image/agile/scrum-nexus.png) 364 | 365 | [controlchaos.com](http://www.controlchaos.com/scaled-professional-scrum/) 366 | 367 | #### 스크럼에 스토리 추가하기 368 | 369 | - 제품 백로그에 사용자 스토리만을 넣도록 제한함으로써 제품 소유자가 우선순위를 부여하는 것이 훨씬 쉬워진다. 사용자 스토리로 작성된 백로그 항목들은 제품 소유자가 이해할 수 있는 용어로 기술되어 있으므로 제품 소유자가 기능 간 우선순위를 비교하는 것이 더 쉬워진다. 370 | - 스프린트 계획 회의 동안 제품 소유자와 팀은 제품 백로그에서 우선순위가 가장 높은 항목들을 논의한다. 그리고 나서 팀은 해당 스프린트 동안 수행할 항목들을 골라낸다. 371 | -------------------------------------------------------------------------------- /reference/commit-message.md: -------------------------------------------------------------------------------- 1 | # 커밋 메시지 작성 2 | 3 | - [커밋 메시지 작성](#커밋-메시지-작성) 4 | - [참고](#참고) 5 | - [개요](#개요) 6 | - [git 커밋 메시지를 잘 쓰려고 노력해야 하는 이유](#git-커밋-메시지를-잘-쓰려고-노력해야-하는-이유) 7 | - [기준 세우기](#기준-세우기) 8 | - [AngularJS Git Commit Message Conventions](#angularjs-git-commit-message-conventions) 9 | - [커밋 메시지 카탈로그](#커밋-메시지-카탈로그) 10 | - [FIX](#fix) 11 | - [Fix A](#fix-a) 12 | - [Fix A in B](#fix-a-in-b) 13 | - [Fix A of B](#fix-a-of-b) 14 | - [Fix A that[which] B](#fix-a-thatwhich-b) 15 | - [Fix for A](#fix-for-a) 16 | - [Fix A to V / Fix A for N](#fix-a-to-v--fix-a-for-n) 17 | - [Fix A so that B](#fix-a-so-that-b) 18 | - [Fix A where B](#fix-a-where-b) 19 | - [Fix A when B](#fix-a-when-b) 20 | - [ADD](#add) 21 | - [Add A](#add-a) 22 | - [Add A to B](#add-a-to-b) 23 | - [Add A for B](#add-a-for-b) 24 | - [REMOVE](#remove) 25 | - [Remove A](#remove-a) 26 | - [Remove A from B](#remove-a-from-b) 27 | - [Remove A in B](#remove-a-in-b) 28 | - [Remove A to avoid B](#remove-a-to-avoid-b) 29 | - [USE](#use) 30 | - [Use A instead of B](#use-a-instead-of-b) 31 | - [Use A in B](#use-a-in-b) 32 | - [Use A for B](#use-a-for-b) 33 | - [Use A to V](#use-a-to-v) 34 | - [CHANGE](#change) 35 | - [Change A to V](#change-a-to-v) 36 | - [Change A to N](#change-a-to-n) 37 | - [Change A for N (Replace A with B)](#change-a-for-n-replace-a-with-b) 38 | - [CONVERT](#convert) 39 | - [Convert A to B](#convert-a-to-b) 40 | - [REFACTOR](#refactor) 41 | - [Refactor A](#refactor-a) 42 | - [Refactor A for B](#refactor-a-for-b) 43 | - [SIMPLIFY](#simplify) 44 | - [Simplify A](#simplify-a) 45 | - [UPDATE](#update) 46 | - [Update A](#update-a) 47 | - [Update to A](#update-to-a) 48 | - [Update A to N](#update-a-to-n) 49 | - [Update A to V](#update-a-to-v) 50 | - [Update A with N](#update-a-with-n) 51 | - [Update A for B](#update-a-for-b) 52 | - [IMPROVE](#improve) 53 | - [Improve A](#improve-a) 54 | - [MAKE](#make) 55 | - [Make A B](#make-a-b) 56 | - [Make it A to V](#make-it-a-to-v) 57 | - [Make sure to V](#make-sure-to-v) 58 | - [Make sure (that) A](#make-sure-that-a) 59 | - [IMPLEMENT](#implement) 60 | - [Implement A](#implement-a) 61 | - [Implement A to B](#implement-a-to-b) 62 | - [REVISE](#revise) 63 | - [Revise A](#revise-a) 64 | - [CORRECT](#correct) 65 | - [Correct A](#correct-a) 66 | - [ENSURE](#ensure) 67 | - [Ensure A](#ensure-a) 68 | - [PREVENT](#prevent) 69 | - [Prevent A](#prevent-a) 70 | - [Prevent A from B](#prevent-a-from-b) 71 | - [AVOID](#avoid) 72 | - [Avoid A](#avoid-a) 73 | - [Avoid A to B](#avoid-a-to-b) 74 | - [Avoid A if/when B](#avoid-a-ifwhen-b) 75 | - [MOVE](#move) 76 | - [Move A to/into B](#move-a-tointo-b) 77 | - [RENAME](#rename) 78 | - [Rename A to B](#rename-a-to-b) 79 | - [ALLOW](#allow) 80 | - [Allow A](#allow-a) 81 | - [Allow A to V](#allow-a-to-v) 82 | - [VERIFY](#verify) 83 | - [Verify A](#verify-a) 84 | - [SET](#set) 85 | - [Set A to B](#set-a-to-b) 86 | - [Set A for B](#set-a-for-b) 87 | 88 | ## 참고 89 | 90 | - [커밋 메시지 GitHub에서 검색하기](https://github.com/search?q=org:google+change+to&type=commits) 91 | - [좋은 git commit 메시지를 위한 영어 사전](https://blog.ull.im/engineering/2019/03/10/logs-on-git.html) - Reid 92 | - [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/) - Chris Beams 93 | - 번역: [좋은 git 커밋 메시지를 작성하기 위한 8가지 약속](https://djkeh.github.io/articles/How-to-write-a-git-commit-message-kor/) 94 | - [AngularJS Git Commit Message Conventions](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/) 95 | - [gist](https://gist.github.com/stephenparish/9941e89d80e2bc58a153) 96 | - [GitHub](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-commit-message-format) 97 | - [번역1](http://dogfeet.github.io/articles/2013/angularjs-git-commit-message-conventions.html) 98 | - [번역2](https://velog.io/@outstandingboy/Git-%EC%BB%A4%EB%B0%8B-%EB%A9%94%EC%8B%9C%EC%A7%80-%EA%B7%9C%EC%95%BD-%EC%A0%95%EB%A6%AC-the-AngularJS-commit-conventions) 99 | - [GitHub 에서 자주 쓰이는 영어 정리해 봤습니다](https://tagilog.tistory.com/588) - 탁이 100 | 101 | ## 개요 102 | 103 | 네이밍만큼 어려운 커밋 메시지 작성법을 정리합니다. 104 | 그런데 이제 영작문을 곁들인... 105 | 106 | ### git 커밋 메시지를 잘 쓰려고 노력해야 하는 이유 107 | 108 | 1. 더 좋은 커밋 로그 가독성 109 | 2. 더 나은 협업과 리뷰 프로세스 110 | 3. 더 쉬운 코드 유지보수 111 | 112 | ## 기준 세우기 113 | 114 | 기준은 사람마다 팀마다 프로젝트마다 다를 수 있다. 115 | 116 | - 제목과 본문을 한 줄 띄워 분리하기 117 | - `git shortlog` 118 | - `git log --online` 119 | - 제목은 영문 기준 50자 이내로 120 | - 제목은 첫 글자를 대문자로 한 명령문으로 121 | - Git Built-in Convention과 일관성 유지 122 | - `Merge branch 'myfeature'` 123 | - `Merge pull request #123 from someuser/somebranch` 124 | - `Revert "Add the thing with the stuff"` 125 | - 명령조가 어색하다면 앞에 `If applied, this commit will`을 붙여본다. 126 | - (If applied, this commit will) Refactor subsystem X for readability 127 | - 동명사보다 명사를 사용한다. 128 | - 관사(`a`, `an`, `the`)는 사용하지 않는다. 129 | - 제목 끝에 마침표(`.`) 금지 130 | - Github - 제목(이나 본문)에 이슈 번호 붙이기 131 | - 본문은 영문 기준 72자마다 줄 바꾸기 132 | - 본문은 `어떻게`보다 `무엇을`, `왜`에 맞춰 작성하기 133 | - 커밋 메시지로 Github 이슈(issue)를 자동 종료시키기 134 | - close, closes, closed: 일반 개발 이슈 135 | - fix, fixes, fixed: 버그 픽스나 핫 픽스 이슈 136 | - resolve, resolves, resolved: 문의나 요청 사항에 대응한 이슈 137 | 138 | ### AngularJS Git Commit Message Conventions 139 | 140 | ```text 141 |
142 | 143 | 144 | 145 |