Scaling up your microservice testing with Apache Spark (Part 1)

Author: Stripe Engineering | Source: stripe.dev/blog | Published: (미기재)


한 줄 요약

입력 분포의 롱테일이 행동을 결정하는 서비스는 손으로 만든 테스트로 검증할 수 없으므로, 결정 로직을 요청 경로에서 분리해 Spark로 수개월~수년치 프로덕션 히스토리를 replay하면 프로덕션 이력 자체가 실행 가능한 테스트 자산이 된다.

핵심 주장/내용

  • 단위/통합 테스트가 답하지 못하는 질문: “룰 하나, rate table 하나, 의존성 하나, 자격 조건 하나를 바꾸면 실제 히스토리 트래픽 분포 전체에서 무슨 일이 일어나는가?”
  • request handler와 Spark transformation은 형태가 같다: 입력 수신 → 보조 상태 로드 → 비즈니스 로직 → 출력. 코어 로직이 transport·프레임워크 배선·부수효과와 깔끔히 분리되어 있으면 같은 로직을 Spark 잡에서 호출 가능. 출력은 단일 응답이 아니라 쿼리·조인·diff·집계·리뷰가 가능한 데이터셋
  • AI 시대에 더 중요해진다: AI 도구가 리팩터·마이그레이션·후보 구현을 빠르게 만들어주지만, 금전 이동·과금·가격·자격·고객 대면 설명에 영향을 주는 시스템은 더 빠른 코드 변경일수록 더 강한 평가가 필요. 국소적으로 맞아 보이는 변경이 입력 분포의 좁지만 중요한 부분에서 행동을 바꿀 수 있음
  • 러닝 예제 — 카드 네트워크 비용 추정: 거래 사실(금액·통화·국가·카드 네트워크·카드 상품·CP/CNP·인증 방식·토큰화 상태), 머천트/연동 컨텍스트(MCC·설정·빌링 데이터 가용성·enhanced line-item), 룰·의존성 상태(버전별 rate table·네트워크 프로그램 룰·자격 리스트·리전 설정). 출력도 숫자 하나가 아니라 적용된 룰·자격 프로그램·설명 필드까지 — IC+ 가격제 고객에게는 비용이 그대로 노출되므로 특히 중요
  • 세 가지 활용:
    1. 회귀 테스트 — 현재 구현과 후보 구현을 히스토리 입력에 모두 돌려 비교. 완벽 일치가 목표가 아님. 일부 diff는 의도된 변경이고 일부는 기존 구현의 버그를 드러냄. 가치는 차이가 프로덕션 도달 전에 보인다는 것
    2. 미래 룰 변경 모델링(what-if) — 네트워크가 새 프로그램·인센티브·scheme fee를 도입할 때, 어려운 문제는 룰을 인코딩하는 게 아니라 실제 히스토리 트래픽에서 어떻게 행동할지 추정하는 것. “과거에 무슨 일이 있었나”를 묻는 일반 분석과 달리 “의사결정 환경이 달랐다면 서비스가 무엇을 반환했을까”를 물음
    3. PR용 golden dataset — 공통 흐름·자격 경계·과거 인시던트·작은 입력 변화가 큰 결과 차이를 내는 케이스를 담은 큐레이션된 입력/기대출력 쌍. CI에서 매 PR마다 실행하고 예기치 않은 차이면 빌드 실패. 인시던트가 놓친 엣지 케이스를 드러낼 때마다 보존되므로 살아있는 스펙이 됨
  • 프라이버시 경계: 유용한 테스트 케이스는 원본 필드 전체가 아니라 의사결정에 관련된 요청의 형태. 테스트 대상 행동에 필요한 필드로 최소화하고 민감 식별자는 토큰화 또는 안정적 테스트 ID로 치환. 기대출력·diff·로그·golden dataset 모두 원본 PII 노출을 피하고 소스 데이터 민감도에 맞는 접근 통제·보존 정책 적용
  • 테스팅 스택에서의 위치: 단위 테스트(의도적으로 구성한 작은 케이스) < 통합 테스트(시스템 간 상호작용) < golden dataset(알려진 서비스 레벨 예시) < 히스토리 replay(팀이 설계하지 않은 입력까지 포함한 실제 프로덕션 분포)

관련 위키


Source: 원문 보기