본문으로 건너뛰기
입문약 22분

검증과 확인, 오류·결함·실패의 구분과 전파

제대로 만들고 있는가(검증)와 맞는 것을 만들고 있는가(확인)를 구분하고, 사람의 실수가 결함을 거쳐 실패로 드러나는 경로를 코드로 추적한다.

  • #검증
  • #확인
  • #결함전파
  • #QA기초

개념

검증(Verification) vs 확인(Validation)

왜 비슷해 보이는 두 단어를 굳이 나누는지부터 짚자. 둘 다 "맞는지 본다" 는 뜻이지만, 무엇과 맞춰 보는지가 다르다. 하나는 적어 둔 문서 와 맞춰 보고, 다른 하나는 실제로 쓰는 사람의 목적 과 맞춰 본다. 문서대로 만들었는데도 쓸모가 없을 수 있기 때문에 두 가지를 따로 센다 — 레슨 1의 우산이 바로 그 이야기였다.

두 단어가 한국어로도 영어로도 헷갈리기 쉬운데, 질문 형태로 외우면 구분이 쉽다.

질문확인 대상시점
검증 (Verification)"우리가 제대로 만들고 있는가?"산출물이 명세·설계와 일치하는가개발 각 단계마다 (문서, 설계, 코드)
확인 (Validation)"우리가 맞는 것을 만들고 있는가?"실제로 사용자 요구를 충족하는가보통 동작하는 소프트웨어로, 더 나중에

두 단어의 구분은 ISTQB Foundation Level 실러버스 1장에 그대로 등장하는 정식 용어이기도 하다. 나중에 "V-모델" 같은 개발 생명주기 그림을 보게 되면, 그 그림의 왼쪽 절반은 대부분 검증을, 오른쪽 절반은 확인을 나타낸다는 걸 알아볼 수 있을 것이다 — 지금은 질문 두 개로 구분하는 것만 확실히 해두면 충분하다.

검증은 "명세대로 만들었는가"를 보고, 확인은 "그 명세 자체가 맞았는가, 실제로 쓸모 있는가"를 본다. 레슨 1의 품질 두 축(명세 충족 / 쓰임에 적합함)과 정확히 짝을 이룬다 — 검증은 첫 번째 축을, 확인은 두 번째 축을 담당한다.

쉬운 비유로 다시 보기 — 레시피와 손님

요리사가 레시피대로 정확히 요리를 만들었는지 확인하는 사람과, 그 요리를 먹은 손님이 맛있어하는지 확인하는 사람은 다른 질문을 던진다.

  • 검증: "레시피에 소금 5g이라고 적혀 있는데, 정말 5g을 넣었는가?" — 주방장이 레시피와 완성된 요리를 대조한다.
  • 확인: "그런데 이 손님은 원래 싱겁게 먹는 사람인데, 이 요리를 맛있어할까?" — 손님이 직접 먹어봐야만 알 수 있다.

레시피대로 완벽하게 만들었어도(검증 통과) 그 손님 입맛에는 너무 짤 수 있다(확인 실패). 반대로 레시피에 없는 향신료를 셰프가 감으로 살짝 더했는데 손님이 "이게 훨씬 낫다"고 할 수도 있다(검증 실패, 확인은 우연히 통과 — 이 경우 레시피를 고쳐야 한다는 신호다). 소프트웨어에서도 똑같은 일이 벌어진다 — "명세대로 정확히 만들었다"는 개발팀의 말과 "그런데 이걸 왜 이렇게 만들었어요?"라는 사용자의 반응이 동시에 참일 수 있다.

둘은 독립적으로 실패한다

이게 핵심이다. 네 가지 조합이 전부 실제로 일어난다.

검증확인무슨 상황인가실무에서
✅✅명세대로 만들었고 사용자도 만족목표 상태
✅❌명세대로 만들었는데 아무도 못 씀가장 위험. 테스트는 전부 통과하는데 제품이 실패한다
❌✅명세와 다르게 만들었는데 오히려 자연스러움드물다. 명세를 갱신하라는 신호
❌❌명세와도 다르고 쓸모도 없음발견은 쉽다. 대개 빨리 잡힌다

