본문으로 건너뛰기

Specification by Example

책 [Specification by Exmaple(성공적인 프로젝트를 관통하는 핵심 실천법)]을 읽고 정리한 문서이다.

image-20250512151057028

핵심 이점

file.excalidraw (4)

올바른 제품을 효과적으로 만들기 위한 소프트웨어 개발 실천법에는 아래와 같은 사항들이 보장되어야 한다.

  • 이해관계자와 개발팀원 모두 제품 인도에 필요한 사항을 동일한 방식으로 이해한다.
  • 개발팀은 명확한 명세를 통해 모호함 및 기능상의 차이에 따른 불필요한 재작업을 하지 않는다.
  • 객관적인 수단을 통해 단위 작업이 완료된 시점을 측정한다.
  • 문서가 소프트웨어 기능과 팀 구조 측면 모두의 변화를 촉진한다.

전통적으로 올바른 제품을 만들기 위해 방대한 기능 명세, 문서화, 오랜 기간에 걸친 테스트 단계가 필요하다. 요즘과 같이 주 단위로 소프트웨어를 출시하는 시대에는 위와 같이 작업을 할 수 없어 아래와 같은 해결책이 필요하다.

  • 지나친 명세화를 피한다.
    • 실제 개발이 들어가지 전 변경될 지 모르는 세부 사항을 정의하는 데 시간을 허비하지 않는다.
  • 시스템이 수행하는 내용을 설명하는 신뢰할 만한 문서를 만든다.
    • 시스템을 쉽게 변경할 수 있다.
  • 명세에 정의된 대로 시스템이 실행되는지 효율적으로 점검한다.
  • 최소한의 유지보수 비용으로 문서를 적절하고 신뢰할 수 있게 유지한다.
  • 앞으로 수행해야 할 작업에 관한 정보를 적기에 공급할 수 있게 모든 것을 짧은 Iteration과 흐름 기반의 Process에 맞춘다.

file.excalidraw (5)

예제를 활용한 명제를 도입한 후 효과는 아래와 같다.

  • 변경 작업의 효율화: 시스템 기능에 대한 믿을 수 있는 정보의 원천인 Living Documentation을 통해 잠재적 변경이 미칠 영향을 분석하고 지식을 효과적으로 공유할 수 있다.
  • 제품 품질 개선: 시스템에 대한 기대를 명확하게 정의하고 검증 프로세스를 효율적으로 개선했다.
  • 재작업 감소: 명세를 중심으로 긴밀하게 협업하고, 시스템의 요구사항을 팀원 모두가 동일하게 이해할 수 있다.
  • 각 역할의 활동에 대한 효과적인 조율: 긴밀한 협업으로 제품 출시 흐름이 일정하게 진행됐다.

정리

  • 제품을 올바르게 만드는 것과 올바른 제품을 만드는 일은 서로 다른 일이다. 성공하기 위해 두 가지 모두 잘해야 한다.
  • 예제를 활용한 명세는 적기에 필요한 만큼의 문서만 제공한다. 짧은 이터레이션 혹은 흐름 기반의 개발 프로세스를 통해 올바른 제품이 만들어지는 데 이바지한다.
  • 예제를 활용한 명세는 소프트웨어 제품의 품질을 향상시키고 재작업을 현저히 줄이며, 개발팀의 분석, 개발, 테스트 활동을 원활하게 한다.
  • 장기적으로 예제를 활용한 명세는 Living Documentation System을 구축하는 데 기여한다. 프로그래밍 언어 코드가 변경될 때 그 기능에 대한 설명도 함께 변경되어 적절하고 신뢰할 수 있는 문서가 만들어진다.
  • 예제를 활용한 명세의 실천법은 짧은 이터레이션 기반 개발 방법이나 흐름 기반 개발 방법과 가장 잘 어울린다. 그러나 일부 아이디어는 RUP나 폭포수 모델과 같은 구조적인 개발 프로세스에도 적용할 수 있으며, 그 결과 많은 비용을 절감한 사례가 있다.

주요 프로세스 패턴

패턴: 이 책에서 소개하는 Proces Idea들은 다양한 팀에서 자주 발견된다는 의미에서 Pattern을 형성한다는 것이지 Christopher Alexander가 이야기한 Pattern과 다르다.

적절한 시기에 작업하기: 성공적인 팀에서는 한 번의 흐름으로 전체 명세를 구현하지 않는다. 프로젝트나 마일스톤의 초기 단계처럼 일할 수 있는 준비가 됐을 때 목표로부터 작업할 범위를 도출한다. 이터레이션의 시작과 같이 구현을 시작할 준비가 됐을 때만 해당 면세를 상세화한다.

file.excalidraw (6)

목표에서 범위 도출하기

