Devin.KR

동등 분할과 경계값

75분 안팎

학습 목표

비밀번호 길이 8~64자의 유효·무효 구간과 경계를 선택합니다.

개념

값을 나열하기 전에 규칙을 나눕니다

가입 폼에 비밀번호를 여러 번 입력했다고 해서 길이 규칙을 확인한 것은 아닙니다. 12자, 15자, 20자는 모두 허용 구간의 안쪽이어서 같은 종류의 실수를 놓칠 수 있습니다. QA는 입력 개수를 늘리기 전에 어떤 규칙이 결과를 갈라놓는지 찾습니다. 이번 목표는 길이가 8~64자인 합성 비밀번호에서 허용 구간과 거절 구간을 나누고, 조건이 뒤집히는 지점의 사례를 설명하는 것입니다.

동등 분할은 같은 규칙으로 처리될 것으로 예상하는 입력을 한 묶음으로 나누는 설계 방법입니다. 이 예제의 길이 구간은 8 미만, 8 이상 64 이하, 64 초과입니다. 한 구간의 대표값으로 그 구간을 확인하되 모든 입력이 실제로 같은 내부 경로를 탄다고 보장하지는 않습니다. 특수 문자나 공백 정책이 추가되면 길이와 별도로 분할해야 합니다. 대표 사례 통과를 전체 입력에 대한 증명으로 확대하지 않습니다.

이번 모듈의 실행 환경과 계약

브라우저 실습은 JavaScript 표준 입력을 읽고 텍스트를 출력합니다. 외부 패키지, DOM, 실제 회원 계정은 쓰지 않습니다. 코드의 require는 입력을 읽는 기본 기능이며 가입 서버에 요청하는 코드가 아닙니다. 따라하기 코드는 별도 example.cjs 파일로 저장하고 node example.cjs로 실행할 수 있습니다. 자동 채점의 입력은 실습 아래 tests와 같고 출력의 대소문자와 줄 구분을 맞춥니다. 언어의 자세한 연산자 설명은 더 읽기에서 확인합니다.

미션은 Python 3와 bash로 문서를 검사합니다. starter 압축을 푼 폴더에서 bash check.sh를 실행합니다. 앞 모듈 solution의 spec 네 파일과 검사기는 그대로 포함합니다. 이번 산출물은 cases/contract.json, cases/cases.json, cases/review.json입니다. 검사기는 수정하지 않고 사례와 리뷰를 채웁니다. JSON 파일의 따옴표·쉼표 오류는 파일명과 줄·열을 보고 고칩니다. 문서 검사 PASS는 제품 실행 증거가 아니므로 모든 사례의 실행 상태는 planned입니다.

교육용 설계 계약 v2는 이번 모듈의 계산 예제를 위한 추가 약속입니다. 비밀번호 길이는 ASCII 문자 8~64개이고 양 끝을 포함합니다. 프로필 수정 판단은 인증 확인, 본인 여부, 대상 존재 순서입니다. 세션 만료 후 접근은 거절되고 올바른 로그인으로만 다시 인증됩니다. 기존 합의 v1은 그대로 유지하며 이메일 대소문자와 닉네임 길이는 계속 보류합니다. 이 계약은 운영 제품의 정책이나 API 상태 코드를 확정하는 문서가 아닙니다.

양 끝 바로 옆을 확인합니다

경계값은 유효성이 바뀌는 지점과 그 근처입니다. 하한 8에서는 7·8·9, 상한 64에서는 63·64·65를 선택합니다. 7은 하한 밖, 8은 첫 허용값, 9는 허용 구간 안쪽입니다. 63은 마지막 허용값 바로 전, 64는 마지막 허용값, 65는 상한 밖입니다. 이 여섯 값은 비교 연산에 등호가 빠지거나 제한값이 한 칸 어긋난 구현을 구별하기 위해 고른 것입니다. 8과 64를 제외하면 양 끝 포함 여부를 확인할 수 없습니다.

길이 규칙의 기대값은 7 INVALID, 8 VALID, 9 VALID, 63 VALID, 64 VALID, 65 INVALID입니다. INVALID는 제품이 잘못되었다는 뜻이 아니라 해당 길이를 거절해야 한다는 뜻입니다. 길이 7을 제품이 거절하면 그 사례의 테스트는 통과입니다. 입력 허용 여부와 테스트 비교 결과를 같은 단어로 적지 않습니다. 미션에는 거절 안내와 회원 무변경까지 적어 입력 정책을 저장 결과와 연결합니다.

유효한 중간값 20 하나만 사용하면 8을 거절하는 구현도 통과합니다. 반대로 경계 여섯 개만으로 이메일 중복이나 타인 프로필 접근을 확인할 수는 없습니다. 한 기법이 모든 누락을 해결한다고 생각하지 않습니다. 길이 축의 대표값과 경계를 먼저 확보한 뒤 다른 축은 결정표와 상태 전이로 확장합니다. 리뷰에서 각 사례가 어느 규칙을 겨냥하는지 말할 수 있어야 합니다.

입력 단위를 고정하고 조건 하나씩 바꿉니다