두 번째 줄이 QA가 가장 경계해야 할 상태다. 모든 테스트 케이스가 초록불인데 제품이 실패한다. 테스트 케이스는 명세에서 나왔고, 그 명세가 틀렸기 때문이다. 이 상태는 테스트 케이스를 아무리 늘려도 절대 발견되지 않는다 — 실제 사용자를 봐야만 드러난다.

이게 왜 무서운가 하면, QA가 스스로의 성과를 잘못 판단하게 만들기 때문이다. "테스트 케이스 200개, 전부 통과, 결함 0건"이라는 보고는 근사해 보이지만, 그 200개가 전부 틀린 명세에서 나온 것이라면 이 숫자는 오히려 위험 신호를 가려버린다. 통과율은 검증의 결과일 뿐이지 확인의 결과가 아니다 — 이 둘을 섞어서 보고하면 "테스트를 열심히 했는데 왜 사용자는 화가 났나요?"라는, 가장 답하기 곤란한 질문을 받게 된다.

어떤 활동이 어느 쪽인가

표에 단위 테스트·통합 테스트 가 나온다. 각각 "부품 하나만 따로 돌려 보는 시험", "부품 두어 개를 맞물려 돌려 보는 시험" 이라고 알아 두면 지금은 충분하다. 다음 레슨 전체가 이 구분을 다룬다.

활동검증확인
코드 리뷰✅
단위·통합 테스트✅
명세 대비 추적표(traceability matrix) 점검✅
설계 문서 리뷰✅
사용자 인수 테스트(UAT)✅
베타 테스트·사용성 테스트✅
실사용 데이터·이탈률 분석✅
프로토타입을 사용자에게 보여주기✅

마지막 줄이 중요하다. 확인은 소프트웨어가 완성된 뒤에만 할 수 있는 게 아니다. 종이에 그린 화면, 클릭만 되는 프로토타입으로도 "이게 사용자가 원하는 게 맞나"를 물어볼 수 있다. 레슨 1의 비용 곡선을 떠올리면, 확인을 앞당길수록 싸다.

오류 → 결함 → 실패의 전파

세 단어를 QA에서는 엄격하게 구분한다.

  • 오류(Error/Mistake): 사람이 저지른 실수. 요구사항을 잘못 이해했거나, 코드를 잘못 짰거나.
  • 결함(Defect/Fault/Bug): 그 실수가 산출물(코드, 문서, 설계)에 남긴 흔적. 아직 실행되지 않았을 수도 있다.
  • 실패(Failure): 그 결함이 특정 조건에서 실행되어 겉으로 드러난 오작동.
// 오류: 개발자가 "빈 배열도 유효한 입력"이라는 걸 놓쳤다 (사람의 실수)
function getDiscountRate(items) {
  // 결함: items가 빈 배열일 때를 고려하지 않은 코드가 여기 남아 있다
  return items[0].price > 100000 ? 0.1 : 0.05;
}
 
getDiscountRate([{ price: 150000 }]); // 0.1 — 정상 동작, 실패가 드러나지 않는다
getDiscountRate([]);                  // TypeError — 여기서 실패가 발생한다

이 코드는 결함이 있어도 대부분의 입력에서는 실패하지 않는다. 빈 배열이 들어오는 경로를 실행해야만 실패로 드러난다. 그래서 "지금까지 문제가 없었다"는 "결함이 없다"는 뜻이 아니라 "그 결함을 건드리는 조건을 아직 실행해보지 않았다" 는 뜻일 수 있다.

결함이 실패가 되려면 세 가지가 모두 필요하다

결함이 있다고 항상 실패가 보이는 건 아니다. 세 조건이 다 맞아야 한다.

  1. 도달(Reachability) — 그 코드 줄이 실행되어야 한다
  2. 감염(Infection) — 실행 결과로 프로그램 내부 상태가 잘못돼야 한다
  3. 전파(Propagation) — 그 잘못된 상태가 밖으로 관찰 가능한 형태로 나와야 한다

세 번째가 특히 함정이다. 내부적으로 잘못 계산됐는데 화면에 표시할 때 반올림되어 같아 보이는 경우, 테스트는 통과한다. 결함은 그대로 남아 있고 조건이 조금만 달라지면 터진다.

// 결함: 세금을 더해야 하는데 빼고 있다
function total(price) {
  return price - price * 0.1;   // 잘못된 부호
}
 
