Skip to content

필사 모드: 검증 설계 — 테스트를 통과 여부가 아니라 신뢰 근거로 보기

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

초록불은 그 자체로는 아무것도 뜻하지 않습니다

CI가 초록입니다. 그래서 무엇을 알게 된 걸까요.

이 질문에 답하지 못하는 초록불이 많습니다. 통과했다는 사실만 있고, 통과가 무엇을 보장하는지는 아무도 문장으로 갖고 있지 않습니다. 이 상태에서 테스트는 배포 절차의 관문이지 판단의 근거가 아닙니다. 관문은 통과하면 잊히지만, 근거는 사고가 났을 때 다시 꺼내집니다.

차이는 배포 직후에 드러납니다. 장애가 나면 누군가 반드시 묻습니다. 이거 테스트는 안 잡았나요. 이때 "그 영역은 원래 검증 범위 밖이었습니다"라고 답할 수 있으면 조직은 다음 결정을 할 수 있고, "잡았어야 하는데요"밖에 못 하면 같은 일이 반복됩니다.

존재는 보일 수 있고 부재는 보일 수 없습니다

Edsger Dijkstra가 1970년 "Notes On Structured Programming"에서 남긴 문장이 이 분야의 출발점입니다. 프로그램 테스트는 버그의 존재를 보이는 데 쓸 수 있지만 부재를 보이는 데는 결코 쓸 수 없다는 것입니다.

이 문장은 흔히 테스트 무용론으로 오해되지만 정반대입니다. 테스트가 증명 도구가 아니라 증거 수집 도구라는 뜻입니다. 증거는 얼마나 모았느냐가 아니라 무엇에 대한 증거냐가 중요합니다. 그래서 테스트를 설계하는 일은 개수를 늘리는 일이 아니라, 어떤 주장을 뒷받침할 증거를 모을지 고르는 일이 됩니다.

1편에서 판정을 수행하는 일은 자동화되고 판정을 설계하는 일은 남는다고 했습니다. 테스트는 그 문장의 가장 깨끗한 사례입니다. 좋은 테스트를 고르는 것은 비싸고, 그 테스트를 만 번 돌리는 것은 공짜입니다.

각 테스트에 신뢰 문장을 붙이기

실무로 옮기는 가장 싼 방법이 하나 있습니다. 테스트마다 한 문장을 붙이는 것입니다. 이것이 초록이면 나는 무엇을 안 걱정해도 되는가.

예시 — 테스트에 붙이는 신뢰 문장

test_refund_exceeds_payment_is_rejected
  → 결제액보다 큰 환불이 데이터베이스에 기록되는 일은 없다고 믿어도 된다

test_order_service_returns_200
  → (문장이 안 써짐) 이 테스트가 초록이어도 걱정이 줄어드는 항목이 없다

두 번째 같은 테스트가 생각보다 많습니다. 실행은 하는데 아무것도 주장하지 않는 테스트입니다. 이런 테스트는 없는 것보다 나쁩니다. 개수를 채워서 안심시키고, 그 안심 위에서 판단이 이뤄지기 때문입니다.

문장을 붙이다 보면 부수 효과가 하나 생깁니다. 같은 문장이 여러 테스트에 붙는 것이 보이고, 그건 중복이고, 반대로 아무 테스트도 붙지 않은 중요한 문장이 보입니다. 그 빈자리가 다음에 쓸 테스트입니다.

커버리지가 재는 것과 재지 못하는 것

커버리지는 유용하지만 자주 오독됩니다. 커버리지가 재는 것은 테스트 실행 중에 그 줄을 지나갔는가입니다. 그 줄의 결과를 검사했는가가 아닙니다.

단언문이 하나도 없는 테스트도 커버리지를 올립니다. 예외가 안 나면 통과하기 때문입니다. 그래서 커버리지 숫자는 위쪽으로는 거의 의미가 없고, 아래쪽으로만 의미가 있습니다. 20퍼센트라면 확실히 부족하다는 정보가 있지만, 90퍼센트라는 숫자에는 안전하다는 정보가 없습니다.

더 쓸모 있는 신호는 따로 있습니다. 최근 장애가 났던 코드 경로에 테스트가 있는지, 되돌리기 어려운 동작에 테스트가 있는지, 그리고 불안정 테스트가 몇 개인지입니다. 마지막 것이 특히 중요합니다. 가끔 빨간불이 뜨는 테스트가 있으면 사람들은 빨간불을 무시하는 법을 배우고, 그 학습은 그 테스트에만 적용되지 않습니다.

