요구사항의 빈틈 질문하기
65분 안팎
학습 목표
중복 이메일과 권한·공백 처리의 미합의 조건을 질문합니다.
개념
질문은 구현 지연이 아니라 판단 근거입니다
요구사항에 ‘이메일이 중복이면 가입할 수 없다’만 적혀 있다고 가정합니다. 한 사람은 QA@example.test와 qa@example.test를 같은 이메일로 보고 다른 사람은 서로 다른 값으로 봅니다. 어느 구현을 만드느냐보다 먼저 합의가 필요한 상황입니다. QA가 익숙한 서비스의 동작을 정답으로 삼으면 잘못된 결함을 보고하거나 실제 위험을 놓칠 수 있습니다. 질문은 결정되지 않은 조건을 드러내고 누가 언제 답할지 정하는 작업입니다.
시니어가 신입의 질문을 검토할 때는 질문 개수보다 답변에 따라 테스트가 어떻게 달라지는지를 봅니다. ‘이메일은 어떻게 하나요?’는 범위가 넓습니다. ‘대소문자만 다른 이메일을 같은 계정으로 간주하나요? 기존 qa@example.test가 있을 때 QA@example.test 가입을 거절할지 확인이 필요합니다’라고 쓰면 결정할 조건과 구체적인 사례가 드러납니다. 상대가 한 문장으로 답하기 쉬운 질문으로 나눕니다.
관찰한 사실과 정하지 않은 정책
화면에서 앞뒤 공백이 사라지는 것을 보았다고 해서 API에서도 공백을 제거하도록 합의되었다고 할 수 없습니다. 발견한 동작은 실제 결과이고 합의된 정책은 기대 결과의 근거입니다. 실제 동작이 문서와 다르다면 정책 오류인지 구현 오류인지 추가 확인이 필요합니다. 이번 단계는 앱을 실행하지 않으므로 ‘실제 화면에서 확인했다’는 근거를 쓰지 않습니다. 교육용 합의 v1과 미합의 조건을 나누어 기록합니다.
이 모듈의 합의는 정확히 같은 이메일의 중복 거절, 빈 이메일 거절, 스페이스만 있는 닉네임 거절, 가입 후 로그인 화면 이동입니다. 이메일 대소문자와 닉네임 최대 길이의 계산 단위는 보류입니다. 합의된 공백 전용 닉네임 거절에서 앞뒤 공백 자동 제거까지 추론하지 않습니다. ‘ 새회원 ’을 저장할 때 원본을 유지할지 제거할지는 다른 질문입니다. 비슷한 예시라도 규칙을 넓힐 때는 근거가 필요합니다.
질문 기록에 담을 정보
questions.json의 question은 결정할 문장이고 example은 그 문장의 뜻이 갈리는 입력입니다. requirementIds는 영향을 받는 요구사항의 ID 배열입니다. impact에는 기대값이 달라지는 이유를 적습니다. owner는 답을 책임지는 역할, nextAction은 답변을 받을 시점이나 다음 조치입니다. 상태만 ‘보류’로 쓰면 그대로 남기 쉬우므로 누구에게 언제 다시 물을지 기록합니다. 담당은 실제 개인 이름 대신 교육용 제품 담당으로 적습니다.
{
"id": "Q-01",
"requirementIds": ["REQ-02"],
"question": "이메일의 대소문자를 같은 값으로 볼까요?",
"example": "QA@example.test와 qa@example.test",
"status": "보류",
"decision": "대소문자 규칙은 아직 정하지 않았습니다.",
"owner": "교육용 제품 담당",
"impact": "가입 중복 판정과 로그인 기대값이 달라집니다.",
"nextAction": "다음 모듈 테스트 설계 전 확인합니다.",
"evidence": "아직 답변 없음"
}
decision은 보류 상태에서도 비워 두지 않습니다. 무엇이 아직 정해지지 않았는지 밝히고 임시 추정을 합의로 바꾸지 않습니다. evidence는 확인 근거입니다. 이번 예시는 답변이 없으므로 ‘아직 답변 없음’이라고 씁니다. 합의된 항목에는 교육용 합의 v1을 쓰며 실제 회의가 있었다고 꾸미지 않습니다. 실제 팀에서는 승인된 문서 버전이나 답변 기록을 연결할 수 있습니다.
답변을 기준으로 반영하는 순서
질문을 보낸 뒤 ‘네’라는 답만 받으면 어떤 선택에 동의했는지 다시 확인합니다. 선택지와 예시의 결과를 함께 되읽습니다. 예를 들어 공백만 있는 닉네임을 거절한다고 합의했다면 질문의 status를 합의로 바꾸고 decision에 안내와 저장 무변경을 적습니다. 이어 REQ-04의 AC-04에도 같은 결과를 반영합니다. 질문 기록만 바꾸고 인수 기준을 그대로 두면 검사할 때 옛 기준을 사용하게 됩니다.
답변이 새로운 요구를 추가했다면 기존 ID를 억지로 재사용하지 않습니다. 본인 수정 정책과 타인 접근 정책은 다른 결과이므로 분리할 수 있습니다. 반대로 문구만 명확하게 고친 경우는 기존 ID를 유지하고 근거 버전을 바꿉니다. 질문 기록에서 영향을 받는 ID를 따라가 기준과 추적표를 검토하면 바꿀 범위를 확인할 수 있습니다. 연결을 유지하는 습관은 다음 레슨의 추적표 작업으로 이어집니다.
권한과 데이터 영향부터 묻습니다
답변 시간이 부족할 때는 회원 정보가 잘못 바뀌거나 노출되는 조건을 먼저 확인합니다. ‘A가 B의 프로필을 수정하려 하면 어떤 결과가 필요하나요?’는 안내 문구뿐 아니라 데이터 무변경과 정보 비노출을 함께 논의하게 합니다. 화면에서 버튼을 숨겼다는 답변이면 다른 요청 경로에서도 정책이 적용되는지 되묻습니다. 화면 표시와 서비스의 접근 권한은 같은 근거가 아니기 때문입니다.
이번 실습은 합성 회원 A와 B만 가정합니다. 실제 계정이나 타인의 데이터를 확인할 필요가 없습니다. 존재하지 않는 회원 ID의 접근, 로그아웃 상태, 세션 만료도 관련 질문 후보이지만 현재 범위를 넓히기 전에 어떤 요구사항과 연결되는지 씁니다. 후보를 한꺼번에 결함으로 등록하지 않습니다. 정상 동작만 적힌 요구에는 거절 조건을 질문으로 보완하고 답이 있는 것부터 기준으로 확정합니다.
보류를 숨기지 않고 진행합니다
질문 하나가 미해결이라고 모든 작업이 멈추는 것은 아닙니다. 대소문자 중복은 보류해도 정확히 같은 이메일의 중복 거절은 준비할 수 있습니다. 추적표의 테스트 제목에도 정확히 같은 이메일이라고 써 두면 보류 조건을 이미 검증할 수 있다는 오해를 줄입니다. 반면 닉네임 최대 길이를 모르면 그 길이의 경계값 기대 결과는 확정할 수 없습니다. 다음 모듈에 넘길 때 설계 보류 사유와 해제 조건을 전달합니다.
테스트 조건의 임시 가정이 필요한 팀도 있습니다. 그 경우에는 ‘가정’, 적용 기간, 승인 역할, 틀렸을 때 수정할 산출물을 남깁니다. 가정은 합의와 구분되어야 합니다. 이번 미션에서는 agreed 또는 pending 요구사항 상태와 질문의 합의 또는 보류 상태를 사용합니다. 상태가 다른 두 문서가 서로 모순되는지 사람 리뷰로 확인합니다. 자동 검사기는 한글 문장의 정책 의미까지 비교하지 않습니다.
좋은 질문을 제출 전 점검합니다
‘질문 5개 이상 필요’라는 메시지가 나왔다면 같은 문장의 표현만 바꿔 개수를 채우지 않습니다. 중복 이메일, 공백 닉네임, 로그인 목적 화면, 타인 수정의 저장 영향, 닉네임 길이 단위처럼 서로 다른 결정을 다룹니다. ‘Q-01: 상태 오류’는 status가 합의나 보류가 아닌 값이라는 뜻입니다. ‘확인 중’ 같은 자유 문구는 정한 상태 값으로 바꾸고 상세 상황은 decision과 nextAction에 옮깁니다.
동료 리뷰에서는 질문마다 두 가지 가능한 답을 가정하고 기대 결과가 실제로 달라지는지 확인합니다. 달라지지 않는다면 이미 합의된 내용을 반복한 질문일 수 있고 추가 근거 확인이 목적일 수도 있습니다. 질문의 목적을 밝히면 됩니다. 답이 오면 어느 기준을 고칠지 설명할 수 있고 보류가 남으면 미검증 범위를 말할 수 있어야 합니다. 협업에서 변경과 근거를 남기는 일반 원칙은 더 읽기의 장으로 이어집니다.
따라하기
의미가 갈리는 입력으로 질문 쓰기
questions.json의 Q-01을 유지하고 example에 QA@example.test와 qa@example.test를 씁니다. requirementIds는 ["REQ-02"]입니다. status는 보류, evidence는 아직 답변 없음으로 둡니다. impact에는 가입 중복과 로그인 기대값이 달라진다고 적습니다. 담당과 다음 모듈 설계 전 확인이라는 nextAction을 기록합니다.
합의 항목 반영하기
Q-02는 공백만 있는 닉네임 거절 합의입니다. status=합의, decision=닉네임 필수 안내와 무저장, evidence=교육용 합의 v1로 씁니다. 연결된 REQ-04/AC-04도 동일 결과인지 확인합니다. 파일을 편집하는 단계이므로 실행 출력은 없습니다.
보류 질문만 꺼내기
question-review.py에 아래 코드를 저장하고 python3 question-review.py로 실행합니다. 이 예시는 질문 배열 중 보류 ID를 골라 출력합니다. 질문의 실제 답변을 조사하는 프로그램은 아닙니다. Q-05의 닉네임 길이 단위가 해결되어야 어떤 테스트를 확정할 수 있을지 설명합니다.
questions = [{"id": "Q-01", "status": "보류"}, {"id": "Q-02", "status": "합의"}, {"id": "Q-03", "status": "합의"}, {"id": "Q-04", "status": "합의"}, {"id": "Q-05", "status": "보류"}]
for q in questions:
if q["status"] == "보류":
print(q["id"] + ": 다음 설계 전 답변 필요")
실행 결과
Q-01: 다음 설계 전 답변 필요 Q-05: 다음 설계 전 답변 필요
질문 다섯 건과 전달 메모 완성
Q-03 로그인 목적 화면, Q-04 타인 수정의 데이터 영향, Q-05 닉네임 최대 길이 단위를 추가합니다. 앞의 두 질문은 교육용 합의, 길이 단위는 보류입니다. 질문별 예시·결정·영향·담당·다음 조치·근거를 모두 적습니다. REQ의 ID가 존재하는지 확인하고 보류로 인해 확정하지 않은 조건을 별도 전달 문장으로 작성합니다.
확인 문제
실습
spec/questions.json에 질문 5개 이상을 제출합니다. 각 질문에 연결 REQ, 해석이 갈리는 예시, 합의/보류, 결정, 근거, 담당, 영향, 다음 조치를 적습니다. 교육용 합의 v1을 사용하고 이메일 대소문자와 닉네임 길이 단위는 보류로 둡니다. 합의는 관련 기준에 반영하고 보류가 막는 테스트 범위를 두 문장으로 설명합니다.
더 읽기
면접 질문
- 요구사항에 정상 동작만 적혀 있을 때 대응 방법을 설명해 주시면 됩니다.