// price = 0 이면?  →  0 (정답도 0) — 도달했지만 "감염"이 관찰되지 않는다
// price = 10000 이면? → 9000 (정답 11000) — 여기서 비로소 실패가 보인다

"0으로 테스트했더니 통과했다"가 왜 위험한지가 여기 있다. 모듈 3에서 배울 동등분할·경계값이 "실패를 드러나게 만드는 입력을 고르는 기술"인 이유다.

실패가 안 보이는 결함은 안전한가

아니다. 두 가지 이유로 위험하다.

  • 조건이 바뀌면 갑자기 터진다. 위 getDiscountRate 예시에서, 지금까지는 장바구니가 빈 채로 이 함수를 부르는 경로가 없었을 뿐이다. 다음 스프린트에 "빈 장바구니에서도 예상 할인율 미리보기" 기능이 추가되는 순간 실패한다. 코드는 안 바뀌었는데 실패가 시작된다.
  • 조용히 잘못된 데이터를 만든다. 화면에는 안 보여도 DB에는 잘못된 값이 쌓일 수 있다. 레슨 1에서 본 것처럼, 데이터 오염은 코드 수정보다 훨씬 비싼 복구를 부른다.

이 구분이 결함 리포트를 바꾼다

전파 경로를 알면 리포트에 무엇을 써야 하는지가 분명해진다.

빈약한 리포트전파 경로를 아는 리포트
"할인율 계산이 에러남" (실패만 기술)"빈 장바구니 상태에서 할인율 미리보기를 열면(조건) getDiscountRate가 items[0]에 접근하며(결함) TypeError 발생(실패)"

오른쪽은 개발자가 재현 절차를 다시 물을 필요가 없다. "어떤 조건이 그 결함을 건드렸는가"를 적었기 때문이다. 결함 리포트 작성법은 모듈 6에서 자세히 다룬다.

근본 원인은 결함이 아니라 오류 쪽에 있다

결함을 고치면 그 실패는 사라진다. 하지만 같은 오류(사람의 실수 패턴)가 남아 있으면 비슷한 결함이 다른 곳에서 또 생긴다.

이번 결함: getDiscountRate가 빈 배열을 고려하지 않음 그 뒤의 오류: "목록은 항상 최소 1개"라는 검증되지 않은 가정을 팀이 공유하고 있음 → 그렇다면 다른 함수들도 같은 가정을 하고 있을 가능성이 높다

이 관점이 QA를 "버그 잡는 사람"에서 "같은 종류의 버그가 다시 안 생기게 하는 사람"으로 바꾼다. 결함 하나를 발견했을 때 "이 실수가 다른 곳에도 있지 않을까?" 를 함께 묻는 습관이 여기서 나온다 — 레슨 6에서 다룰 QA(프로세스)와 QC(결과물)의 차이와도 닿아 있다.

사례 연구 — 할인율이 어쩌다 마이너스가 됐나

이 레슨에서 배운 개념들이 실제로 어떻게 이어지는지, 하나의 흐름으로 짚어본다.

제보: "가끔 주문 금액이 원래보다 더 나온다"는 CS 문의가 몇 건 들어왔다.

1단계 — 검증부터 시작한다. 할인율 계산 명세를 열어보니 "10만원 이상 구매 시 10% 할인"이라고 적혀 있고, 코드도 그 로직 그대로다. 명세와 코드는 일치한다 — 검증은 통과. 하지만 검증 통과가 "문제없다"는 뜻이 아니라는 걸 이제는 안다.

2단계 — 오류 → 결함의 흔적을 찾는다. 코드를 더 보니, 쿠폰과 할인율이 함께 적용될 때 할인율을 두 번 빼는 구간이 있었다. 개발자는 "쿠폰과 등급 할인은 동시에 안 쓴다"고 가정하고 짰는데(오류), 실제로는 두 할인이 겹치는 경우가 있었다(결함). 평소엔 안 겹쳐서 티가 안 났을 뿐이다(도달했지만 감염이 드물게만 일어남 — 앞서 배운 개념 그대로다).

3단계 — 실패 조건을 좁힌다. "쿠폰 + 등급 할인이 동시에 적용되는 주문"이라는 조건에서만 재현된다는 걸 확인했다. 이게 바로 "어떤 조건이 결함을 건드렸는가"이고, 이걸 리포트에 적으면 개발자가 되묻지 않는다.

