본문 바로가기

카테고리 없음

애자일 개발의 기술 2/e - 개발

제로 프릭션

개발 속도는 마찰(friction)을 제거하는 데 있어 가장 중요한 영역이다. 여러분이 무언가를 변경한다면 5초 이내에 해당 변경에 관한 피드백을 받을 수 있어야 한다. 1초 이내라면 최고다. 아무리 늦더라도 10초 이내에 피드백을 받아야 한다. 이는 매우 쉽게 실험하고 이터레이션할 수 있음을 의미한다.

1초 피드백을 위해 하나는 빠른 피드백을 위한 빌드, 다른 하나는 프로덕션 배포를 위한 빌드다. 로컬 빌드가 프로덕션 빌드와 동일한 것이 바람직하지만, 빠른 피드백이 훨씬 중요하다. 코드 베이스가 커지면 테스트가 너무 많아져 1초 이내에 모두 실행할 수 없게 된다. 이런 때는 하위 테스트 집합만 실행되도록 수정해야 한다.

5분 통합

CI를 활용하면 하루에도 수 차례씩 통합을 진행할 것이다. 이 프로세스는 튼튼하고 빨라야 한다. 이는 5분 안에 결과를 받아야 한다. 5분은 커피를 마시고 스트레칭하기 좋은 시간이다 10분은 너무 길다.

모든 것을 자동화하라

  1. build: 컴파일 및 테스트 수행
  2. watch: 파일이 변경될 때 자동으로 build 실행
  3. integrate: 프로덕션과 유사한 환경에서 build를 실행하고 코드를 통합
  4. deploy: integrate를 실행하고 통합 브랜치를 배포
  5. rundev: 수동 리뷰와 테스트를 위해 소프트웨어을 로컬에서 실행

지속적인 통합(Continous Integration)

지속적인 통합의 궁극적인 목표를 릴리스를 기술적인 관점이 아니라 비즈니스 관점의 의사 결정으로 만ㄷ는 것이다. 현장 고객이 릴리스할 준비가 되면 개발자는 버튼을 누르고 릴리스한다. 지속적인 통합은 집단 코드 오너십과 리팩토링을 위해 필수적이다.

지속적인 통합은 도구가 아니라 프랙티스다. CI 서버는 CI의 극히 일부만 담당한다. CI 서버는 시그널을 받아 코드를 빌드하고 병합한다. CI는 팀의 최신 작업 결과물을 언제든 릴리스할 수 있는 능력에 관한 것이다.

지속적인 통합을 자주 하는 것은 고통스러운 병합 과정의 리스크를 줄인다.

통합 브랜치는 릴리스할 수 있는 상태로 유지해야 한다.

다단계 통합 빌드

  • First Stage: 소프트웨어가 동작하는 것을 입증하기 위해 필요한 컴파일, 유닛 테스트, 간단한 스모크 테스트 후 병합
  • Second Stage: 조금 더 느린 성능 테스트, 부하 테스트, 안정성 테스트에 이은 스테이징, 프로덕션 배포

풀 리퀘스트와 코드 리뷰

PR은 CI에서는 적합하지 않다. 너무 느리기 때문이다. PR은 대게 1~2일이 걸리는데 이는 병합 충돌이 일어날 가능성이 높다. 대신 페어링과 모빙을 통해 코드 리뷰의 필요성을 제거하라. 코드 리뷰를 유지하기 원한다면 통합을 위한 게이트가 아니라 통합한 후에 리뷰를 수행하라.

PR은 CI를 이용하는 팀에서는 적절한 효과를 얻을 수 없지만, 오너십을 공유하지 않는 팀 사이에서의 조정 메커니즘으로서는 여전히 그 역할을 할 수 있다.

테스트 주도 개발

프로그래밍 언어에 정말로 필요한 것은 "내가 말한 대로가 아니라 내가 의미한 대로 하라" 이다.

이를 한번에 실천할 수 있는게 TDD이다. 현대 개발 환경이 여러분이 코드를 작성할 때 구문에 대한 피드백을 제공하는 것처럼, TDD는 여러분이 작성하는 코드의 의미에 대한 피드백을 제공한다. 또한, 작업을 마치면 테스트 코드가 남고 의도대로 동작하는 코드에 대한 살아있는 문서 역할을 한다.

단계
1.생각하기: 어떻게 코드가 동작하길 원하는지 상상하라.
2.빨간색 막대: 인터페이스 관점에서 테스트를 작성한다. 구현자가 아닌 사용자 관점에서 인터페이스를 디자인하게 된다.
3.녹색 막대: 테스트를 통과할만큼 코드를 작성하라.
4.리팩터: 테스트가 통과하면 마음대로 리팩토링하라.
5.이터레이션: 새로운 동작을 추가할 땐 위 과정을 이터레이션하라.

빠르고 신뢰할 수 있는 테스트

넓은 범위의 테스트는 소프트웨어의 많은 부분을 다루기 위해 작성한다. 예를 들어 웹 브라우저를 실행하거나, 버튼을 클릭하고 데이터를 입력한 뒤 브라우저가 기대했던 결과를 보여주는지 확인하는 것이다. 이는 테스트 커버리지를 높이기에 좋아 보이지만 이는 함정이다. 넓은 테스트는 느리고 불안정하다.

좁은 범위의 테스트는 소량의 코드에 집중한다. 하나의 모듈이나 클래스 안에 존재하는 여러 개의 메소드를 테스트한다. 보통 '단위 테스트'라고 불리며 빠르고 결정적이다.

사교적 유닛 테스트를 작성하라. 좁은 범위의 사교적 유닛 테스트는 의존성을 교체하지 않고 테스트한다. 이는 모두 테스트 더블로 대체된 외로운 유닛 테스트가 아닌 실제로 동작하는 것을 확인한다. 이는 기대대로 동작함을 충분히 확인할 수 있는 빠른 테스트가 만들어진다.

넓은 범위의 테스트는 일반적인 시나리오만 테스트하게 작성한다.

스파이크 솔루션

스파이크는 기술적인 조사다. 코드 상의 문제의 답을 확인하기 위한 솔루션이며 확인되면 스파이크는 폐기된다. 서드 파티 디펜던시는 작은 stand-alone 프로그램을 만들어 어떤지 조사한다. 디자인 개선에 관한 아이디어가 실제로 작동할 지 확신할 수 없다면 이를 활용한다.

프로토타입과 다른점은 프로토타입은 최종 제품을 모방하도록 만든 불완전한 소프트웨어이지만, 스파이크는 이보다 한 층 더 집중적이다.