검증하지 않기로 한 것을 적기

이 글에서 가장 실천하기 어렵고 값어치가 큰 항목입니다. 무엇을 검증했는지가 아니라 무엇을 검증하지 않기로 했는지를 적는 것입니다.

모든 것을 검증할 수는 없으므로 모든 팀은 이미 이 선택을 하고 있습니다. 다만 대개 암묵적으로 하고, 그래서 아무도 그 선택을 검토하지 않습니다. 명시적으로 적어 두면 세 가지가 생깁니다.

첫째, 사고가 났을 때 그것이 알려진 위험이었는지 몰랐던 위험이었는지 구별됩니다. 둘째, 위험 감수 결정이 개인의 판단에서 팀의 결정으로 올라갑니다. 셋째, 검증하지 않기로 한 목록을 사람들에게 보여 주면 반발이 나오고, 그 반발이 진짜 중요한 항목을 알려 줍니다.

형식은 단순해도 됩니다. 이번 변경에서 검증한 것 세 줄, 검증하지 않은 것 세 줄, 검증하지 않은 이유 한 줄이면 충분합니다.

판정 기준이 없는 영역

지금 가장 어려운 영역은 정답표가 없는 쪽입니다. 검색 결과의 품질, 추천의 적절함, 생성된 텍스트의 유용함. 여기서는 통과와 실패로 갈리는 테스트를 쓸 수 없습니다.

이때 필요한 것은 테스트가 아니라 판정의 설계입니다. 세 가지가 축이 됩니다.

먼저 기준 집합입니다. 사람이 판정한 사례를 모아 고정된 세트로 만들어 둡니다. 크지 않아도 되고, 대신 어렵고 논쟁적인 사례가 들어가야 합니다. 쉬운 사례만 모으면 무엇을 바꿔도 점수가 안 움직입니다.

다음은 대리 지표입니다. 직접 재고 싶은 것을 못 재니 옆의 것을 잽니다. 이때 반드시 함께 적어야 할 것이 이 지표가 어떻게 속을 수 있는지입니다. 속는 경로를 미리 적어 두지 않으면, 언젠가 그 경로로 지표가 올라가고 아무도 못 알아챕니다.

마지막은 표본 검토입니다. 자동 판정이 불가능한 부분은 정기적으로 사람이 표본을 봅니다. 이때 중요한 것은 좋은 것을 보는 게 아니라 무작위로 뽑는 것입니다. 골라서 보면 아무것도 안 배웁니다.

직접 해보기

이번 주에 자기가 최근에 쓴 테스트 다섯 개를 열고, 각각에 신뢰 문장을 한 줄씩 붙여 보세요. 안 써지는 것이 하나라도 나오면 그것이 이 글에서 가장 중요한 발견입니다.

  • SLO와 에러 예산 계산기 — 안정성을 목표가 아니라 예산으로 다루면 얼마나 검증할 것인가가 계산 문제가 됩니다.
  • 논리법 훈련소 — 필요조건과 충분조건을 구별하는 연습이 들어 있습니다. 테스트가 무엇을 보장하는지 정확히 말하는 일과 같은 구조입니다.

안 통하는 경우도 있습니다. 요구가 매주 바뀌는 탐색 단계에서 두꺼운 테스트를 깔면, 테스트가 변경을 막는 벽이 됩니다. 이 단계에서는 되돌릴 수 없는 것들에만 검증을 붙이고 나머지는 비워 두는 편이 낫습니다. 검증의 밀도는 코드의 중요도가 아니라 되돌리기 비용을 따라가야 합니다.

이어서 읽기

비싸게 남는 기술 시리즈

참고 자료

  • Edsger W. Dijkstra 인용 모음 — Wikiquote — 프로그램 테스트는 버그의 존재를 보일 수 있을 뿐 부재를 보일 수 없다는 문장의 출처는 1970년 "Notes On Structured Programming"(EWD249)입니다. 2026-08-15 확인.
  • 신뢰 문장, 명시적 비검증 목록, 판정 설계의 세 축은 위 자료에 나오는 것이 아니라 이 글에서 정리한 절차입니다.

현재 단락 (1/36)

CI가 초록입니다. 그래서 무엇을 알게 된 걸까요.

작성 글자: 0원문 글자: 3,036작성 단락: 0/36