4단계 — 확인까지 가본다. 코드를 고친 뒤, 실제로 쿠폰과 등급 할인을 함께 쓰는 사용자 흐름을 처음부터 다시 밟아본다. 계산만 맞는지가 아니라, 화면에 표시되는 최종 금액이 사용자 입장에서 납득 가는 숫자인지까지 본다 — 여기가 확인이다.

5단계 — 오류 수준으로 올라간다. "동시에 안 쓴다"는 검증되지 않은 가정이 이 결함의 진짜 원인이었다. 그렇다면 이 코드베이스의 다른 할인·적립 로직에도 같은 가정이 깔려 있지 않을까? 이 질문을 던지는 게 이 레슨의 마지막 절에서 말한 "근본 원인은 결함이 아니라 오류 쪽에 있다"를 실제로 적용하는 것이다.

한 건의 CS 문의가 검증 → 결함 추적 → 조건 좁히기 → 확인 → 재발 방지 질문까지 이어지는 흐름을 보여준다. 이 다섯 단계는 앞으로 배울 결함 리포트 작성(모듈 6), 탐색적 테스팅(모듈 5)에서도 계속 반복해서 쓰이는, QA 업무의 가장 기본적인 골격이다.

실무에서 왜 필요한가

실무에서 가장 흔한 오해는 "명세대로 만들었으니 QA 책임은 끝났다"는 생각이다. 하지만 명세 자체가 틀렸다면(확인 실패), 그건 QA가 검증만 하고 확인을 건너뛰었기 때문일 수 있다. 예를 들어 결제 폼이 요구사항 문서와 한 글자도 다르지 않게 구현됐지만(검증 통과), 실제 사용자 테스트에서 결제 단계가 너무 복잡해 다들 중간에 이탈한다면(확인 실패), 그 결함은 테스트 케이스로는 절대 못 잡는다 — 실제 사용자 흐름을 봐야 잡힌다.

QA가 확인(Validation)에 기여하는 현실적인 방법은 이렇다. 사용자 리서치를 직접 하지 않더라도 할 수 있는 일이 많다.

  • 요구사항 리뷰에서 "이 흐름을 처음 보는 사람이 이해할까?"를 묻기
  • 실제 사용 데이터(이탈 지점, 오류 로그, CS 문의 내용)를 정기적으로 보기
  • 테스트할 때 명세를 잠시 덮고 사용자처럼 써보기 — 스크립트 밖을 보는 이 활동이 모듈 5의 탐색적 테스팅이다
  • 베타·UAT에서 나온 피드백을 "요구사항 대비 차이"로 번역해 전달하기

또한 "결함이 있어도 실패가 안 보이면 괜찮다"는 생각도 위험하다. 위 코드 예시처럼, 결함은 그대로 남아있다가 몇 달 뒤 특정 이벤트(예: 프로모션으로 빈 장바구니 관련 로직이 새로 실행되는 경로)에서 갑자기 실패로 터지는 경우가 실무에서 자주 있다. 그때는 "왜 갑자기?"라는 질문이 나오는데, 답은 "갑자기가 아니라 원래 있었다" 이다.

신입 QA가 특히 조심할 것 — "제 담당은 검증까지입니다"라는 선 긋기. 실무에서 검증과 확인이 조직적으로 완전히 분리된 경우는 드물다. 신입일수록 검증(명세 대조)에 먼저 익숙해지고, 확인은 "시니어나 PM이 하는 일"로 여기기 쉽다. 하지만 위 목록처럼 확인에 기여하는 방법은 리서치 전문가가 아니어도 할 수 있는 것들이다. 오히려 매일 코드와 화면을 들여다보는 사람이 "이거 좀 이상한데"를 가장 먼저 느낄 위치에 있다. 이 감각을 "내 일이 아니다"로 넘기지 않는 것이 검증과 확인을 함께 챙기는 QA와, 체크리스트만 채우는 QA를 가른다.

실습 과제

과제 1 — 검증인가 확인인가 (10분)