구현 범위는 비즈니스 문제에 대한 해결책이나 비즈니스 목표에 도달하는 수단을 제공한다. 대다수의 팀에서는 구현이 시작되기 전에 고객, 제품 책임자, 사용자가 작업 범위를 결정해 주길 바란다.(소프트웨어 개발팀은 구현 전에 발생하는 모든 것을 대수롭지 않게 여기는 경향이 있다) 고객이 원하는 바를 정확하게 정의한 후에야 소프트웨어 개발팀은 그것을 개발한다. 위와 같은 방식으로 진행하면 올바른 제품을 구축하는 데 차질이 생긴다.

정리

  • 예제를 활용한 명세의 주요 프로세스 패턴으로 목표에서 범위 도출하기, 협업을 통해 명세 작성하기, 예제를 활용해 설명하기, 명세 정제하기, 명세의 변경 없이 검증 자동화하기, 자주 검증하기, Living Documentation 발전시키기가 있다.
  • 예제를 활용한 명세에서는 기능적 요구사항, 명세, 인수 테스트가 모두 같은 것이다.
  • 결과물은 Living Documentation System이다. Living Documentation System은 시스템이 무슨 일을 하는지 설명하며, 프로그래밍 언어 코드만큼 유의미하고 신뢰성 있을 뿐더러 훨씬 이해하기 쉽다.
  • 팀이 처한 상황이 다르면 프로세스 패턴을 구현하는 실천법도 다르다.

Living Documentation

정리

  • 예제를 호라용한 명세에는 몇 가지 모델이 있다. 각 모델은 각기 다른 용도에 유용하다.
  • 예제를 활용한 명세를 활용하면 유용한 문서화 시스템을 점진적으로 구축할 수 있다.
  • Living Documentation은 개발 프로세스에서 소스코드만큼 중요한 산출물이다.
  • 비즈니스 프로세스 문서 시스템을 만드는 데 초점을 두면 명세와 테스트를 장기간 유지보수하는 과정에서 가장 흔히 발생하는 문제를 예방하는 데 도움이 된다.

변화의 시작

정리

  • 예제를 활용한 명세는 명세를 적기에 공급하는 좋은 방법이고 짧은 이터레이션이나 흐름 기반 개발의 성공을 위한 핵심 요소이다.
  • 자그마한 소프트웨어 조각들을 효율적으로 다뤄 빠른 처리 시간과 피드백을 이끌어낸다.
  • 길고 지루한 문서보다 효과적이고 효율적인 의사소통을 강조한다.
  • 올바른 시스템 명세를 작성하려면 테스터, 분석가, 개발자가 함께 일할 수 있는 연합팀을 만들어야 한다.
  • 프로젝트 초기에 자동화 비용을 계획에 반영한다.

목표에서 범위 도출하기

정리

  • 요구사항을 받았다면 일단 작업을 미뤄두고 실제 문제를 이해하는 데 필요한 정보를 모으고 협력적으로 해결책을 설계한다.
  • 작업을 피할 수 없다면 어떻게 그것들이 유용한지에 대한 상위 수준의 예제를 요청한다. 그렇게 될 경우 누가, 왜 그것을 필요로 하는지 이해할 수 있게 되어 그에 대한 해결책을 만들 수 있다.
  • 적절한 범위를 도출하려면 마일스톤의 비즈니스 목표와 마일스톤에 기여하거나 영향을 받을 이해관계자를 고려한다.
  • 비즈니스 사용자가 더 관심을 갖는 비즈니스 결과부터 시작한다.
  • 개발팀이 완결성 있는 기능 단위로 개발할 수 있게 팀을 재구성한다.
  • 목표에서 범위를 효과적으로 도출하기 위해 기능 주입, 사용자 스토리 매핑, 효과 매핑을 비롯한 최신 기법을 조사한다.

협업을 통해 명세 만들기

정리

  • 예제를 활용한 명세는 비즈니스 사용자와 개발팀원의 협업이 잘 되느냐에 전적으로 달렸다.
  • 개발 팀의 모든 구성원은 올바른 명세에 대한 책임감을 지녀야 한다. 개발자와 테스터는 기술적 구현과 검증 관점에 대한 정보를 제공해야 한다.
  • 대부분의 팀은 명세에 대한 협업을 2단계로 나눠서 진행한다. 누군가 기능에 대한 초기 예제를 사전에 준비한 후 해당 기능과 관련된 사람들이 기능에 대해 토론함으로써 명세를 명확하고 완전하게 만들 예제를 추가한다.
  • 준비 과정의 작업량과 협업 과정에서의 작업량 간 균형은 제품의 성숙도, 개발팀의 도메인 지식 수준, 일반적인 변경 요청의 복잡도, 프로세스 병목, 비즈니스 사용자의 가용성과 같은 요소에 달려 있다.

예제를 활용해 설명하기

