테스트 리포트를 숫자가 아닌 스토리로 전달하기
- 12 Dec, 2025
테스트 리포트를 숫자가 아닌 스토리로 전달하기
7시 30분, 리포트 정리 시작
매일 저녁 7시. 내 업무 루틴은 리포트 정리로 끝난다.
Jenkins에서 떨어진 테스트 결과. Pytest 리포트. Allure 대시보드. 숫자만 잔뜩이다. Pass 2,847개. Fail 23개. Skip 15개.
이걸 그대로 공유하면? 아무도 안 본다.
작년까지 나도 그랬다. 엑셀에 숫자 복붙. 컬러 코딩. 메일 발송. 다음 날 개발팀장이 물었다. “그래서 릴리즈 해도 돼요?”
멘탈이 나갔다. 2,847개 테스트를 통과했는데. 이걸 어떻게 설명하지.
그때부터 바꿨다. 리포트는 숫자가 아니라 이야기다.

CTO가 물어본 질문
리포트 방식을 바꾸게 된 계기.
3개월 전 월례 회의. CTO가 내 리포트를 보더니 물었다. “테스트 커버리지 85%면 좋은 건가요? 릴리즈 해도 되나요?”
순간 막혔다. 기술적으론 좋은 수치다. 업계 평균도 70% 정도니까. 근데 “좋다”고 말할 수 없었다. 결제 모듈 테스트가 3개 실패 중이었거든.
85%라는 숫자는 의미 없었다. 나머지 15%가 어디냐가 중요했다.
그날 깨달았다. 임원진은 QA 전문가가 아니다. 숫자보다 리스크를 알고 싶어 한다. “릴리즈해도 안전한가”가 궁금한 거다.
다음 회의부터 접근을 바꿨다. “결제 모듈 테스트 3개 실패. 릴리즈 블로킹 이슈. 다른 건 문제없음.”
CTO 표정이 달라졌다. “결제는 고쳐야죠. 나머진 배포 가능?” 드디어 대화가 됐다.
숫자 대신 컨텍스트
리포트 구조를 완전히 뜯어고쳤다.
Before:
- 전체 테스트: 2,885개
- Pass: 2,847개 (98.7%)
- Fail: 23개 (0.8%)
- Skip: 15개 (0.5%)
After:
- 릴리즈 블로킹: 3개 (결제 API 타임아웃)
- 주의 필요: 5개 (UI 깨짐, UX 영향)
- 알려진 이슈: 15개 (백로그 등록됨)
- 안전: 2,847개 기능 검증 완료
같은 데이터다. 전달 방식만 바뀌었다. 근데 반응이 180도 달라졌다.
개발팀장: “결제는 내일 아침까지 고칠게요.” PM: “UI 깨진 건 어느 화면이에요? 급한가요?” CTO: “알려진 이슈 15개는 언제 해결 예정?”
구체적인 액션이 나왔다. 이게 진짜 리포트다.