다음 활동이 검증(Verification)인지 확인(Validation)인지 분류한다.

  1. 설계 문서와 실제 구현된 API 응답 필드가 일치하는지 대조한다.
  2. 실제 사용자 5명에게 신규 가입 흐름을 써보게 하고 어디서 헤매는지 관찰한다.
  3. 요구사항 문서의 각 항목이 테스트 케이스로 하나씩 커버되는지 추적표로 확인한다.
  4. 베타 사용자 그룹에 기능을 먼저 공개하고 실제 사용 데이터를 본다.
  5. 종이에 그린 화면 시안을 사용자에게 보여주고 "이걸로 원하는 걸 하실 수 있겠어요?"라고 묻는다.
해설 보기
  1. 검증 — 산출물 간 일치 확인
  2. 확인 — 실제 사용자 관점
  3. 검증 — 명세 대비 커버리지
  4. 확인 — 실사용 데이터
  5. 확인 — 코드가 없어도 확인은 가능하다. 그리고 이 시점의 확인이 가장 싸다.

5번이 이 과제의 핵심이다. 확인을 "소프트웨어가 다 만들어진 뒤 하는 것"으로 생각하면 가장 비싼 시점에만 하게 된다.

과제 2 — 전파 경로 추적하기 (10분)

아래 코드에서 오류·결함·실패를 각각 찾아 적는다. "이 결함이 실패로 드러나려면 어떤 입력이 필요한가?"도 함께 적는다.

def calculate_average(scores):
    total = sum(scores)
    return total / len(scores)
해설 보기
  • 오류: 개발자가 "점수 목록은 항상 비어 있지 않다"고 가정했다. 검증되지 않은 가정.
  • 결함: len(scores)가 0일 수 있는데 그 경우를 처리하지 않은 코드.
  • 실패: calculate_average([]) 호출 시 ZeroDivisionError.
  • 실패를 드러내는 입력: 빈 리스트 [].

추가로 생각해볼 것 — scores에 숫자가 아닌 값이 섞이면? None이 들어오면? 하나의 결함을 찾았을 때 "이 함수가 하고 있는 다른 가정은 없나" 를 묻는 것이 레슨에서 말한 "오류 수준으로 올라가 보기"다.

과제 3 — 도달·감염·전파 (10분)

아래 함수에는 결함이 있다. 부가세 10%를 더해야 하는데 빼고 있다.

function totalWithTax(price) {
  return price - price * 0.1;
}

세 가지 입력에 대해 ①코드가 실행되는가(도달) ②내부 값이 틀리는가(감염) ③겉으로 틀린 게 보이는가(전파)를 판정한다.

입력도달감염전파(실패가 보이는가)
0
10000
함수를 아예 호출하지 않는 화면
해설 보기
입력도달감염전파
0✅❌ (0 - 0 = 0, 정답도 0)❌ 테스트가 통과한다
10000✅✅ (9000, 정답 11000)✅ 실패가 보인다
호출 안 함❌—❌

첫 줄이 교훈이다. 0으로만 테스트했다면 이 결함을 놓친다. 결함이 없어서가 아니라 그 입력에서는 잘못된 값이 겉으로 드러나지 않기 때문이다. "테스트를 했는데 왜 못 잡았나"의 상당수가 이 구조다 — 모듈 3에서 배울 값 고르기 기법이 필요한 이유.

과제 4 — 검증 통과 / 확인 실패 사례 만들기 (10분)

"명세대로 정확히 만들었지만 사용자가 쓸 수 없는" 상황을 직접 하나 만들어본다. 자신이 써본 서비스에서 떠올려도 좋고, 가상으로 지어내도 좋다. 아래를 채운다.

  • 명세에 뭐라고 적혀 있었을까:
  • 개발은 그 명세를 어떻게 정확히 지켰나:
  • 그런데 사용자는 왜 못 쓰는가:
  • 이걸 코드가 생기기 전에 발견하려면 무엇을 했어야 했나:

마지막 줄이 목적이다. 확인 실패는 테스트 케이스로 못 잡으므로, "그럼 언제 어떻게 잡을 수 있었나"를 스스로 답해보는 것이 이 과제의 핵심이다.

과제 5 — 사례 연구 다시 짚기 (10분)

위 "할인율이 어쩌다 마이너스가 됐나" 사례 연구를 다시 읽고, 다섯 단계 각각이 검증/확인 중 무엇에 해당하는지, 그리고 오류·결함·실패 중 무엇을 다루고 있는지 표로 정리해본다.

