★ 이 책에서 다루는 내용 ★
■ 전체 코드의 단위 테스팅 단순화, 통합 테스팅 및 시스템 테스팅 개선
■ 의도와 구현을 구분한 테스팅의 신뢰성 및 확장성 향상
■ 테스트 작성법에 대한 혼란과 오해 정복
■ 부작용, 동작 특성, 상황적 제약 조건의 테스트
■ 설계와 테스트 용이성 간 절묘한 상호작용 이해
■ 주요 테스팅 결정을 이끄는 핵심 원칙 발견
■ 획득자/설정자, 문자열 처리, 캡슐화, 오버라이딩 변형, 노출도, 싱글턴 패턴, 에러 조건 등의 테스팅 탐구
■ 복잡한 경쟁 상태의 확정적 재현 및 테스트
★ 이 책의 대상 독자 ★
이 책은 전문 소프트웨어 개발자 또는 코드 품질을 향상하기 위해 코드 수준의 테스팅 실력을 높이려는 소프트웨어 개발자를 위한 책이다. 처음부터 코드의 정확성을 보증하고자 하는 테스트 주도 개발 및 조기 테스트 실무자에게 특히 유용할 것이다. 이 책에 나오는 기법은 대부분 통합 테스팅 혹은 시스템 테스팅에도 적용 가능하다.
★ 이 책의 구성 ★
1부, ‘테스팅의 원칙과 실제’에서는 테스팅을 성공적으로 이끄는 원칙과 실제를 다룬다. 1장에서는 이 책의 접근법을 공학의 컨텍스트에 두고, 공학, 장인정신, 최초 품질 및 소프트웨어 특유의 문제에 관해 논의한다. 2장에서는 의도의 역할에 대해 검토한다. 3장에서는 하나의 요소에 집중할 수 있게 해주는 테스팅 방법의 윤곽을 보여준다. 4장에서는 테스트하는 수고를 줄이는 몇 가지 방안을 비롯해, 설계와 테스트 용이성 간의 상호 영향을 논의한다. 5장에서는 테스트에 대한 의사 결정을 도울 만한 여러 테스팅 원칙을 제시한다.
2부, ‘테스팅과 테스트 용이성 패턴’에서는 테스팅을 위한 구현 패턴을 자세히 다룬다. 먼저 6장에서 테스트를 부트스트랩(bootstrap)하고 기법들의 기본 목록을 서술한다. 6장에서 소개한 주제를 7장부터 12장에 걸쳐 더 구체적으로 살펴본다. 9장에서는 코드의 의도에 관해 더 깊이 살펴보며 중간 정리를 한다. 13장에서는 많은 이들이 불가능하다고 여기는 일에 기술적으로 깊이 파고들어, 확정적으로(deterministically) 경쟁 상태(race condition)를 재현하는 기법들을 소개한다.
3부, ‘실제 사례’에서는 이 책에서 다룬 원칙과 기법들을 적용한 실제 사례 두 가지를 서술한다. 14장에서는 테스트 주도 개발을 통해 처음부터 자바 애플리케이션을 만드는 과정을 살펴보며, 어떻게 시작하고 어떻게 타입에 엄격한 언어에 기법을 적용하는지 설명한다. 15장에서는 테스트되지 않은 오픈소스 자바스크립트 제이쿼리(jQuery) 플러그인을 테스트하도록 가져오면서 동적 언어로 된 레거시(legacy) 코드를 다루는 방법을 설명한다. 두 사례 모두 상세한 깃허브(GitHub) 커밋 이력에 대한 참조 번호까지 함께 보여준다.
★ 지은이의 말 ★
린 생산(Lean production)은 지난 수십 년에 걸쳐 제조업 분야에 혁신을 일으켰다. 종합적 품질 경영(TQM, Total Quality Management)이나 적시 생산(Just-in-time), 제약이론(Theory of Constraints), 토요타 생산 시스템 같은 프레임워크를 통해 전반적인 자동차 및 제조 품질의 상태를 크게 개선하고 핵심적인 경쟁 구도를 낳았다. 애자일 소프트웨어 개발과 같은 접근법은 린 생산 원리를 지식 분야인 소프트웨어 제품 개발에 가져왔지만, 원리를 기계적이지 않은 컨텍스트에 맞춰 조정해야 한다.
품질을 제품의 일부로 포함해 고객 만족을 높이고 총 유지 보수 비용을 줄이려는 아이디어는 테스트 주도 개발(TDD, Test-Driven Development), 우선 테스트(test-first) 및 조기 테스트(test-early) 방식 등으로 이어졌다. 어떤 취향을 지지하든 간에, 테스트 용이한 소프트웨어가 어떻게 생겼는지 이해하고 테스트를 성공적으로 구현하기 위해 다양한 기법을 충분히 익혀야 한다. 나는 원칙과 실제의 괴리가 테스팅 실패의 숨은 원인임을 깨달았다. “테스트 주도 개발을 해봐.”라고 말하기는 쉽지만, 막상 프로젝트를 마주하면 무엇부터 할지 막막한 개발자가 다수다.
사람들에게 테스트 주도 개발 혹은 최소한 조기 테스트 개발을 적용하는 법을 알려주면서 흔히 겪는 난관 중 하나가 테스트 작성법이다. 수학 함수처럼 입력을 사용하기 편한 출력으로 바꾸기만 하는 메소드를 시행(試行)하는 데는 아무 문제가 없다. 하지만 테스트하기 쉽지 않은 부가 효과나 동작 특성, 상황에 따른 제약 조건을 갖는 소프트웨어가 많다.
이 책은 개발자들에게 걸림돌이 되는 구체적인 상황을 어떻게 테스트하는지 거듭 알려달라는 요구에서 비롯됐다. 꾸준히, 몇 분 정도 차분히 자리잡고 앉아서 골칫거리인 코드에 대한 단위 테스트를 작성한다면, 여러분은 새로운 도구를 갖추게 될 것이다.
★ 옮긴이의 말 ★
테스트는 중요한 자산이다. 테스트가 차곡차곡 쌓여갈수록, 소프트웨어의 품질과 개발자들의 유산도 함께 쌓인다. 테스트 베이스의 크기와 수준만 봐도 그 회사와 제품을 어느 정도 신뢰할지 결정할 수 있다. 하지만 대다수의 개발자는 하기 귀찮은 일로 문서 작성과 테스트를 꼽는다. 어떤 일이든 사람들이 하기 귀찮아 하는 경우는 들어가는 노력에 비해 얻는 것이 적거나 일이 불편하고 까다로운 경우이다.
테스트를 통해 얻는 것은 분명하다. 소프트웨어의 품질. 품질이라는 압축된 용어를 굳이 쓰지 않더라도, 실무자는 개발할 때 테스트의 중요성을 체감한다. 테스트가 없이는 이미 출시한 제품의 수정이 불가능하다. 버그 없는 소프트웨어는 없지만, 적어도 테스트가 커버하는 범위 내의 동작이 이전과 동일함을 보일 수는 있다. 탄탄한 테스트 베이스가 있으면 개발자는 제품이 새로 수정한 부분 때문에 다른 기존 동작이 바뀌는지 걱정할 필요 없이 마음 놓고 작업할 수 있다. 문제는 테스트를 작성하는 일 자체가 불편하고 까다롭다는 데 있다. 생각해보면 우리는 테스트하라는 말만 들었을 뿐, 슬기롭게 테스트하는 방법을 배우고 익힌 적이 없다. 직접 시행착오를 겪고 나서야 겨우 테스팅 관련 자료나 서적을 찾아보지만 실제 상황과 맞는 내용을 찾기도 쉽지 않다.
이 책은 소프트웨어 테스팅의 기본 원칙부터 테스트를 수월하게 작성하는 실제적인 기법들을 풍부한 예시와 함께 전해준다. 저자는 또한 소프트웨어를 설계할 때부터 테스팅을 염두에 두어야 함을 역설하고 좋은 설계안을 추천하고 있다. 이에 깊이 공감하며, 유지보수를 위해 코드의 가독성이 점점 중요한 요소가 됐듯이 테스트 용이성도 소프트웨어 개발에서 더욱 중요한 요소로 자리매김해야 할 것이라 생각한다. 원서가 출간되어 번역을 맡은 시점부터 출판 시점까지 3년이 넘는 시간이 흘렀지만, 이 책의 가치가 전혀 퇴색하지 않았다는 생각이 든다. 이 책이 시류에 편승하는 내용이 아니라 근본 원칙과 기본기를 담고 있음을 방증한다. 저자의 의도를 올바로 전달하려 노력했으나, 부족한 부분은 고스란히 역자의 책임이다. 질책과 더불어 독자 분들의 많은 제의를 부탁드린다.