시각화는 도구일 뿐
처음엔 시각화에 집착했다.
Grafana 대시보드 만들었다. 그래프 10개. 실시간 업데이트. 컬러풀하고 멋있었다. 근데 아무도 안 봤다.
문제는 간단했다. 너무 많았다. 임원진은 대시보드 10분 볼 시간이 없다. 1분 안에 핵심만 알고 싶어 한다.
지금은 3가지만 보여준다.
1. 신호등 (Traffic Light)
- 빨강: 릴리즈 블로킹. 절대 배포 금지.
- 노랑: 주의 필요. 비즈니스 판단 필요.
- 초록: 안전. 배포 가능.
한눈에 본다. 오늘이 빨강인지 초록인지.
2. 트렌드 (Trend)
- 최근 2주 테스트 실패율 그래프
- 갑자기 튄 날 있으면 설명 추가
- “10일 - API 배포로 인한 일시적 실패”
패턴을 본다. 점점 나아지는지 악화되는지.
3. 핫스팟 (Hotspot)
- 가장 자주 실패하는 모듈 Top 3
- 테스트 불안정한 기능 표시
- “로그인 모듈 - 이번 주 4번 실패”
리스크 영역을 본다. 어디에 집중해야 하는지.
이 3개면 충분하다. 나머지는 디테일 페이지에 넣어뒀다. 궁금하면 클릭해서 보면 된다. 대부분은 안 본다. 그래도 된다.
이야기 구조로 전달
리포트를 이야기처럼 쓴다.
기승전결 구조:
기(상황): “오늘 2,885개 테스트 실행. 밤새 4시간 걸렸습니다.”
승(문제): “결제 API 테스트 3개 실패. 타임아웃 에러. 원인은 DB 쿼리 성능 이슈.”
전(영향): “결제 플로우 전체에 영향. 신용카드/계좌이체 모두 영향권. 릴리즈 블로킹.”
결(해결): “백엔드팀 인덱스 추가 중. 내일 오전 재테스트 예정. 그 외 영역은 배포 가능.”
누구나 이해한다. 기술 배경 없어도.
실제 예시 (지난주 금요일 리포트):
제목: [빨강] 결제 모듈 블로킹, 그 외 배포 가능
“오늘 릴리즈 준비 테스트 완료했습니다.
좋은 소식: 신규 검색 기능, 마이페이지 개편 모두 통과. 2주간 준비한 기능들 문제없습니다.
나쁜 소식: 결제 API 성능 이슈 발견. 1,000건 이상 주문 시 타임아웃. 실제 운영 데이터로 테스트하면서 잡혔습니다.
영향도: 블랙프라이데이 대비 필수. 대량 주문 처리 불가능.
해결: 백엔드팀 DB 최적화 중. 월요일 오전 재검증.
결론: 검색/마이페이지는 이번 주 배포 가능. 결제는 다음 주.”
CTO 답장: “결제는 다음 주 가능할까요? 블프 전까진 필수.” 즉시 답했다: “월요일 오후면 확실히 결론 드릴게요.”
이게 소통이다.