정리

  • 개발과 테스트에 일관되게 명세를 설명하는 공통의 예제를 사용할 수 있다면 무엇을 만들어야 하는가에 대해 모든 사람들이 똑같이 이해하게 될 것이다.
  • 기능을 설명하는 데 사용되는 예제는 명확하고 완전해야 하며, 현실적이고 이해하기도 쉬워야 한다.
  • 현실적인 예제를 이용하려면 불일치와 기능 차이를 구현하기 전에 발견할 수 있다.
  • 초기 예제를 만들면 데이터로 실험해보고 기능이 명세를 만족하는지 테스트할 수 있는 대안을 찾아야 한다.
  • 예제가 너무 복잡하고 많거나, 너무 많은 요소가 나타난다면 놓치고 있는 개념을 찾아보고 좀 더 추상적인 수준에서 예제를 해석해야 한다. 그리고 새로운 개념을 개별적으로 설명할 때는 각 개념에 초점을 맞춘 예제를 사용한다.

명세 정제하기

Given-When-Then

정리

  • 처음 만든 예제를 그대로 쓰지 마라. 그러한 예제로부터 명세를 정제하라.
  • 예제를 최대한 활용하려면 결과 명세가 엄밀하고 테스트할 수 있어야 한다. 또한 부연 설명이 필요 없을 만큼 자명하고 초점이 분명해야 한다. 도메인 언어로 기술되고 비즈니스 기능에 대해 설명해야 한다.
  • 명세가 스크립트가 되지 않게 하고 소프트웨어 설계에 대해 설명하지 않게 하라.
  • 모든 개별적인 상황을 다루려고 하지 마라. 명세는 모든 조합에 대한 회귀 테스트의 대체재가 아니다.
  • 각각의 중요한 상황에 대한 예제로 시작한 후 개발자나 테스터가 관심을 둘 만한 특별한 상황을 설명하는 예제를 추가하라.
  • 유비쿼터스 언어를 사용해 명세, 소프트웨어 설계, 테스트를 정의하라.

명세의 변경 없이 검증 자동화하기

정리

  • 정제된 명세는 가능한 한 변경을 통해 자동화돼야 한다.
  • 자동화 계층에서는 뭔가를 어떻게 테스트할 것인가를 정의하고 명세에서는 무엇을 테스트 할 것인지 정의해야 한다.
  • 자동화 계층에서는 뭔가 어떻게 테스트하는 가를 정의해야 하고, 명세에서는 무엇을 테스트해야 하는가를 정의해야 한다.
  • 가능하다면 사용자 인터페이스 내부를 자동화하라.
  • 될 수 있으면 기존 데이터에 과도하게 의존하지 마라.

자주 검증하기

정리

  • 실행 가능한 명세를 자주 검증해서 신뢰성을 높인다.
  • 단위 테스트와 지속적인 통합에 비해 지속적인 금증을 위한 두 가지 과제는 빠른 피드백과 안정성이다.
  • 지속적인 검증을 위해 격리된 환경을 준비하고 더 신뢰할 수 있게 배포를 완전히 자동화한다.
  • 피드백을 더 빨리 얻을 수 있는 방법을 찾아라. 빠르고 느린 테스트를 분리하고, 현재 이터레이션에 대한 명세 팩을 만들고, 오랫동안 실행되는 실행 가능한 명세 팩을 더 작은 팩으로 나눈다.
  • 실패하는 테스트를 그냥 비활성화해서는 안 된다. 문제를 해결하거나 철저하게 모니터링 할 수 있는 우선순위가 낮은 회기 이슈에 대한 팩으로 테스트를 옮긴다.

문서 시스템 발전시키기

정리

  • Living Documentation System을 최대한 활용하기 위해 일관성을 유지하고 각각의 실행 가능한 명세에 비즈니스 사용자를 포함한 모든 사람들이 손쉽게 접근하고 실행 가능한 명세를 쉽게 이해할 수 있어야 한다.
  • 유비쿼터스 언어를 발전시키고 일관되게 사용한다.
  • 시스템이 발전해 나감에 따라 긴 명세나 사소한 변경과 같은 것을 설명하는 다수의 작은 명세에서 유의한다. 이러한 것을 쉽게 설명하는 최상위 추상화 개념을 찾는다.
  • Living Document System을 체계적으로 구성해서 현재 이터레이션에 대한 모든 명세뿐 아니라 이전 구현된 기능도 쉽게 찾을 수 있게 한다.

사례연구

결론

요구사항에 대한 협업은 이해관계자와 개발팀원 간의 신뢰를 쌓이게 한다

협업은 준비가 필요하다

협업하는 방법에는 여러 가지가 있다

최종 목표를 비즈니스 프로세스 문서화로 하는 것은 유용한 모델이다

장기적 가치는 Living Documentation에서 나온다