단계검증/확인오류/결함/실패
1. 명세와 코드 대조
2. 이중 차감 코드 발견
3. 재현 조건 좁히기
4. 사용자 흐름으로 재확인
5. "다른 곳에도 있지 않을까" 질문
해설 보기
단계검증/확인오류/결함/실패
1. 명세와 코드 대조검증— (아직 결함을 못 찾음)
2. 이중 차감 코드 발견—결함 발견 (그 뒤의 오류까지 추정)
3. 재현 조건 좁히기—실패 조건 확정
4. 사용자 흐름으로 재확인확인실패가 사라졌는지 확인
5. "다른 곳에도 있지 않을까"—오류 수준 — 아직 결함으로 발견되지 않은 곳을 찾는 단계

5단계가 이 표에서 유일하게 "아직 아무것도 발견되지 않은" 단계라는 게 흥미롭다. 결함도 실패도 아직 없는데, 이미 결함이 있을 가능성이 높은 곳을 짚어내는 것이다. 이게 QA가 "이미 벌어진 일을 확인하는 사람"을 넘어 "다음에 벌어질 일을 예측하는 사람"이 되는 지점이다. 실제로 5단계 이후 이 팀이 코드베이스를 검색해보니, 적립금 계산 로직에도 똑같이 "쿠폰과 동시에 안 쓴다"는 가정이 남아 있었다 — 아직 아무도 신고하지 않았을 뿐, 조건만 맞으면 언제든 터질 수 있는 결함이었다.

자가 체크리스트

  • 검증과 확인을 각각 질문 형태("제대로 만들고 있는가" / "맞는 것을 만들고 있는가")로 설명할 수 있다
  • 검증과 확인이 레슨 1의 품질 두 축과 어떻게 짝을 이루는지 설명할 수 있다
  • 레시피 비유로 검증과 확인의 차이를 다른 사람에게 30초 안에 설명할 수 있다
  • 하나의 결함 사례를 검증 → 결함 추적 → 조건 좁히기 → 확인 → 재발 방지 질문의 흐름으로 재구성할 수 있다
  • "제 담당은 검증까지입니다"라는 태도가 왜 위험한지, 확인에 기여할 수 있는 구체적 방법을 들어 설명할 수 있다
  • V-모델 같은 개발 생명주기 그림을 봤을 때, 어느 부분이 검증이고 어느 부분이 확인인지 짚어낼 수 있다
  • 검증은 통과하지만 확인은 실패하는 사례를 스스로 만들 수 있다
  • 그 경우가 왜 테스트 케이스로는 잡히지 않는지 설명할 수 있다
  • 확인이 완성된 소프트웨어 없이도 가능하다는 것을 예로 들 수 있다
  • 오류·결함·실패 세 단어를 순서대로, 서로 다른 개념으로 구분해 쓸 수 있다
  • 결함이 실패가 되려면 도달·감염·전파 세 가지가 모두 필요하다는 것을 설명할 수 있다
  • "결함이 있어도 실패가 관찰되지 않을 수 있다"는 이유를 코드 예시로 설명할 수 있다
  • 실패가 안 보이는 결함이 왜 여전히 위험한지 두 가지 이유를 댈 수 있다
  • 결함 리포트에 "어떤 조건이 결함을 건드렸는가"를 왜 적어야 하는지 설명할 수 있다
  • 결함 하나를 발견했을 때 "같은 오류가 다른 곳에도 있지 않을까"를 묻는 이유를 안다

