이 글은 누구를 위한 것인가
- "이 버튼 색상이 더 나을 것 같아요" vs "아니요, 저게 더 나을 것 같아요" 논쟁을 끝내고 싶은 팀
- A/B 테스트를 시작했지만 결과 해석이 어려운 팀
- 통계를 몰라도 A/B 테스트를 설계할 수 있는 방법을 찾는 디자이너
들어가며
A/B 테스트의 목적은 "누가 맞는지"가 아니라 "사용자가 더 좋아하는 것을 확인"하는 것이다. 잘못된 A/B 테스트는 틀린 결론을 빨리 내리게 만든다. 올바른 가설과 충분한 샘플이 핵심이다.
이 글은 bluefoxdev.kr의 UX 실험 설계 가이드 를 참고하여 작성했습니다.
1. A/B 테스트 설계 프로세스
[올바른 A/B 테스트 설계]
1. 가설 설정:
형식: "X를 Y로 바꾸면 Z가 N% 향상된다"
예: "CTA 버튼 색상을 회색→파란색으로 바꾸면 클릭율이 15% 향상된다"
나쁜 가설: "버튼을 예쁘게 바꾸면 더 많이 클릭한다" (측정 불가)
2. 지표 선택:
Primary Metric: 결정에 쓸 핵심 지표 (클릭율, 전환율)
Guard Metric: 부작용 감지 (이탈율 증가하면 안됨)
3. 샘플 크기 계산:
최소 효과 크기 (MDE): 몇 % 개선을 의미 있다고 볼 건가?
통계 검정력: 80% (거짓 음성 20% 허용)
유의 수준: 5% (p < 0.05)
예: 현재 전환율 3%, MDE 0.5%p 개선 감지
→ 필요 샘플: 약 각 그룹 15,000명
4. 테스트 기간:
최소 2주 (주말/평일 효과 포함)
완전한 비즈니스 사이클 포함
5. 결과 해석:
p < 0.05: 통계적으로 유의미
신뢰구간 확인 (점 추정 아닌 범위로)
경제적 유의미성도 확인 (통계 유의해도 효과 작으면 무의미)
[A/B 테스트 실패 패턴]
❌ 이른 종료 (유의미하다 나오자마자 중단)
❌ 여러 변수 동시 변경 (무엇이 효과인지 모름)
❌ 샘플 부족 (10명으로 결론 내기)
❌ 이미 알고 있는 결론 확인용 사용
2. 이커머스 A/B 테스트 사례
// Feature Flag 기반 A/B 테스트
function useABTest(experimentId: string): "control" | "variant" {
const userId = getCurrentUserId();
// 사용자 ID 기반 일관된 분배 (같은 사용자는 항상 같은 그룹)
const hash = simpleHash(`${experimentId}-${userId}`);
return hash % 2 === 0 ? "control" : "variant";
}
// CTA 버튼 색상 A/B 테스트
function AddToCartButton({ productId }: { productId: string }) {
const variant = useABTest("cta-color-test");
const analytics = useAnalytics();
const buttonClass = variant === "control"
? "bg-gray-700 text-white"
: "bg-blue-600 text-white";
const handleClick = () => {
analytics.track("add_to_cart_click", {
experiment_id: "cta-color-test",
variant,
product_id: productId,
});
addToCart(productId);
};
return (
<button
onClick={handleClick}
className={`w-full py-3 rounded-xl font-semibold ${buttonClass}`}
>
장바구니 담기
</button>
);
}
// 샘플 크기 계산기
function calculateSampleSize(
baselineRate: number, // 현재 전환율 (0.03 = 3%)
mde: number, // 최소 감지 효과 크기 (0.005 = 0.5%p)
power: number = 0.8, // 검정력 (80%)
alpha: number = 0.05, // 유의 수준 (5%)
): number {
const p1 = baselineRate;
const p2 = baselineRate + mde;
// 정규분포 z값 (단측 검정)
const z_alpha = 1.96; // alpha = 0.05
const z_beta = 0.84; // power = 0.80
const numerator = (z_alpha + z_beta) ** 2 * (p1 * (1 - p1) + p2 * (1 - p2));
const denominator = (p1 - p2) ** 2;
return Math.ceil(numerator / denominator);
}
// 사용 예시
const n = calculateSampleSize(0.03, 0.005);
console.log(`필요 샘플: 각 그룹 ${n.toLocaleString()}명`);
// 각 그룹 약 15,032명
마무리
A/B 테스트에서 가장 흔한 실수는 "유의미한 결과가 나오자마자 실험을 종료"하는 것이다. 이것은 통계적으로 거짓 양성을 증가시킨다. 실험 시작 전에 "언제 종료할지"를 미리 정하고, 정해진 샘플에 도달했을 때 결과를 확인해야 한다.