Conway's Law가 테스팅에 미치는 영향
"우리의 테스트 코드는 왜 이렇게 복잡해졌을까요?"
이 질문의 답은 코드베이스에만 있지 않습니다. 1968년 멜빈 콘웨이가 제시한 바와 같이 "조직의 커뮤니케이션 구조는 시스템 설계에 반영된다"는 원리는, 분산 시스템 시대의 테스트 아키텍처에도 그대로 투영됩니다. 팀이 기능 라인별로 갈라지면 테스트 리포지토리도 분화되고, 의사소통 경계가 많을수록 인터페이스 테스트의 부담이 커집니다.
실제로 한 스타트업의 사례를 보면 이 법칙이 얼마나 정확한지 알 수 있습니다. 프론트엔드 팀이 3개로 나뉘어 있었고, 놀랍게도 테스트 리포지토리도 정확히 3개였습니다. 더 흥미로운 것은 각 팀이 선호하는 프레임워크가 달랐다는 점입니다. 첫 번째 팀은 Cypress를 사용했고, 두 번째 팀은 Playwright를 선택했으며, 세 번째 팀은 여전히 Selenium을 고수하고 있었습니다. 이는 단순한 기술 선택의 문제가 아니었습니다. 각 팀의 문화와 의사결정 구조가 도구 선택에까지 영향을 미친 것입니다.
마이크로서비스 전환이 가속화되며 품질 보증의 기본 단위도 커다란 "제품"이 아니라 작은 서비스 경계가 되었습니다. Netflix의 Full Cycle Developer, Spotify의 Squad 및 길드, Amazon의 Two-Pizza Teams는 모두 팀 경계와 소프트웨어 경계의 정렬을 통해 품질 책임을 분산하고 내재화하는 조직적 장치입니다.
하지만 여기서 주의해야 할 점이 있습니다. 많은 조직이 이러한 성공 사례를 그대로 복사하려 합니다. 그러나 Conway's Law가 말해주듯, 조직의 고유한 문화와 구조를 무시한 채 다른 회사의 모델을 이식하는 것은 실패로 이어질 수밖에 없습니다. 중요한 것은 원칙을 이해하고 자신의 조직에 맞게 적용하는 것입니다.
핵심은 명확합니다. 테스트 복잡도는 코드 복잡도만의 함수가 아닙니다. 조직의 대화 경계가 곧 테스트 경계입니다. 그리고 이 경계를 의식적으로 설계하지 않으면, 테스트 아키텍처는 조직의 비효율성을 그대로 반영하게 됩니다.
모놀리식 QA는 중앙 QA가 하나의 통합 환경에서 전 기능을 승인하는 모델입니다. 이 모델은 소프트웨어가 단일 배포 단위였던 시절에는 합리적이었습니다. 모든 기능이 함께 테스트되고, 함께 배포되며, 함께 롤백되었습니다. QA 팀은 제품의 전체적인 품질을 책임지는 수호자 역할을 했습니다.
그러나 마이크로서비스 환경에서는 이 구조가 심각한 병목을 만들어냅니다. 첫째, 대기 병목입니다. 12개의 서비스 팀이 있다면, 각 팀은 중앙 QA의 검증을 받기 위해 평균 2~3일을 기다려야 합니다. 이는 단순 산술로도 월 40~60일의 대기 시간을 의미합니다. 실제로 한 핀테크 기업은 이러한 대기 시간 때문에 경쟁사 대비 기능 출시가 평균 3주 늦어졌다고 보고했습니다.
둘째, 지식 병목입니다. 중앙 QA 팀이 결제, 사용자 관리, 추천 시스템, 데이터 분석 등 모든 도메인의 전문 지식을 갖추는 것은 현실적으로 불가능합니다. 결과적으로 테스트는 표면적인 기능 검증에 그치게 되고, 도메인 특화된 엣지 케이스나 비즈니스 로직의 미묘한 부분은 놓치게 됩니다. 한 이커머스 기업에서는 QA 팀이 복잡한 프로모션 로직을 완전히 이해하지 못해, 블랙프라이데이 당일 가격 계산 오류로 수백만 원의 손실을 입었습니다.
셋째, 환경 병목입니다. "유일한" 통합 환경은 곧 단일 실패 지점이 됩니다. 한 서비스의 불안정한 배포가 전체 테스트 환경을 마비시킬 수 있습니다. 더 심각한 것은 데이터 오염입니다. 여러 팀이 동일한 테스트 데이터를 사용하면서 서로의 테스트를 방해하게 됩니다. 실제로 한 금융 서비스 기업은 통합 환경의 데이터 충돌로 인해 주당 평균 15시간의 테스트 실패를 경험했습니다.
이러한 병목현상은 단순히 프로세스의 문제가 아닙니다. Conway's Law가 작동하는 결과입니다. 중앙집중식 QA 조직은 중앙집중식 테스트 아키텍처를 만들어내고, 이는 분산 시스템의 본질과 근본적으로 충돌합니다.
병목현상을 해소하기 위한 전환은 급진적이어서는 안 됩니다. 체계적이고 단계적인 접근이 필요합니다.
1단계: 승인 권한의 점진적 분산 (3~6개월)
먼저 리스크가 낮은 서비스부터 시작합니다. 내부 도구나 관리자 페이지 같은 영역에서 서비스 팀에 품질 승인 권한을 부여합니다. 이때 중요한 것은 명확한 품질 기준을 먼저 수립하는 것입니다. 코드 커버리지 80% 이상, 성능 테스트 통과, 보안 스캔 완료 등의 객관적 지표를 설정합니다.
동시에 "품질 체크포인트"를 도입합니다. 서비스 팀이 자체 승인을 하되, 주요 마일스톤에서는 중앙 QA의 리뷰를 받도록 합니다. 이는 완전한 자율로 가기 전의 안전장치 역할을 합니다. 한 결제 서비스 기업은 이 방식으로 전환하여, 첫 3개월 동안 배포 빈도를 주 1회에서 일 2회로 늘리면서도 장애율을 5% 감소시켰습니다.
2단계: 검증 단위의 세분화 (6~9개월)
E2E 테스트 의존도를 체계적으로 줄여갑니다. 먼저 현재 E2E 테스트 스위트를 분석하여, 실제로 통합이 필요한 시나리오와 단위 서비스에서 검증 가능한 시나리오를 구분합니다. 경험적으로 E2E 테스트의 60~70%는 계약 테스트나 컴포넌트 테스트로 대체 가능합니다.
계약 테스트 도입은 서비스 간 의존성이 높은 곳부터 시작합니다. 결제 서비스와 주문 서비스 간의 인터페이스를 계약으로 정의하고, 양쪽에서 독립적으로 검증합니다. 이를 통해 통합 테스트 없이도 호환성을 보장할 수 있습니다. 실제로 한 물류 플랫폼은 계약 테스트 도입 후 통합 테스트 실행 시간을 8시간에서 45분으로 단축했습니다.
3단계: 환경의 연방제 구축 (9~12개월)
통합 환경을 없애는 것이 아니라, 다층 구조로 전환합니다. 각 서비스는 자체 개발 환경을 가지고, 팀 단위로 통합 환경을 운영하며, 전사 차원의 스테이징 환경을 유지합니다. 이때 중요한 것은 환경 간 프로모션 자동화입니다. 서비스가 팀 환경에서 검증되면 자동으로 스테이징으로 프로모션되는 파이프라인을 구축합니다.
환경 연방제의 핵심은 "격리와 통합의 균형"입니다. 개발 속도를 위해서는 격리가 필요하지만, 전체 시스템의 건강성을 위해서는 통합이 필요합니다. 이 균형점을 찾는 것이 성공의 열쇠입니다.
4단계: 릴리즈 체크리스트의 자동화 (지속적)
수동 체크리스트를 정책 코드로 전환합니다. 계약 준수 여부, 에러버짓 잔량, 런북 존재 여부, 롤백 계획 검증 등을 자동으로 확인하는 "릴리즈 게이트"를 구현합니다. 이는 Policy as Code 접근법으로, 품질 기준을 주관적 판단이 아닌 객관적 규칙으로 만듭니다.
모놀리식 QA의 한계를 극복하려다 실패한 사례들도 많습니다. 한 스타트업은 QA 팀을 하루아침에 해체하고 모든 책임을 개발팀에 넘겼습니다. 결과는 참담했습니다. 3개월 만에 프로덕션 장애가 500% 증가했고, 고객 이탈률이 30% 상승했습니다.
무엇이 문제였을까요?
첫째, 준비 없는 전환이었습니다. 개발팀은 테스트 작성 경험이 부족했고, 품질에 대한 책임 의식도 낮았습니다.
둘째, 지원 체계가 없었습니다. QA 팀이 사라지면서 테스트 인프라, 도구, 노하우도 함께 사라졌습니다.
셋째, 품질 기준이 모호했습니다. 각 팀이 자의적으로 품질을 정의하면서 전사적 품질이 급락했습니다.
이 사례가 주는 교훈은 명확합니다. 모놀리식 QA의 한계를 인식하는 것과 성급하게 해체하는 것은 전혀 다른 문제입니다. 전환은 체계적이고 점진적이어야 하며, 무엇보다 조직의 준비도를 고려해야 합니다. 변화는 기술이 아니라 사람에서 시작됩니다.
조직을 바꾸지 않고 아키텍처만 바꾸면 품질은 이중 부조화에 빠집니다. 이를 해소하기 위한 접근이 Inverse Conway Maneuver(ICM)입니다. ICM은 단순히 "원하는 아키텍처에 맞춰 조직을 재설계하라"는 구호가 아닙니다. 구체적이고 실천 가능한 방법론입니다.
먼저 목표 아키텍처를 명확히 정의해야 합니다. "독립적으로 배포 가능한 10개의 마이크로서비스"라는 목표가 있다면, 조직도 10개의 자율적인 팀으로 구성되어야 합니다. 각 팀은 자신의 서비스에 대한 완전한 권한과 책임을 가져야 합니다. 이는 개발, 테스트, 배포, 운영, 모니터링을 모두 포함합니다.
Amazon의 "You build it, you run it" 철학은 ICM의 대표적 성공 사례입니다. 그들은 서비스 경계를 먼저 정의하고, 그에 맞춰 팀을 구성했습니다. 각 팀은 6~10명의 "Two-Pizza Team"으로 제한되었습니다. 이는 의사소통 오버헤드를 줄이고, 빠른 의사결정을 가능하게 했습니다. 결과적으로 각 서비스는 팀의 성격을 반영하게 되었고, 이는 더 나은 설계로 이어졌습니다.
하지만 ICM이 항상 순조롭게 진행되는 것은 아닙니다. 기존 조직 구조의 관성, 정치적 저항, 문화적 충돌 등 많은 장애물이 있습니다. 한 대기업은 ICM을 시도했지만, 중간 관리자들의 저항으로 실패했습니다. 팀 자율성이 높아지면서 그들의 역할이 축소될 것을 우려했기 때문입니다.
성공적인 ICM을 위해서는 단계적 접근이 필요합니다. 먼저 파일럿 팀을 구성하여 새로운 구조를 실험합니다. 성공 사례를 만들고, 이를 전파합니다. 동시에 중간 관리자들의 역할을 재정의합니다. 그들은 더 이상 통제자가 아니라 조력자가 되어야 합니다. 팀 간 조정, 장애물 제거, 리소스 확보 등 새로운 가치를 창출해야 합니다.
중앙 QA에서 품질 플랫폼 팀으로의 전환
중앙 QA 팀은 사라지는 것이 아니라 역할이 진화합니다. 그들은 이제 "품질 플랫폼 팀"이 되어 새로운 책임을 집니다.
첫째, 테스트 실행 인프라를 제공합니다. 이는 단순한 CI/CD 파이프라인이 아닙니다. 병렬 실행, 플레이키 테스트 감지, 테스트 영향 분석, 지능형 테스트 선택 등 고급 기능을 포함합니다. 코드 변경이 어떤 테스트에 영향을 미치는지 자동으로 분석하여, 필요한 테스트만 실행하는 "Test Impact Analysis" 시스템을 구축합니다. 한 대형 이커머스 기업은 이 방식으로 테스트 실행 시간을 평균 45분에서 12분으로 단축했습니다.
둘째, 품질 메트릭스 대시보드를 운영합니다. 각 서비스의 품질 지표를 실시간으로 수집하고 시각화합니다. 이는 단순한 모니터링이 아니라, 품질 트렌드 분석, 이상 징후 감지, 예측 모델링을 포함합니다. 한 팀의 품질이 급락하면 자동으로 알림이 가고, 필요시 지원을 제공합니다. 품질 저하의 조기 경보 시스템 역할을 하는 것입니다.
셋째, 베스트 프랙티스를 연구하고 전파합니다. 새로운 테스트 기법, 도구, 방법론을 실험하고, 성공 사례를 전사에 공유합니다. 이는 "Center of Excellence" 모델로, 혁신의 허브 역할을 합니다. 한 핀테크 기업의 품질 플랫폼 팀은 Property-based Testing을 도입하여, 엣지 케이스 발견율을 300% 향상시켰고, 이를 전사에 전파했습니다.
서비스 팀 내 품질 엔지니어의 임베딩
각 서비스 팀에는 품질 엔지니어가 임베드됩니다. 이들은 전통적인 테스터가 아닙니다. 그들의 역할은 근본적으로 다릅니다.
첫째, 테스터빌리티 아키텍트입니다. 시스템 설계 단계부터 참여하여, 테스트 가능한 아키텍처를 설계합니다. 의존성 주입을 통한 모킹 가능성, 관측 가능한 상태 전환, 결정적(deterministic) 동작 보장 등을 고려합니다. 예를 들어, 결제 시스템을 설계할 때 테스트 모드 지원, 감사 로그, 멱등성 보장, 롤백 메커니즘 등을 처음부터 고려합니다.
둘째, 품질 코치입니다. 팀원들이 더 나은 테스트를 작성하도록 돕습니다. 코드 리뷰에서 테스트 커버리지뿐 아니라 테스트 품질을 검토합니다. "이 테스트가 정말 의미 있는가?", "엣지 케이스를 놓치지 않았는가?", "유지보수가 쉬운가?" 같은 질문을 던집니다. 품질은 모두의 책임이라는 문화를 만드는 것이 핵심입니다.
셋째, 자동화 전문가입니다. 반복적인 테스트 작업을 자동화합니다. 이는 단순한 스크립트 작성이 아니라, 지능형 자동화를 의미합니다. 프로덕션 트래픽을 기반으로 테스트 시나리오를 자동 생성하거나, 버그 패턴을 학습하여 유사한 문제를 사전에 감지합니다. 한 모빌리티 기업의 품질 엔지니어는 프로덕션 로그 분석을 통해 자동으로 회귀 테스트 케이스를 생성하는 시스템을 구축했습니다.
완전한 자율은 혼돈으로 이어질 수 있습니다. 따라서 조직적 가드레일이 필요합니다. 이는 창의성을 제한하는 것이 아니라, 안전한 실험을 가능하게 하는 안전망입니다.
표준 계약 스키마의 정의와 진화
서비스 간 계약은 단순한 API 명세가 아닙니다. 기능적 계약, 비기능적 계약, 진화 계약을 모두 포함해야 합니다.
기능적 계약은 입력/출력 형식, 오류 코드, 상태 전환 규칙을 정의합니다. 비기능적 계약은 응답 시간 SLA, 처리량 한계, 가용성 목표를 명시합니다. 진화 계약은 버전 정책, 하위 호환성 규칙, 폐기 일정을 포함합니다.
이러한 계약은 살아있는 문서여야 합니다. 서비스가 진화하면 계약도 함께 진화해야 합니다. 한 소셜 미디어 기업은 계약 진화를 위한 "Contract Council"을 운영합니다. 매월 서비스 팀 대표들이 모여 계약 변경 사항을 논의하고 승인합니다. 이를 통해 자율성을 보장하면서도 전체 시스템의 일관성을 유지합니다.
SLO와 에러버짓의 실무 적용
SLO(Service Level Objective)는 추상적인 목표가 아니라 구체적인 운영 도구입니다. 각 서비스는 가용성, 지연시간, 정확성에 대한 명확한 SLO를 정의합니다.
에러버짓은 이러한 SLO를 기반으로 계산됩니다. 99.9% 가용성은 월 43분의 다운타임을 허용합니다. 이 버짓을 어떻게 사용할지는 팀의 자율입니다. 새로운 기능 실험에 사용할 수도 있고, 기술 부채 해결에 투자할 수도 있습니다.
중요한 것은 에러버짓 소진에 따른 명확한 정책입니다. 50% 소진 시 경고 및 원인 분석, 75% 소진 시 신규 기능 배포 중단, 100% 소진 시 긴급 안정화 모드 전환. 이러한 정책은 자동으로 실행되어야 합니다. 한 스트리밍 서비스는 에러버짓 기반 자동 배포 제어 시스템을 구축하여, 서비스 안정성을 40% 향상시켰습니다.
분산 QA의 가장 큰 도전은 다양성의 폭발입니다. 각 팀이 자율적으로 운영되면서, 테스트 전략, 도구, 프로세스가 제각각이 됩니다. 이는 창의성과 혁신을 촉진하지만, 동시에 전사적 품질 관리를 어렵게 만듭니다.
Uber의 경험이 이를 잘 보여줍니다. 2020년 기준 약 2,200개의 핵심 마이크로서비스를 운영했을 때, 그들은 15개 이상의 서로 다른 테스트 프레임워크, 8개의 CI/CD 플랫폼, 수십 개의 모니터링 도구를 사용하고 있었습니다. 이는 심각한 문제를 야기했습니다.
첫째, 지식 사일로입니다. 한 팀의 엔지니어가 다른 팀으로 이동할 때, 완전히 새로운 도구와 프로세스를 배워야 했습니다. 온보딩 시간이 평균 3주에서 8주로 늘어났습니다. 이는 단순한 시간 낭비가 아니라, 조직의 유연성을 크게 저해했습니다.
둘째, 중복 투자입니다. 각 팀이 비슷한 문제를 독립적으로 해결하면서, 동일한 기능을 여러 번 구현했습니다. 테스트 데이터 생성 도구만 12개가 있었고, 각각 비슷한 기능을 제공했습니다. 이는 엔지니어링 리소스의 심각한 낭비였습니다.
셋째, 품질 격차입니다. 일부 팀은 95% 이상의 코드 커버리지와 철저한 통합 테스트를 유지했지만, 다른 팀은 기본적인 단위 테스트조차 없었습니다. 이는 시스템 전체의 약한 고리가 되었습니다. 가장 약한 서비스가 전체 시스템의 신뢰성을 결정하기 때문입니다.
2023년까지 Uber는 4,500개의 스테이트리스 서비스로 성장했고, 이 문제는 더욱 심각해졌습니다. 그들의 해결책은 "Up"이라는 통합 플랫폼이었습니다. 이는 강제가 아닌 유인을 통해 표준화를 달성했습니다. 플랫폼을 사용하면 자동으로 얻을 수 있는 혜택을 제공함으로써, 팀들이 자발적으로 표준을 따르도록 유도했습니다.
모든 것을 표준화하려 하면 실패합니다. 대신 계층적 접근이 필요합니다. 필수 표준, 권장 표준, 선택 사항으로 구분하여 관리합니다.
필수 표준 (Mandatory)은 모든 팀이 반드시 따라야 하는 최소한의 규칙입니다. 보안 스캔은 모든 배포 전에 반드시 통과해야 합니다. 4가지 골든 시그널(지연시간, 트래픽, 에러율, 포화도)은 반드시 측정하고 보고해야 합니다. 서비스 간 통신은 정의된 계약 스키마를 따라야 합니다. 이러한 필수 표준은 시스템의 기본적인 건강성을 보장합니다.
권장 표준 (Recommended)은 대부분의 경우 따르는 것이 좋지만, 예외를 허용하는 규칙입니다. 언어별 권장 테스트 프레임워크 목록을 제공하되, 특별한 이유가 있다면 다른 선택도 가능합니다. 코드 커버리지 80% 목표를 권장하되, 서비스 특성에 따라 조정 가능합니다. Blue-Green 또는 Canary 배포를 권장하되, 선택은 자율입니다.
선택 사항 (Optional)은 필요에 따라 선택할 수 있는 고급 기능입니다. 성능 테스트, 카오스 엔지니어링, Property-based testing, Mutation testing 등은 팀의 필요와 역량에 따라 도입합니다.
지금 바로 작가의 멤버십 구독자가 되어
멤버십 특별 연재 콘텐츠를 모두 만나 보세요.