SI 프로젝트에서 "문서 작성"이라고 하면 귀찮은 일처럼 느껴질 수 있다. 하지만 기능명세서와 테스트계획서는 프로젝트의 성패를 가르는 핵심 산출물이다. 이 글에서는 두 문서의 개념, 차이점, 그리고 실무에서 어떻게 작성하는지 정리한다.
기능명세서(Functional Specification)란?
기능명세서는 **"시스템이 무엇을 해야 하는가"**를 정의한 문서다.
개발자 입장에서 보면 "이 API가 어떤 요청을 받아서 어떤 응답을 줘야 하는지", 기획자 입장에서 보면 "사용자가 이 버튼을 누르면 어떤 일이 일어나는지"를 명확하게 기술한 것이다.
기능명세서의 핵심 구성요소
| 기능 ID | 기능을 식별하는 고유 번호 | FN-USER-001 |
| 기능명 | 기능의 이름 | 사용자 로그인 |
| 설명 | 기능이 수행하는 작업 | 이메일과 비밀번호로 사용자 인증 |
| 입력 | 필요한 데이터 | email(string), password(string) |
| 출력 | 반환되는 결과 | accessToken, refreshToken |
| 사전조건 | 기능 실행 전 충족 조건 | 회원가입 완료 상태 |
| 사후조건 | 기능 실행 후 상태 | 세션 생성, 로그인 이력 저장 |
| 예외처리 | 오류 상황과 대응 | 비밀번호 5회 오류 시 계정 잠금 |
API 기반 기능명세서 예시
기능 ID: API-AUTH-001
기능명: 사용자 로그인
엔드포인트: POST /api/v1/auth/login
설명: 이메일과 비밀번호를 검증하여 JWT 토큰을 발급한다.
Request:
Headers:
Content-Type: application/json
Body:
email: string (required) - 사용자 이메일
password: string (required) - 비밀번호 (8자 이상)
Response:
Success (200):
accessToken: string - 접근 토큰 (유효기간 1시간)
refreshToken: string - 갱신 토큰 (유효기간 7일)
user:
id: string
email: string
name: string
Error:
401 - 인증 실패 (이메일 또는 비밀번호 불일치)
423 - 계정 잠금 (5회 연속 실패)
429 - 요청 제한 초과
비즈니스 규칙:
- 비밀번호 5회 연속 오류 시 30분간 계정 잠금
- 로그인 성공 시 실패 카운트 초기화
- 로그인 이력은 90일간 보관
테스트계획서(Test Plan)란?
테스트계획서는 **"시스템이 제대로 동작하는지 어떻게 검증할 것인가"**를 정의한 문서다.
기능명세서가 "무엇을 만들 것인가"라면, 테스트계획서는 "만든 것이 제대로 작동하는지 어떻게 확인할 것인가"에 대한 답이다.
테스트계획서의 핵심 구성요소
| 테스트 ID | 테스트 케이스 고유 번호 |
| 테스트 항목 | 테스트 대상 기능 |
| 테스트 유형 | 단위/통합/E2E/성능/보안 등 |
| 사전조건 | 테스트 실행 전 환경 설정 |
| 테스트 절차 | 단계별 수행 방법 |
| 입력 데이터 | 테스트에 사용할 데이터 |
| 예상 결과 | 정상 동작 시 기대값 |
| 판정 기준 | Pass/Fail 기준 |
| 우선순위 | 테스트 중요도 (High/Medium/Low) |
테스트 케이스 예시
테스트 항목: 사용자 로그인 - 정상 케이스
관련 기능: API-AUTH-001
테스트 유형: 통합 테스트
우선순위: High
사전조건:
- 테스트 사용자 계정 생성 완료 (test@example.com / Test1234!)
- 계정 잠금 상태 아님
테스트 절차:
1. POST /api/v1/auth/login 호출
2. Request Body에 올바른 이메일/비밀번호 전송
3. Response 검증
입력 데이터:
{
"email": "test@example.com",
"password": "Test1234!"
}
예상 결과:
- HTTP Status: 200
- Response Body에 accessToken, refreshToken 포함
- accessToken이 유효한 JWT 형식
판정 기준:
- Pass: 모든 예상 결과 충족
- Fail: 하나라도 불충족
테스트 케이스 설계 기법
- 동등 분할(Equivalence Partitioning): 입력값을 유효/무효 그룹으로 나누어 대표값 테스트
- 경계값 분석(Boundary Value Analysis): 경계 지점(최소값, 최대값, 경계±1)을 집중 테스트
- 결정 테이블(Decision Table): 조건과 결과의 조합을 표로 정리
- 상태 전이(State Transition): 상태 변화 흐름을 검증
기능명세서 vs 테스트계획서 비교
| 목적 | 무엇을 만들 것인가 | 제대로 만들었는지 검증 |
| 작성 시점 | 설계 단계 | 설계 완료 후 ~ 개발 병행 |
| 주요 독자 | 개발자, 기획자, 고객 | QA, 개발자, PM |
| 핵심 질문 | "이 기능이 뭘 해야 하지?" | "이게 맞게 동작하나?" |
| 관계 | 테스트계획서의 기준이 됨 | 기능명세서를 검증 |
실무 팁: 효과적인 문서 작성법
1. 기능명세서 작성 팁
- 명확한 용어 정의: "사용자", "관리자", "시스템" 등의 용어를 문서 초반에 정의
- 버전 관리 필수: 변경 이력을 추적할 수 있도록 버전 번호와 변경일자 기록
- 예외 상황 빠짐없이: Happy Path만 쓰지 말고, 오류 상황도 모두 기술
- API 명세 도구 활용: Swagger/OpenAPI로 작성하면 문서와 코드 동기화 용이
2. 테스트계획서 작성 팁
- 기능명세서와 1:N 매핑: 하나의 기능에 여러 테스트 케이스(정상, 예외, 경계값)
- 재현 가능하게: 누가 실행해도 같은 결과가 나오도록 구체적으로 작성
- 우선순위 지정: 모든 테스트를 다 할 수 없을 때 중요한 것부터 실행
- 자동화 고려: 반복 수행할 테스트는 자동화 스크립트로 전환
3. 실무에서 자주 하는 실수
❌ 기능명세 없이 바로 개발 → 요구사항 누락, 재작업 발생
❌ 테스트계획 없이 "잘 되겠지" → 배포 후 장애 발생
❌ 문서만 쓰고 업데이트 안 함 → 실제 코드와 문서 불일치
❌ 테스트 케이스가 너무 추상적 → "로그인 테스트" (X) → "유효한 이메일+비밀번호로 로그인 시 토큰 발급 확인" (O)
마치며
기능명세서와 테스트계획서는 단순한 "문서 작업"이 아니다.
- 기능명세서는 팀 전체가 같은 목표를 보게 하는 나침반이고
- 테스트계획서는 품질을 보장하는 안전망이다
실제로 100개 이상의 API 엔드포인트가 있는 프로젝트에서 기능명세서 없이 개발하면, 나중에 "이 API가 뭘 하는 거였지?"라는 질문이 반복된다. 테스트계획서 없이 배포하면, 운영 환경에서 예상치 못한 오류를 사용자가 먼저 발견하게 된다.
처음엔 번거롭더라도 기능명세서와 테스트계획서를 제대로 작성하는 습관을 들이면, 장기적으로 개발 속도와 품질 모두를 높일 수 있다.
관련 글: API 설계 원칙, 테스트 자동화 전략, CI/CD 파이프라인 구축
'Software > Maker(Spring & Python & node)' 카테고리의 다른 글
| Progressive Partial Rendering(PPR)에 대해서 설명해주세요. (0) | 2026.03.30 |
|---|---|
| 이벤트 소싱이란 무엇인가요? (0) | 2026.03.30 |
| 시퀀스 다이어그램으로 장애를 잡는다: 트러블슈팅을 구조화하는 방법 (0) | 2026.03.28 |
| Node.js의 주요 특징에 대해 설명해주세요. (0) | 2026.03.27 |
| 멀티 프로세스와 멀티 스레드 (4) | 2026.03.26 |
