책소개
단위 테스트 코드 작성을 기본으로 하는 테스트 주도 개발 방식은 소프트웨어가 테스트 가능한(Testable) 구조를 갖도록 강제하며, 이로 인해 보다 간단하면서도 구조화된 설계로 이끌 뿐만 아니라 코드에 대한 신뢰를 높일 수 있는 효과적인 방법이다. 이 책에서는 Go, 자바스크립트, 파이썬의 세 가지 프로그래밍 언어로 테스트 주도 개발을 실천하는 실용적 방법을 제공한다. 켄트 벡(Kent Beck)의 저서 『테스트 주도 개발』(인사이트, 2014)에서 다룬 돈 문제(Money Problem) 예제를 각 언어로 재해석해 서술했으며, 테스트 주도 개발 방식에 쉽고 재미있게 익숙해질 수 있도록 돕는다. 실패하는 테스트를 먼저 작성하고 프로덕션 코드를 작성해 테스트를 통과하게 만든 후 개선하는, 레드-그린-리펙터 사이클의 테스트 주도 개발 필수 구성 요소 세 단계를 다룬다. 또한 GitHub Action을 활용한 지속적 통합과, 자동화된 회귀 테스트의 실천적 방법을 제시한다.
목차
1부 시작하기
1장. 돈 문제
__레드-그린-리팩터: TDD 구성 요소
__문제 인식
__첫 번째 실패하는 테스트
____Go
____자바스크립트
____파이썬
__그린으로 전환
____Go
____자바스크립트
____파이썬
__마무리하기
____Go
____자바스크립트
____파이썬
__변경 사항 반영하기
__중간 점검
____Go
____자바스크립트
____파이썬
2장. 다양한 통화로 돈 계산
__유로에 발 들이기
____Go
____자바스크립트
____파이썬
__DRY한 코드를 유지하라
____Go
____자바스크립트
____파이썬
__반복하지 말라고 하지 않았나?
__분할 정복
____Go
____자바스크립트
____파이썬
__마무리하기
____Go
____자바스크립트
____파이썬
__변경 사항 반영하기
__중간 점검
3장. Potfolio
__다음 테스트 설계하기
____Go
____자바스크립트
____파이썬
__변경 사항 반영하기
__중간 점검
2부 모듈화
4장. 관심사의 분리
__테스트 코드와 프로덕션 코드
____단방향 의존성
____의존성 주입
____패키징 및 배포
__모듈화
__의존성 제거
__중간 점검
5장. Go의 패키지 및 모듈
__코드를 패키지로 분리하기
__Go 모듈
__패키지 생성하기
__캡슐화
__테스트에서 중복 제거하기
__변경 사항 반영하기
__중간 점검
6장. 자바스크립트의 모듈
__코드를 모듈로 나누기
__자바스크립트 모듈로 넘어가기
____CommonJS
____비동기 모듈 정의
____유니버설 모듈 정의
____ESModules
__테스트 개선하기
____테스트에서 중복 제거하기
____테스트 클래스 및 테스트 메서드 추가하기
____자동으로 테스트를 찾고 실행하기
____테스트가 성공적으로 실행되면 출력 생성하기
____앞서 실행된 테스트가 어써션에서 실패해도 모든 테스트를 실행하기
__변경 사항 반영하기
__중간 점검
7장. 파이썬의 모듈
__모듈로 코드를 분리하기
__테스트에서 중복 제거하기
__변경 사항 반영하기
__중간 점검
3부. 피처와 재설계
8장. 포트폴리오 평가하기
__돈 섞기
____Go
____자바스크립트
____파이썬
__변경 사항 반영하기
__중간 점검
9장. 여기도 통화, 저기도 통화
__해시(맵) 만들기
____Go
____자바스크립트
____파이썬
__변경 사항 반영하기
__중간 점검
10장. 오류 처리
__오류 위시리스트
____Go
____자바스크립트
____파이썬
__변경 사항 반영하기
__중간 점검
11장. 은행 업무로 재설계
__의존성 주입
__모두 합치기
____Go
____자바스크립트
____파이썬
__변경 사항 반영하기
__중간 점검
4부. 마무리 짓기
12장. 테스트 순서
__환율 변경
____Go
____자바스크립트
____파이썬
__변경 사항 반영하기
__중간 점검
13장. 지속적 통합
__핵심 개념
____버전 관리
____빌드 서버 및 에이전트
____아티팩트 저장소
____배포 환경
__모두 합치기
____깃허브 계정 생성
____깃허브 계정 인증
____코드 저장소를 깃허브에 푸시
____CI 빌드 스크립트 준비
____Go
____JavaScript
____Python
__변경 사항 반영하기
__중간 점검
14장. 회고
__프로필
____순환 복잡도
____결합도
____단순성
__목적
____응집도
____완전성
__프로세스
__모두 합치기
____Go
____자바스크립트
____파이썬
__TDD는 죽었다?
__중간 점검
부록 A. 개발 환경 구축
__온라인 REPL
____Repl.it
____LeetCode
____CoderPad
____Go 플레이그라운드
____온라인 REPL의 종합 목록
__통합 개발 환경
____비주얼 스튜디오 코드
____인텔리제이 IDEA
____이클립스
__언어 도구 설치하기
____Go
____자바스크립트/ES6
____파이썬
부록 B. 세 언어의 간략한 역사
__Go
__자바스크립트
____단언 모듈
____모듈 메커니즘
__파이썬
부록 C. 감사의 말
작가
살림 시디퀴 , 김인태
출판사리뷰
◈ 이 책에서 다루는 내용 ◈
◆ 도메인 복잡성을 제어하기 위한 테스트 주도 개발의 분할 정복 접근 방법 사용
◆ 언어, 테스팅 프레임워크, 도메인 개념을 아우르는 테스트 주도 개발 동작 방식 이해
◆ 테스트 주도 개발이 지속적 통합을 가능하게 하는 방식 학습
◆ 테스트 주도 개발을 바탕으로 리펙터링 및 재설계 지원
◆ 자바스크립트로 간단하고 효과적인 단위 테스트 하네스 작성 방법 학습
◆ 테스트 주도 개발 진행 중 만든 단위 테스트를 바탕으로 지속적 통합 환경 구축
◆ 테스트 주도 개발을 사용해 Go, 자바스크립트, 파이썬으로 깨끗하고, 깔끔한 코드 작성
◈ 이 책의 대상 독자 ◈
소프트웨어를 작성하는 개발자를 대상으로 한다.
‘개발자’에 어울리는 직함이 많다. 소프트웨어 엔지니어, 애플리케이션 아키텍트, 데브옵스 엔지니어, 자동화 테스트 엔지니어, 프로그래머, 해커, 코드 위스퍼러 등 직함은 셀 수도 없다. 개발자를 가리키는 직함은 인상적이거나 겸손하거나 유행을 타거나 근엄하거나 전통적이거나 현대적인 느낌이 있다. 다양한 직함 속 개발자들은 매일은 아니더라도 적어도 일주일의 어느 정도는 컴퓨터 앞에서 소스 코드를 읽고 쓰는 데 시간을 보낸다는 공통점이 있다. 그런 이유로 ‘개발자’라는 용어로 대상 독자를 특정했다.
코딩은 상상력을 동원할 수 있는 가장 자유롭고 평등한 활동이다. 이론적으로, 신체적 기량에서 ‘두뇌’만 있다면 필요한 모든 것이 준비된 셈이다. 나이, 성별, 국적, 출신 중 어느 것도 장애물이 돼서는 안 된다. 특히 신체적 장애는 장애물이 될 수 없다.
◈ 지은이의 말 ◈
우리는 말로 표현할 수 없을 만큼 운이 좋다. 우리는 수년간 테스트 주도 개발을 했다. 머큐리 우주 프로그램 코드를 작성한 개발자들이 펀치 카드로 테스트 주도 개발(Test-Driven Development, TDD)을 실천한 지도 수십 년이 지났다(https://oreil.ly/pKpSZ). 테스트 주도 개발적용을 수월하게 하는 XUnit 라이브러리는 세기를 거슬러 올라간다. 사실, 『테스트 주도 개발』(인사이트, 2014)을 저술하고 JUnit 프레임워크를 개발한 켄트 벡은 스스로 테스트 주도 개발의 실천(https://oreil.ly/zDyBr)을 발명이 아닌 ‘재발견’이라 말한다. 이 표현은 그의 겸손의 증거이면서도 사실이다. 테스트 주도 개발은 소프트웨어 개발만큼이나 오래됐다.
그렇다면 테스트 주도 개발이 표준 코드 작성 방식과 여전히 거리가 먼 이유는 무엇일까? 일정의 압박이 있을 때, 또는 IT 예산을 줄여야 할 때, 또는(개인적으로 가장 좋아하는) ‘소프트웨어 딜리버리 팀의 속도 향상’이 필요할 때 흔히 희생돼야 하는 첫 번째 대상이 테스트 주도 개발일까? 테스트 주도 개발은 결함 개수를 줄이고 설계를 더 간단하게 만들며 개발자 스스로가 갖는 코드에 대한 신뢰를 향상시키는 데 경험적이고 실험적인 증거가 있음에도 이런 모든 이유가 제시된다.
테스트 주도 개발이 마지못해 채택되거나 쉽게 버려지는 이유는 무엇일까? 테스트 주도 개발 실천을 꺼리는 이들이 주장은 크게 두 가지다.
첫째, 어디서부터 어떻게 시작해야 할지 모르겠다.
아마도 가장 흔한 이유는 인지도와 노출의 부족이다. 다른 기술과 같이, 테스트 주도 스타일의 코드 작성은 배워야 한다. 많은 개발자들은 이 기술을 배울 외적 동기(시간, 리소스, 지침, 격려)도 내적 동기(꺼리는 마음과 두려움 극복)도 없다.
둘째, 테스트 주도 개발은 토이 프로그램이나 인터뷰에서는 쓸 법하나 ‘실제 세계’ 코드 작성에는 제대로 작동하지 않는다.
사실이 아니지만 이해는 된다. 대부분의 테스트 주도 개발 튜토리얼과 이 책을 포함한 서적에서는 뻔한 도메인에서 비교적 간단한 예제를 선택하도록 강요한다. 상업적으로 배포된 애플리케이션(예: 금융 기관, 의료 관리 시스템, 자율주행자동차)에서 빼낸 소프트웨어 조각의 실제 코드를 바탕으로 테스트 주도 개발 기사나 책을 쓰기는 어렵다. 우선 한 가지 이유는, 실제 코드는 대부분 독점 소유권이 있으며 오픈 소스가 아니다. 다른 이유로는, 가장 많은 청중들에게 가장 폭넓은 관심을 가질 도메인의 코드를 보여주는 것은 저자의 역할이다. 고도로 전문적인 도메인의 문맥상에서 테스트 주도 개발을 보여주는 것은 애매함에 경계에 있어 비논리적이다. 그렇게 하려면 무엇보다 해당 도메인의 난해한 전문 용어와 은어들의 장황한 설명이 필요하다. 테스트 주도 개발을 이해하기 쉽고, 접근하기 쉬우며, 심지어 사랑스럽게 만들려는 저자의 의욕을 꺾게 될 것이다.
테스트 주도 개발 문헌에서 실제 세계 코드를 사용함에 있어 이런 장애물에도 불구하고, 개발자는 어김없이 테스트 주도 개발로 프로덕션 소프트웨어를 작성한다. 아마도 최고의 설득력 있는 예시는 JUnit 프레임워크(https://oreil.ly/UCPcg) 자체에 대한 단위 테스트 스위트일 것이다. 리눅스 커널(아마 세계에서 가장 활발히 사용되고 있는 소프트웨어 조각)은 단위 테스트를 바탕으로 개선되고 있다.
코드 작성부터 하고 테스트를 작성해도 충분하다. 테스트 주도 개발은 너무 제한적이고 현학적이다.
이 주장은 ‘단위 테스트는 지나치게 과대 평가됐다(https://oreil.ly/Y7S5M)’라고 가끔 큰소리치는 것을 듣는 것보다 더 신선하다! 프로덕션 코드를 작성한 후 작성하는 테스트는 아무런 테스트도 작성하지 않는 것보다는 낫다. 개발자가 자신의 코드에 신뢰를 높이고 우발적인 복잡성을 줄이며, 믿을 만한 문서를 제공하는 모든 일은 좋다. 다만, 단위 테스트를 프로덕션 코드를 작성하기 전에 작성하면, 임의의 복잡성의 발생을 예방하도록 강제하는 기능을 제공한다.
테스트 주도 개발은 다음 두 가지 실용적인 규칙을 방호책으로 제공해 더 간단한 설계를 할 수 있다.
1. 실패하는 테스트를 고치기 위해서만 프로덕션 코드를 작성하라.
2. 테스트가 그린일 때만 열성적으로 리팩터링하라.
우리가 작성하는 모든 코드를 자동으로 그리고 필연적으로 동작하는 가장 간단한 코드가 되도록 테스트 주도 개발이 보장하는가? 아니다. 그렇지 않다. 그렇게 할 수 있는 어떤 사례, 규칙, 책, 선언서는 없다. 단순성이 달성되고 유지되도록 이런 사례에 숨을 불어넣는 사람에게 달려 있다.
이 책은 테스트 주도 개발이 세 가지 다른 프로그래밍 언어에서 어떻게 작동하는지 설명하고 지도한다. 테스트 주도 개발을 꾸준히 연습하는 습관과 자신감을 심어주는 것이 목적이다. 야심에 찬 목적일 순 있지만 달성하기 힘들진 않기를 소망한다.
◈ 옮긴이의 말 ◈
여러 프로그래밍 언어로 소프트웨어를 개발하는 접근 방식인 폴리글랏 프로그래밍은, 다양한 언어의 장점을 활용해 보다 유연하고 최적의 성능과 확장성을 제공하는 소프트웨어 개발을 가능케 한다. 한 언어만 고수하는 소프트웨어 개발자가 아닌 이상 자의 또는 타의에 의해 여러 프로그래밍 언어를 접하게 되며, 자연스레 폴리글랏 프로그래밍을 하는 상황에 놓인다.
단위 테스트 코드 작성을 기본으로 하는 테스트 주도 개발 방식은, 소프트웨어가 테스트 가능한(Testable) 구조를 갖도록 강제하며, 이로 인해 보다 간단하면서도 구조화된 설계로 이끌어줄 뿐만 아니라 코드의 신뢰도를 높일 수 있는 효과적인 방법이다.
이 책에서는 개발자에게 사랑받는 Go, 자바스크립트, 파이썬의 세 가지 프로그래밍 언어로 테스트 주도 개발을 실천하는 실용적 방법을 제공한다. 켄트 벡의 저서 『테스트 주도 개발』(인사이트, 2014)에서 다룬 ‘돈 문제’ 예제를 각 언어로 재해석해 쉽고 재밌게 테스트 주도 개발 방식에 익숙해질 수 있도록 설명했다.
테스트 주도 개발은 지속적 통합 및 회귀 테스트를 자동화해 빠르고 정확하게 결함을 발견할 수 있게 하며, 켄트 벡이 얘기했듯이 소프트웨어 개발자 자신이 작성한 코드에 대한 두려움을 관리하는 데 효과적이다. 윤오영 작가의 수필 「방망이 깎던 노인」에서 방망이 장인이 질 좋은 방망이 하나를 깎아내는 데 노련하게 무던히 애를 쓰듯이, 소프트웨어 개발자 또한 품질 좋은 소프트웨어를 개발하기 위해 많은 수고를 아끼지 않는다. 테스트 주도 개발은 질 좋은 방망이와 같은 소프트웨어를 깎아내게끔 하는 정교하고 견고한 도구이기에 소프트웨어 개발자라면 반드시 경험하고 체득해야 한다고 생각한다.
시간은 좀 흘렀으나 2015년에 구글, 넷플릭스, 어도비 본사에 직접 방문한 적이 있다. 현업 개발자들로부터 이야기를 들을 기회가 있었는데, 각 회사의 소프트웨어 테스팅에 대한 인식과 노력은 정말 인상적이었다. 이후 여러 프로젝트에서 다양한 프로그래밍 언어(C/C++, Go, 파이썬, 코틀린, 자바)로 개발하며 테스트 주도 개발 및 단위 테스트에 계속 관심을 두게 됐다. 이 책을 통해 테스트 주도 개발의 가치를 이해하고 그 과정을 즐길 수 있기를 희망한다.