이 실습은 실제 비밀번호 문자열 대신 길이 정수 목록을 읽습니다. 한 줄에 7 8 9처럼 넣으면 각 길이에 대한 판정을 한 줄씩 출력합니다. 빈 입력은 아무 줄도 출력하지 않습니다. 음수·소수·문자가 섞인 입력은 이 계산 실습의 계약 밖입니다. 이를 실제 가입 폼의 정책으로 해석하지 않습니다. 문자열 길이의 단위를 다루는 별도 요구사항이 없으면 이모지나 조합 문자까지 ASCII 예제의 결과로 판단할 수 없습니다.

가입 경계 사례를 실행할 준비를 할 때는 다른 필드를 유효한 값으로 고정합니다. 이메일이 이미 사용 중이면 길이 8이 거절되어도 길이 비교 때문에 거절되었는지 알기 어렵습니다. 각 사례의 이메일은 합성 고유 주소로 준비하고 닉네임은 스페이스가 아닌 값으로 둡니다. 입력 길이를 바꾸었을 때만 결과가 달라지도록 사전 조건을 통제하면 원인 추적이 쉬워집니다. 테스트 이후 회원 수 증가는 해당 실행 전후를 비교합니다.

브라우저 starter는 길이 8과 64를 거절하는 비교식을 담고 있습니다. 실행 오류가 아니라 기대 결과 불일치입니다. 결과표에서 7과 65가 맞고 8과 64가 틀리면 상한·하한 포함 조건을 먼저 의심합니다. SyntaxError는 문법을 읽을 수 없다는 뜻이며 ReferenceError는 변수 이름을 찾지 못했다는 뜻입니다. 이런 오류를 제품의 길이 결함으로 기록하지 않고 계산 코드부터 고칩니다.

사례 선택 근거를 남깁니다

미션의 경계 사례에는 requirementId와 acceptanceId, contractRef, 사전 조건, 입력, 기대 결과, 유형을 적습니다. 기존 REQ-01/AC-01에 연결하되 길이의 추가 근거는 contractRef password-length로 밝힙니다. 기존 인수 기준 문장을 바꿔 새 정책이 처음부터 합의된 것처럼 보이게 하지 않습니다. 이는 요구사항의 출처와 설계 가정을 분리해서 다음 작성자가 변경 범위를 알 수 있게 하는 방법입니다.

여섯 경계 외에 길이 0과 중간값 20을 추가하면 빈 길이와 일반 허용 입력도 설명할 수 있습니다. 개수 충족을 위해 20자 사례를 이름만 바꿔 반복하지 않습니다. 리뷰표에는 확인한 구간과 아직 제외한 문자 규칙을 함께 씁니다. 마지막으로 동료에게 8과 64가 왜 허용되는지 계약 문장으로 설명해 봅니다. 코드 출력만 가리키지 않고 양 끝 포함이라는 근거를 말할 수 있으면 이 레슨의 목표에 도달한 것입니다.

따라하기

구간 대표값 분류

길이 규칙만 계산하는 코드를 실행하고 구간별 결과를 읽습니다.

for (const n of [0,20,80]) console.log(n, n >= 8 && n <= 64 ? 'VALID' : 'INVALID');

실행 결과

0 INVALID
20 VALID
80 INVALID

경계 여섯 값 대조

양 끝을 포함하는 조건으로 아래 출력을 만듭니다. 8과 64의 결과를 계약 문장과 비교합니다.

for (const n of [7,8,9,63,64,65]) console.log(n, n >= 8 && n <= 64 ? 'VALID' : 'INVALID');

실행 결과

7 INVALID
8 VALID
9 VALID
63 VALID
64 VALID
65 INVALID

등호 누락 구별

의도적으로 양 끝을 제외한 조건을 실행합니다. 앞 단계와 달라진 두 길이를 지적합니다.

for (const n of [7,8,9,63,64,65]) console.log(n, n > 8 && n < 64 ? 'VALID' : 'INVALID');

실행 결과

7 INVALID
8 INVALID
9 VALID
63 VALID
64 INVALID
65 INVALID

미션 경계 사례 준비

starter의 cases/cases.json에서 boundary 사례를 채웁니다. passwordLength만 바꾸고 고유 이메일·유효 닉네임은 고정합니다. expected에 안내와 저장 효과, source에 contract password-length를 적습니다.

확인 문제

실습

공백으로 구분한 0 이상의 ASCII 비밀번호 길이 정수 목록을 읽습니다. 각 값에 대해 길이와 VALID 또는 INVALID를 공백으로 구분해 한 줄 출력합니다. 8~64는 양 끝 포함입니다. 빈 입력에는 출력하지 않습니다. 서버 검증이 아닌 길이 계약 계산이며 입력은 정수만 제공합니다.

모범 답안
const fs=require('fs');
const raw=fs.readFileSync(0,'utf8').trim();
const values=raw?raw.split(/\s+/).map(Number):[];
for(const n of values) console.log(n,n>=8&&n<=64?'VALID':'INVALID');

더 읽기

면접 질문

  • 가입 폼의 테스트 조건을 정하는 과정을 설명해 주시면 됩니다.