인사이트는 숨어있다
리포트는 결과만 전달하는 게 아니다.
데이터 속에서 인사이트를 찾는다. 패턴을 본다.
예시 1 - 특정 시간대 실패: “로그인 테스트가 새벽 3시에만 실패. 조사해보니 이 시간에 DB 백업 돌아감. 백업 중 타임아웃 늘어남. 테스트 타이밍 조정 또는 백업 시간 변경 필요.”
→ 운영 이슈 발견. DevOps팀이 백업 시간 옮김.
예시 2 - 특정 OS 실패: “iOS 테스트만 3주간 실패율 높음. Android는 정상. iOS 14.8 특정 버전 이슈. 애플 버그. 우리가 고칠 수 없음. 사용자한테 OS 업데이트 권장 필요.”
→ CS팀이 공지 올림. 문의 감소.
예시 3 - 특정 개발자 커밋: “A 개발자 PR 후 테스트 실패율 증가 패턴. 악의는 없음. 테스트 코드 작성 습관 부족. 페어 프로그래밍 제안.”
→ 조심스럽게 팀장한테 공유. 개선됨.
인사이트는 액션으로 이어진다. 단순 결과 나열과 차원이 다르다.
템플릿을 만들었다
매일 처음부터 쓸 순 없다.
템플릿 3개 만들었다.
1. 일일 리포트 (Daily)
- 신호등 상태
- 블로킹 이슈 (있으면)
- 새로 발견된 버그
- 내일 테스트 계획
5분 안에 작성. Slack에 공유.
2. 주간 리포트 (Weekly)
- 이번 주 하이라이트
- 트렌드 분석 (좋아짐/나빠짐)
- 다음 주 리스크 예상
- 요청 사항
20분 작성. 이메일 발송.
3. 릴리즈 리포트 (Release)
- 전체 테스트 커버리지
- 릴리즈 가능 여부 (Go/No-Go)
- 알려진 이슈 목록
- 릴리즈 후 모니터링 계획
1시간 작성. 회의에서 발표.
템플릿 있으니 일관성 생겼다. 누가 봐도 같은 구조다.
자동화할 건 자동화
리포트 생성도 반은 자동화했다.
Python 스크립트 하나 만들었다.
# 내가 만든 리포트 생성기 (간략 버전)
def generate_daily_report():
results = parse_test_results()
blocking = [t for t in results if t.severity == 'critical' and t.status == 'failed']
warnings = [t for t in results if t.severity == 'high' and t.status == 'failed']
if blocking:
signal = "🔴 빨강"
elif warnings:
signal = "🟡 노랑"
else:
signal = "🟢 초록"
report = f"""
[{signal}] {date.today()} 테스트 리포트
블로킹: {len(blocking)}개
{format_test_list(blocking)}
주의: {len(warnings)}개
{format_test_list(warnings)}
안전: {len([t for t in results if t.status == 'passed'])}개 검증 완료
"""
return report
매일 저녁 7시 자동 실행. 초안을 만들어준다. 내가 할 일은 컨텍스트 추가. “왜 실패했는지”, “언제 해결되는지”.
시간이 절반으로 줄었다. 예전엔 1시간. 지금은 30분.
질문 받을 준비
리포트 보내면 질문 온다.
준비해둔다. 예상 질문과 답변.
자주 오는 질문:
Q: “이번 주 배포 가능?” A: 준비됨. 신호등 색깔 + 조건부 배포 가능 여부.
Q: “이 버그 언제 고쳐짐?” A: 담당자 확인 + 예상 일정. 모르면 “확인 후 알려드릴게요” 솔직히.
Q: “커버리지 왜 떨어졌어?” A: 신규 기능 추가됨. 분모 늘어남. 테스트 추가 중. 다음 주 회복 예정.
Q: “자동화 안 되는 건 어떻게 테스트?” A: 매뉴얼 테스트 계획 있음. 담당자 배정됨. 결과는 금요일 공유.
답 못하는 질문도 있다. 그땐 솔직하게. “확인해보고 알려드릴게요. 30분 드리면 될까요?”
모르는 척 안 한다. 추측도 안 한다. 확인 후 정확히 답한다.
신뢰는 일관성에서
3개월 했더니 달라진 게 있다.
사람들이 내 리포트를 기다린다.
“자동화J 리포트 왔어?” “오늘 신호등 뭐야?” “이번 릴리즈 괜찮대?”
예전엔 읽으라고 태그 걸었다. 지금은 먼저 찾아본다.
이유는 간단하다. 일관성.
매일 같은 시간. 같은 형식. 같은 수준의 디테일. 한 번도 빠진 적 없다. 금요일 밤 배포 전에도. 월요일 아침 장애 후에도.
신뢰는 거기서 온다. “자동화J 리포트면 믿을 만해.”
가끔 PM이 의사결정 회의에 내 리포트 캡처해서 쓴다. “QA팀 판단으론 릴리즈 가능합니다.”
뿌듯하다. 리포트가 의사결정 자료가 됐다.
실패도 공유한다
좋은 것만 보고하지 않는다.
테스트 놓친 것도 쓴다. 자동화 실패도 쓴다.
지난달 장애: “로그인 장애 발생. 테스트에서 못 잡았습니다. 원인: 타사 OAuth 서버 다운. 우리 테스트는 Mock 사용. 실제 연동은 검증 안 됨. 개선: 주 1회 실제 OAuth 통합 테스트 추가.”
숨기지 않았다. 솔직하게 썼다.
CTO 반응: “개선 계획 좋습니다. 다음 주부터 시작하세요.”
책망 없었다. 오히려 신뢰 올라갔다.
완벽한 척 안 한다. QA도 사람이다. 다 잡을 순 없다. 중요한 건 배우고 개선하는 것.
팀원도 가르친다
후배 QA 2명 있다.
이들도 리포트 쓴다. 가르쳐줬다.
처음엔 숫자만 나열했다. 당연하다. 나도 그랬으니까.
“이 숫자가 말하는 게 뭐야? 릴리즈 해도 돼?”
질문하면서 가르쳤다. 숫자 뒤 컨텍스트를 보라고.
2주 지나니 좋아졌다. 한 달 지나니 제법이다.
이제 나 없어도 리포트 돈다. 휴가 갈 수 있다.
데이터는 이야기를 원한다
숫자는 사실이다. 이야기는 의미다.
2,847개 통과는 사실. “결제 빼고 다 안전합니다”는 의미.
의미를 전달해야 움직인다. 액션이 나온다.
리포트는 보고서가 아니다. 소통 도구다.
오늘도 7시 30분. 리포트 쓴다. 신호등은 초록. 내일 배포 간다.
