[SE100 #016] 좋은 요구사항 문장 — ISO/IEC/IEEE 29148
소프트웨어 공학 100 주제 시리즈의 16번째 글이다. (카테고리: 요구사항 공학)
한 줄 요약
ISO/IEC/IEEE 29148 은 요구사항 하나가 갖춰야 할 특성과 요구사항 집합이 갖춰야 할 특성을 나눠 정의한다. 문장 하나는 단일하고 검증 가능해야 하고, 집합은 일관되고 완전해야 한다. 이 특성을 매번 지키는 가장 싼 방법은 EARS 같은 제약된 문장 틀이다.
왜 필요한가
요구사항 분석 글에서 명확성·단일성·검증 가능성의 예를 봤다. 그 세 가지만 지켜도 많이 나아진다. 하지만 규모가 커지면 다른 문제가 나온다.
- 문장 하나하나는 멀쩡한데, REQ-031 과 REQ-112 가 서로 모순된다.
- 시스템 요구사항에 “Redis 클러스터를 써야 한다” 가 들어가 있다. 문장으로는 명확하지만 그 층위에 있으면 안 되는 말이다.
- 같은 뜻을 “~해야 한다”, “~한다”, “~할 수 있다” 로 섞어 써서 무엇이 필수인지 모른다.
- 요구 300개에 출처·근거·검증 방법이 없어, 하나를 바꾸면 무엇이 영향받는지 아무도 모른다.
29148 은 이런 문제를 문장 수준, 집합 수준, 속성 수준으로 나눠 다룬다.
핵심 개념
표준의 계보
| 문서 | 상태 | 비고 |
|---|---|---|
| IEEE 830-1998 | 대체됨(superseded) | “좋은 SRS 의 내용과 품질” 을 다룬 권고 관행. 29148:2011 로 대체 |
| ISO/IEC/IEEE 29148:2011 | 대체됨 | 830 을 대체한 1판 |
| ISO/IEC/IEEE 29148:2018 | 현행 | 2판. 15288·12207 개정에 맞춘 구조 조화 |
IEEE 의 표준 소개는 2018년판이 “좋은 요구사항이 무엇인지” 를 정의하고, 요구사항의 속성과 특성을 규정하며, 요구사항 프로세스의 반복 적용을 다룬다고 요약한다. 오래된 사내 템플릿이 “IEEE 830 양식” 이라면 25년 넘은 문서를 따르고 있는 것이다.
표준의 뼈대
2018년판 5장 “개념” 의 요구사항 기초 절은 다음 순서로 구성된다(표준 목차 기준).
5.2.4 요구사항 구문(requirements construct)
5.2.5 개별 요구사항의 특성
5.2.6 요구사항 집합의 특성
5.2.7 요구사항 언어 기준
5.2.8 요구사항 속성(attributes)
그리고 9장에서 이해관계자 요구 명세(StRS), 시스템 요구 명세(SyRS), 소프트웨어 요구 명세(SRS)의 내용 항목을 정한다.
개별 요구사항의 특성
2018년판이 개별 요구사항에 요구하는 특성은 다음 아홉 가지로 알려져 있다. 표준 본문은 유료라, 아래 설명은 각 특성의 취지를 풀어 쓴 것이다.
| 특성 | 취지 | 깨진 예 |
|---|---|---|
| 필요(necessary) | 빼면 결함이 생기는가 | 아무도 원하지 않는데 “있으면 좋아서” 들어간 요구 |
| 적절(appropriate) | 그 층위에 맞는 상세도인가 | 시스템 요구에 특정 제품명 지정 |
| 명확(unambiguous) | 한 가지로만 해석되는가 | “빠르게”, “적절히” |
| 완전(complete) | 혼자서 이해되는가 | “위와 같이 처리한다” |
| 단일(singular) | 하나만 말하는가 | “저장하고 알림을 보낸다” |
| 실현 가능(feasible) | 비용·일정·기술 안에서 가능한가 | “장애 0건” |
| 검증 가능(verifiable) | 충족 여부를 판정할 수 있는가 | “사용하기 쉽다” |
| 정확(correct) | 원천(필요·상위 요구)을 정확히 반영하는가 | 상위 요구의 300ms 가 3s 로 옮겨짐 |
| 준수(conforming) | 합의된 문장 틀·스타일을 따르는가 | 팀마다 다른 서술 방식 |
요구사항 집합의 특성
집합 수준에서는 완전성, 일관성, 실현 가능성, 이해 가능성, 확인 가능성(able to be validated)을 본다. 개별 문장이 모두 완벽해도 집합이 깨질 수 있다.
REQ-031 세션은 마지막 활동 후 30분이 지나면 만료된다.
REQ-112 결제 화면에서는 세션이 만료되지 않는다.
└─▶ 각각은 명확·단일·검증 가능. 함께 두면 모순.
결제 화면에 머문 사용자는 31분째 만료되는가?
집합 특성은 문장을 한 줄씩 읽어서는 발견되지 않는다. 같은 대상(세션, 주문 상태)을 다루는 요구를 모아서 읽어야 한다. 그래서 요구에 대상·태그 속성을 붙여 두는 것이 실용적이다.
속성: 문장 바깥의 정보
요구사항은 문장만으로 관리되지 않는다. 표준은 요구사항 속성을 별도 절로 둔다. 실무에서 최소한으로 쓰는 속성은 이렇다.
| 속성 | 왜 필요한가 |
|---|---|
| 고유 ID | 추적과 참조(SE100 #019) |
| 근거(rationale) | 왜 이 값인지. 나중에 바꿀 때 판단 근거 |
| 출처 | 어느 이해관계자·법규·상위 요구에서 왔나 |
| 우선순위 | 범위 조정 시 기준(SE100 #017) |
| 검증 방법 | 검사·분석·시연·시험 중 무엇으로 확인하나 |
| 상태 | 제안·승인·구현·검증 완료 |
근거 칸이 특히 중요하다. “p95 300ms” 에 근거가 없으면 1년 뒤 아무도 그 숫자를 바꿀 용기를 내지 못하거나, 아무 이유 없이 바꾼다.
EARS: 문장을 틀에 넣기
Alistair Mavin 등이 Rolls-Royce 에서 제트 엔진 제어 시스템의 감항 규정을 분석하다 만든 EARS(Easy Approach to Requirements Syntax)는 2009년 RE 학회 논문(DOI)으로 처음 발표됐다. 요구가 절의 순서가 항상 같을 때 가장 읽기 쉽다는 관찰에서 출발한다.
기본 구조는 다음과 같다.
While <선택적 사전조건>, when <선택적 트리거>, the <시스템 이름> shall <시스템 응답>
규칙: 사전조건 0개 이상, 트리거 0~1개, 시스템 이름 1개, 응답 1개 이상.
| 패턴 | 키워드 | 틀 | 예 |
|---|---|---|---|
| 상시(ubiquitous) | 없음 | <시스템>은 <응답>해야 한다 |
결제 서비스는 모든 승인 요청을 기록해야 한다 |
| 상태 기반 | While | <상태>인 동안, <시스템>은 … |
점검 모드인 동안, 주문 앱은 신규 주문을 거부해야 한다 |
| 사건 기반 | When | <트리거>하면, <시스템>은 … |
결제가 승인되면, 주문 앱은 주문 번호를 표시해야 한다 |
| 선택 기능 | Where | <기능>이 있는 경우, <시스템>은 … |
포인트 기능이 있는 경우, 주문 앱은 잔액을 표시해야 한다 |
| 원치 않는 동작 | If / Then | <조건>이면, <시스템>은 … |
승인 응답이 10초 안에 오지 않으면, 주문 앱은 결제 상태를 조회해야 한다 |
| 복합 | 둘 이상 | 위 조합 | 점검 모드인 동안 관리자가 로그인하면, … |
EARS 공식 사이트는 Airbus, Bosch, NASA, Siemens 등이 이 표기법을 쓴다고 소개한다. 핵심 가치는 원치 않는 동작(If/Then) 패턴이 따로 있다는 점이다. 틀을 채우다 보면 “그럼 실패하면?” 을 묻게 된다.
요구 강도 키워드
29148 계열 문서는 구속력 있는 요구를 “shall” 로 쓴다. 한국어 문서에서는 “~해야 한다” 를 필수로, “~하는 것이 바람직하다” 를 권고로, “~할 수 있다” 를 허용으로 고정해 두는 식으로 대응한다. 인터넷 표준의 RFC 2119·RFC 8174 처럼 키워드의 뜻을 문서 앞에 선언하는 것이 요점이다.
실무 적용
고쳐 쓰기 예
| 원문 | 문제 | EARS 로 고쳐 쓰기 |
|---|---|---|
| 시스템은 결제 실패를 적절히 처리한다 | 명확성·검증 가능성 | 카드 승인이 거절되면, 주문 앱은 거절 사유를 표시하고 결제 수단 선택 화면으로 돌아가야 한다 |
| 주문을 저장하고 매장에 알린다 | 단일성 | (1) 결제가 승인되면, 주문 앱은 주문을 저장해야 한다 (2) 주문이 저장되면, 주문 앱은 매장 단말에 알림을 보내야 한다 |
| 가능하면 오프라인에서도 동작한다 | 빠져나갈 구멍(“가능하면”) | 네트워크가 끊긴 동안, 주문 앱은 마지막으로 받은 메뉴를 표시해야 한다 |
| 관리자는 Kafka 로 이벤트를 받는다 | 적절성(층위) | 메뉴가 변경되면, 메뉴 서비스는 1분 안에 변경을 모든 매장 단말에 전달해야 한다 |
EARS 패턴 판별기
리뷰 전에 문장이 어떤 틀에 들어가는지, 어느 틀에도 안 들어가는지 표시해 두면 리뷰가 빨라진다.
import re
PATTERNS = [
("복합", r"^(.+인 동안|.+한 경우).*(하면|이면),"),
("원치 않는 동작", r"^.+(않으면|실패하면|거절되면|이면),"),
("상태 기반", r"^.+인 동안,"),
("사건 기반", r"^.+(되면|하면),"),
("선택 기능", r"^.+(있는 경우|지원하는 경우),"),
]
VAGUE = ["적절히", "가능하면", "빠르게", "충분히", "등"]
def classify(req: str):
if not req.rstrip(".").endswith("해야 한다"):
return "틀 밖(강도 키워드 없음)"
for name, pat in PATTERNS:
if re.search(pat, req):
return name
return "상시"
reqs = [
"결제 서비스는 모든 승인 요청을 기록해야 한다.",
"점검 모드인 동안, 주문 앱은 신규 주문을 거부해야 한다.",
"결제가 승인되면, 주문 앱은 주문 번호를 표시해야 한다.",
"승인 응답이 10초 안에 오지 않으면, 주문 앱은 결제 상태를 조회해야 한다.",
"시스템은 결제 실패를 적절히 처리한다.",
]
for r in reqs:
flags = [w for w in VAGUE if w in r]
print(f"[{classify(r)}] {r}" + (f" ⚠ 모호어: {flags}" if flags else ""))
[상시] 결제 서비스는 모든 승인 요청을 기록해야 한다.
[상태 기반] 점검 모드인 동안, 주문 앱은 신규 주문을 거부해야 한다.
[사건 기반] 결제가 승인되면, 주문 앱은 주문 번호를 표시해야 한다.
[원치 않는 동작] 승인 응답이 10초 안에 오지 않으면, 주문 앱은 결제 상태를 조회해야 한다.
[틀 밖(강도 키워드 없음)] 시스템은 결제 실패를 적절히 처리한다. ⚠ 모호어: ['적절히']
한국어 어미 기반 정규식이라 오탐이 있다. 목적은 완벽한 분류가 아니라 틀 밖 문장을 눈에 띄게 하는 것이다.
흔한 오해와 함정
- “29148 을 따른다 = 9장 목차대로 문서를 만든다.” 목차는 빠뜨리지 않기 위한 것이다. 표준의 핵심은 문장·집합·속성의 특성이고, 애자일 백로그에도 그대로 적용된다.
- 문장 품질만 본다. 집합 수준의 모순과 누락은 개별 리뷰로 안 잡힌다. 같은 대상을 다루는 요구를 모아 읽는 리뷰를 따로 한다.
- 적절성을 무시한다. 상위 요구에 해법이 들어가면 설계 선택지가 사라진다. 기술 선택은 설계 결정 기록으로 보낸다.
- 근거 없는 숫자. 검증 가능하게 만들려고 숫자를 넣었는데 근거가 없으면, 그 숫자가 새로운 모호함이 된다.
- 틀을 신앙처럼 따른다. EARS 에 억지로 넣느라 문장이 부자연스러워지면 의미가 오히려 흐려진다. 틀은 기본값이지 법이 아니다.
확인 문제
- IEEE 830-1998 과 ISO/IEC/IEEE 29148 의 관계를 설명하라.
- 개별 요구의 “적절(appropriate)” 특성이 깨진 예를 하나 들고 고쳐 써라.
- 각각 완벽한 두 요구가 집합 수준에서 문제를 일으키는 예를 들어 보라.
- EARS 의 원치 않는 동작 패턴이 실무에서 특히 유용한 이유는?
- 요구사항 속성 중 “근거” 를 기록하지 않으면 어떤 일이 생기는가?
풀이
- IEEE 830-1998 은 SRS 권고 관행이었고 29148:2011 로 대체됐다. 29148 은 2018년 2판으로 개정돼 현행이다.
- 예: “시스템 요구: 알림은 Firebase 로 보내야 한다” → “주문이 준비되면, 주문 앱은 30초 안에 고객 기기에 알림을 보내야 한다”. 제품 선택은 설계로 보낸다.
- “모든 개인정보는 30일 뒤 삭제한다” 와 “주문 내역은 5년간 보관한다” — 주문 내역에 개인정보가 들어 있으면 모순이다.
- 문장 틀 자체가 실패·예외 조건을 위한 자리를 요구하므로, 성공 경로만 적고 끝내는 습관을 막는다.
- 값을 바꿀 때 판단 근거가 없다. 아무도 못 바꾸거나, 이유 없이 바뀌어 원래 목적(법규, 계약, 사용자 조사 결과)이 깨진다.
더 읽을거리 (References)
- ISO/IEC/IEEE 29148:2018 — Systems and software engineering — Life cycle processes — Requirements engineering
- IEEE 830-1998 — Recommended Practice for Software Requirements Specifications (superseded)
- A. Mavin, P. Wilkinson, A. Harwood, M. Novak, Easy Approach to Requirements Syntax (EARS), RE 2009 / EARS 공식 사이트
- RFC 2119, RFC 8174
- CS300: 요구사항 분석