흔한 실수

  • 검증과 확인을 뒤바꿔 쓴다. "확인 테스트"라고 부르면서 실제로는 명세 대조(검증)만 하는 경우가 흔하다. 실제 사용자 관점이 빠졌다면 확인이 아니다.
  • 결함을 고치고 나서 "다른 곳에도 같은 실수가 없는지"를 안 묻는다. 위 사례 연구의 5단계를 생략하는 것과 같다. 결함 하나를 고쳤다는 안도감에 멈추면, 같은 오류가 낳은 다른 결함이 다음 CS 문의로 돌아온다.
  • 레시피 비유를 "확인은 나중에 해도 된다"로 오해한다. 레시피 비유의 핵심은 순서가 아니라 독립성이다 — 요리가 다 되기 전에도 "이 손님이 싱겁게 먹는 사람인가"는 미리 물어볼 수 있다. 확인을 뒤로 미룰 이유가 없다.
  • 확인을 릴리즈 직전에만 한다. 그때는 이미 고치기에 가장 비싼 시점이다. 프로토타입· 시안 단계에서도 확인은 가능하다.
  • "버그가 안 보인다 = 결함이 없다"고 결론짓는다. 실행되지 않은 코드 경로에 결함이 잠들어 있을 수 있다. 커버리지(모듈 3, 10에서 다룸)가 낮으면 이 위험이 커진다.
  • 테스트가 통과했으니 그 입력이 좋은 입력이었다고 믿는다. 0처럼 결함이 있어도 정답과 같아지는 입력이 있다. 통과한 테스트가 많다는 것과 좋은 테스트라는 것은 다르다.
  • 결함만 고치고 오류(실수의 패턴)는 그대로 둔다. 같은 가정을 공유하는 다른 코드에서 비슷한 결함이 또 나온다. 하나를 찾으면 "같은 종류가 더 있나"를 확인하는 게 효율적이다.
  • 오류의 책임을 개인에게 돌리는 데 집중한다. 오류는 사람이 만들지만, 결함이 실패로 이어지기까지 여러 단계(리뷰, 테스트)를 통과했다는 뜻이기도 하다. "누가 실수했나"보다 "왜 이 단계들에서 못 잡았나"가 더 생산적인 질문이다.

참고 자료

  • ISTQB Glossary — Verification / Validation — 공식 용어 정의
  • Barry Boehm, Software Engineering Economics — "Are we building the product right? / Are we building the right product?" 표현의 원출처로 자주 인용된다
  • Andreas Zeller, Why Programs Fail — 결함이 실패로 이어지는 경로(도달·감염·전파)를 체계적으로 다룬 책
  • Barry Boehm & Victor Basili, "Software Defect Reduction Top 10 List" (2001) — 결함을 만든 근본 원인(오류) 수준에서 대응할 때 재발률이 어떻게 달라지는지 정리한 논문. "근본 원인은 결함이 아니라 오류 쪽에 있다"는 이 레슨 마지막 절의 근거다
  • ISO/IEC/IEEE 29119-1 — 검증·확인을 포함한 테스트 용어를 국제 표준으로 정의한 문서. 모듈 8에서 이 표준 전체를 다룬다

낯선 말 풀이

이 레슨에 나온 약어입니다. 본문에서도 처음 나올 때 점선으로 표시해 두었습니다 (제목과 링크 글자는 그대로 둡니다).

ISTQB — 국제 소프트웨어 테스팅 자격 위원회
테스터 자격 시험을 만들고 용어를 정리하는 국제 단체.
QA — 품질보증
만든 것이 쓸 만한지 확인하고, 애초에 덜 망가지게 만드는 방법을 정하는 일. "테스트"는 그 일의 일부다.
UAT — 인수 테스트
만든 쪽이 아니라 실제로 쓸 사람이 "이거면 받겠다"를 확인하는 마지막 시험.
DB — 데이터베이스
데이터를 넣어 두고 꺼내 쓰는 저장소. 보통 표 여러 개가 서로 연결된 형태다.
QC — 품질관리
이미 만들어진 것에서 불량을 골라내는 일. 품질보증은 불량이 생기는 과정 자체를 다룬다는 점이 다르다.
CS — 고객 지원 · 칩 선택 신호
이 커리큘럼에서 두 가지로 쓰인다. ① 고객 문의와 불만을 직접 받는 조직 ② 여러 부품이 한 선을 나눠 쓸 때 "지금은 네 차례" 라고 하나를 고르는 신호. 앞뒤에 문의·고객이 있으면 ①, 통신·배선 이야기면 ②다.
PM — 프로젝트 또는 제품 관리자
일정과 범위를 정하고 결정을 내리는 사람. 회사에 따라 프로젝트 관리자와 제품 관리자 둘 중 하나를 뜻한다.
API — 응용 프로그램 인터페이스
프로그램끼리 주고받는 창구. 사람이 화면 버튼을 누르는 대신, 프로그램이 정해진 주소로 요청을 보내 답을 받는다.
ISO/IEC/IEEE — 세 단체 공동 표준
세 국제 단체가 함께 낸 표준이라는 표시.

용어집 전체 보기