+ 경계·실패·동시성 사례를 폭넓고 균형 있게 다뤘다.
- 모호한 요구를 가정했고 문자열 연산 설명도 틀렸다.
함수나 기능의 테스트 케이스를 설계합니다. 정상 경로만 보지 않고 경계값과 실패 경로를 먼저 찾아줍니다.
| 분류 | 개발 › 코딩 |
|---|---|
| 태그 | 검토개발자표코드 |
Design test cases for this code. ***Cases first, test code later.*** Categories: 1. Happy path — **minimal** 2. **Boundaries** — zero, empty, maximum, one more and one less 3. **Failure paths** — bad input, no permission, external call fails 4. State-dependent — reordered, run concurrently 5. Data shape — null, type mismatch, encoding Output a table: case / input / expected result / why this case is needed. Rules: - ***Produce more of 2 and 3 than of 1.*** That is where bugs live. - ***Mark any case the current code would probably fail.*** **This is the yield of the exercise.** - **Write expected results from the requirements, not from what the code does.** - If the requirements are too unclear to set an expected result, **ask.**
현재 코드 동작을 보고 기대 결과를 적으면 아무것도 검증하지 못한다. 이 프롬프트는 요구사항에서 기대 결과를 뽑고, 정상 경로보다 경계값과 실패 경로를 더 많이 만든다. 지금 코드가 통과하지 못할 것 같은 케이스를 표시하는 게 이 작업의 수확이다.
ChatGPT는 필수 범주를 가장 충실히 다뤘지만 일부 가정과 계산 설명이 부정확하다. Gemini는 구체적이나 누락과 임의 기대값이 있고, [C]는 답이 없다.
+ 경계·실패·동시성 사례를 폭넓고 균형 있게 다뤘다.
- 모호한 요구를 가정했고 문자열 연산 설명도 틀렸다.
+ 실패 예상 사례와 실제 반환값을 구체적으로 표시했다.
- 미정 정책을 임의 기대값으로 쓴 뒤 뒤늦게 질문했다.
| 기준 | ChatGPT | Gemini | 앞선 모델 |
|---|---|---|---|
| 지시 준수 | 8 | 7 | ChatGPT +14% |
| 정확성 | 6 | 6 | 동점 |
| 구체성 | 8 | 8 | 동점 |
| 구성·가독성 | 8 | 9 | Gemini +13% |
| 분량 적정성 | 8 | 7 | ChatGPT +14% |
gpt-5.6-sol가 모델 이름을 가린 채 1~10점으로 채점했습니다 (2026-09-24). 측정값이 아니라 AI 심사 결과입니다.
같은 입력을 세 모델에 넣어 받은 답을 그대로 옮겼습니다. 각 CLI(에이전트 하네스)에서 실행했습니다. ChatGPT·Claude 앱이나 웹에서는 답이 다를 수 있습니다.
요구사항: 장바구니에서 쿠폰을 적용하면 최종 결제 금액을 계산한다. 쿠폰은 정액 할인(원 단위)과 정률 할인(%) 두 종류가 있고, 최종 금액은 0원 미만으로 내려갈 수 없다. 한 주문에 쿠폰은 최대 1개만 적용 가능하며, 만료된 쿠폰이나 최소 주문금액 미달 시에는 적용되지 않는다.
코드: function applyCoupon(orderAmount, coupon) {
if (coupon.type === 'fixed') {
return orderAmount - coupon.value;
} else if (coupon.type === 'percent') {
return orderAmount * (1 - coupon.value / 100);
}
return orderAmount;
}전제: coupon에 expired, minOrderAmount 필드가 있고, 잘못된 입력은 “쿠폰을 적용하지 않고 오류를 반환”하는 것으로 해석했습니다. 오류 형식과 쿠폰 금액의 최대 허용치는 요구사항에 없습니다.
| 구분 | case | input | expected result | why this case is needed |
|---|---|---|---|---|
| 행복 경로 | 정액 할인 최소 정상 사례 | orderAmount=1000, {type:"fixed", value:100} |
최종 금액 900원 |
기본 정액 할인 동작 확인 |
| 행복 경로 | 정률 할인 최소 정상 사례 | orderAmount=1000, {type:"percent", value:10} |
최종 금액 900원 |
기본 정률 할인 동작 확인 |
| 경계 | 주문금액 0원, 정액 할인 | 0, {type:"fixed", value:100} |
0원 |
최종 금액 음수 방지 확인 ⚠️ 현재 코드: -100 |
| 경계 | 주문금액 0원, 정률 할인 | 0, {type:"percent", value:10} |
0원 |
0원 계산과 하한 확인 |
| 경계 | 할인액이 주문금액과 동일 | 1000, {type:"fixed", value:1000} |
0원 |
정확히 0원이 되는 경계 확인 |
| 경계 | 할인액이 1원 적음 | 1000, {type:"fixed", value:999} |
1원 |
0원 직전 값 확인 |
| 경계 | 할인액이 1원 초과 | 1000, {type:"fixed", value:1001} |
0원 |
하한 초과 확인 ⚠️ 현재 코드: -1 |
| 경계 | 정률 할인 0% | 1000, {type:"percent", value:0} |
1000원 |
할인 없음 경계 확인 |
| 경계 | 정률 할인 1% | 1000, {type:"percent", value:1} |
990원 |
최소 유효 할인 확인 |
| 경계 | 정률 할인 100% | 1000, {type:"percent", value:100} |
0원 |
정률 할인 최대치로 해석되는 경계 확인 |
| 경계 | 정률 할인 100% 초과 | 1000, {type:"percent", value:101} |
0원 |
최종 금액 하한 확인 ⚠️ 현재 코드: -10 |
| 경계 | 최소 주문금액과 정확히 일치 | 1000, {type:"fixed", value:100, minOrderAmount:1000, expired:false} |
쿠폰 적용, 900원 |
최소 주문금액 경계 확인 |
| 경계 | 최소 주문금액보다 1원 적음 | 999, {type:"fixed", value:100, minOrderAmount:1000, expired:false} |
쿠폰 미적용, 999원 |
최소 주문금액 조건 확인 ⚠️ 현재 코드: 쿠폰 적용 |
| 경계 | 최소 주문금액보다 1원 많음 | 1001, {type:"fixed", value:100, minOrderAmount:1000, expired:false} |
쿠폰 적용, 901원 |
최소 주문금액 조건의 반대 경계 확인 ⚠️ 현재 코드: 조건 무시 |
| 경계 | 만료 시각 직전 | 1000, 만료되지 않은 쿠폰 |
쿠폰 적용 | 만료 판정 경계 확인 ⚠️ 현재 코드: 만료 정보 무시 |
| 경계 | 만료 시각 도달/직후 | 1000, 만료된 쿠폰 |
쿠폰 미적용, 1000원 |
만료 쿠폰 거부 확인 ⚠️ 현재 코드: 만료 정보 무시 |
| 실패 | 알 수 없는 쿠폰 타입 | 1000, {type:"bogus", value:100} |
오류 또는 쿠폰 미적용, 1000원 |
지원하지 않는 타입 방어 확인 |
| 실패 | 쿠폰 객체 null |
1000, null |
오류로 거부 | null 입력 처리 확인 ⚠️ 현재 코드: TypeError |
| 실패 | 쿠폰 객체 없음 | 1000, undefined |
오류로 거부 | 필수 입력 누락 확인 ⚠️ 현재 코드: TypeError |
| 실패 | 정액 할인값 타입 불일치 | 1000, {type:"fixed", value:"100"} |
오류로 거부 | 문자열 숫자의 암묵적 변환 방지 확인 ⚠️ 현재 코드: 900이 될 가능성 |
| 실패 | 정률 할인값 타입 불일치 | 1000, {type:"percent", value:"10"} |
오류로 거부 | 잘못된 데이터 타입 검증 확인 ⚠️ 현재 코드: 900이 될 가능성 |
| 실패 | 할인값 음수 | 1000, {type:"fixed", value:-100} |
오류로 거부 | 음수 할인으로 금액이 증가하는 문제 방지 ⚠️ 현재 코드: 1100 |
| 실패 | 주문금액 타입 불일치 | "1000", {type:"fixed", value:100} |
오류로 거부 | 주문금액 검증 확인 ⚠️ 현재 코드: "1000100" 가능 |
| 실패 | 주문금액 null |
null, {type:"fixed", value:100} |
오류로 거부 | null 산술 처리 방지 ⚠️ 현재 코드: -100 |
| 실패 | 숫자가 아닌 문자열 인코딩 | "₩1,000", {type:"fixed", value:100} |
오류로 거부 | 통화 문자열 파싱 정책 확인 |
| 실패 | 쿠폰 적용 권한 없음 | 권한 없는 사용자가 정상 쿠폰 적용 시도 | 권한 오류, 주문 금액 불변 | 권한 검사를 우회하지 않는지 확인 ⚠️ 현재 코드: 권한 검사 없음 |
| 실패 | 외부 쿠폰 검증 서비스 실패 | 검증 API 타임아웃/5xx | 안전하게 실패하고 쿠폰 미적용 | 외부 검증 연동 시 금액 오계산 방지 ⚠️ 현재 함수에는 외부 호출/실패 처리가 없음 |
| 상태 의존 | 쿠폰 2개 연속 적용 | 동일 주문에 쿠폰 A 적용 후 B 적용 | 두 번째 쿠폰 거부, 최대 1개 유지 | 쿠폰 1개 제한 확인 ⚠️ 현재 함수만으로는 상태 제한 불가 |
| 상태 의존 | 쿠폰 적용 순서 변경 | A→B, B→A | 어떤 순서에서도 1개만 적용되며 정책에 맞게 처리 | 순서 의존 버그 확인 ⚠️ 현재 함수는 매번 독립 계산 |
| 상태 의존 | 동시 적용 | 같은 주문에 두 요청이 동시에 쿠폰 적용 | 하나만 성공하고 다른 하나는 거부 | 최대 1개 제한의 경쟁 조건 확인 ⚠️ 현재 함수는 동시성 제어 불가 |
| 데이터 형태 | 쿠폰 필드 누락 | {type:"fixed"} |
오류로 거부 | 필수 value 검증 확인 ⚠️ 현재 코드: NaN |
| 데이터 형태 | 쿠폰 타입 대소문자 차이 | {type:"FIXED", value:100} |
오류 또는 명시된 정규화 정책 적용 | 타입 비교 정책 확인 |
| 데이터 형태 | 소수점 금액 | 1000.5, {type:"percent", value:10} |
통화 반올림 규칙에 따라 일관되게 계산 | 원 단위 금액 처리 규칙 확인 |
| 데이터 형태 | 매우 큰 정상 숫자 | Number.MAX_SAFE_INTEGER 수준의 주문금액 |
정밀도 손상 없이 계산하거나 오류로 거부 | 금액 overflow/정밀도 확인 |
특히 현재 코드는 최종 금액 0원 미만 방지, 만료 여부, 최소 주문금액, 입력 검증, 권한, 동시 적용 제한을 처리하지 않으므로 해당 사례들이 주요 실패 예상 지점입니다.
정확한 테스트 기대값을 확정하려면 다음 정책이 추가로 필요합니다: 금액 소수점/반올림 규칙, 할인율 100% 초과 허용 여부, 오류의 반환 형식, 쿠폰의 최대 할인값, 외부 검증 실패 시 오류인지 쿠폰 미적용인지.
| 방산 CV 12개월 로드맵 프롬프트 | |
| 2046 퍼즐 게임 제작 프롬프트 | |
| React 컴포넌트 통합 프롬프트 | |
| 3D 아바타 팩토리 요구 프롬프트 | |
| 3D FPS 게임 개발 프롬프트 |