KoderKoder.ai
가격엔터프라이즈교육투자자용
로그인시작하기

제품

가격엔터프라이즈투자자용

리소스

문의하기지원교육블로그

법적 고지

개인정보 처리방침이용 약관보안허용 사용 정책악용 신고

소셜

LinkedInTwitter
Koder.ai
언어

© 2026 Koder.ai. All rights reserved.

홈›블로그›경계 케이스 중심 Claude Code 테스트 생성 프롬프트: 고신호 테스트 만들기
2025년 12월 19일·5분

경계 케이스 중심 Claude Code 테스트 생성 프롬프트: 고신호 테스트 만들기

경계, 불변성, 실패 모드를 겨냥해 해피 패스 대신 고신호 테스트를 생성하는 Claude Code 테스트 생성 프롬프트를 배워보세요.

경계 케이스 중심 Claude Code 테스트 생성 프롬프트: 고신호 테스트 만들기

왜 정상 경로(happy-path) 테스트 생성은 시간을 낭비하는가

자동 생성된 테스트 스위트는 겉으로 보기엔 인상적입니다: 수십 개의 테스트, 많은 셋업 코드, 거의 모든 함수명이 어딘가에 등장합니다. 하지만 그 테스트들 중 상당수는 단순히 “정상일 때 동작한다”는 확인에 불과합니다. 쉽게 통과하고, 버그를 거의 잡지 못하며, 읽고 유지하는 데 시간만 듭니다.

일반적인 Claude Code 테스트 생성 프롬프트에서는 모델이 본 예시 입력을 따라가는 경향이 있습니다. 겉으로 달라 보이는 변형들이 나오지만 실제로는 같은 동작만을 다루죠. 결과는 핵심을 제대로 커버하지 못하는 방대한 테스트 모음입니다.

고신호 테스트는 다릅니다. 최근의 사고를 잡아냈을 소수의 테스트들입니다. 위험한 방식으로 동작이 바뀌면 실패하고, 무해한 리팩터링에는 안정적입니다. 하나의 고신호 테스트는 스무 개의 “기대값을 반환한다” 확인보다 더 가치 있을 수 있습니다.

저가치 해피-패스 생성에는 몇 가지 뚜렷한 징후가 있습니다:

  • 많은 테스트가 입력 레이블만 다르고 실제로는 깨질 수 있는 지점을 다루지 않습니다.
  • 어서션이 얕습니다(“null 아님”, “상태가 200”) — 의미를 확인하지 않음.
  • 셋업이 테스트 대상 동작보다 무겁습니다. 그래서 사람들이 테스트를 업데이트하지 않게 됩니다.
  • 커버리지는 높아 보이지만 엣지 케이스는 untouched 상태입니다.

예를 들어 할인 코드를 적용하는 함수가 있다고 합시다. 해피-패스 테스트는 “SAVE10”이 가격을 낮춘다를 확인합니다. 실제 버그는 다른 곳에 숨어 있습니다: 0 이거나 음수인 가격, 만료된 코드, 반올림 경계, 최대 할인 한도 등. 그런 케이스들이 잘못된 합계, 화난 고객, 자정의 롤백을 유발합니다.

목표는 “테스트를 더 많이” 만드는 것에서 “더 좋은 테스트”로 옮기는 것입니다. 이를 위해 세 가지 목표를 노리세요: 경계(boundaries), 실패 모드(failure modes), 불변성(invariants).

세 가지 목표: 경계, 실패 모드, 불변성

고신호 단위 테스트를 원한다면 “더 많은 테스트”를 요구하는 것을 멈추고 세 가지 특정 유형을 요청하세요. 이것이 Claude Code 테스트 생성 프롬프트의 핵심입니다. 쓸모없는 "정상 입력에서 동작" 확인 더미 대신 실용적인 커버리지를 만듭니다.

1) 경계(버그가 숨어있는 곳)

경계는 코드가 허용하거나 생성하는 것의 가장자리입니다. 많은 실제 결함은 오프바이원, 빈 상태, 타임아웃 문제 등 해피 패스에서는 나타나지 않습니다.

최소/최대(0, 1, 최대 길이), 빈 vs 존재("", [], nil), 오프바이원(n-1, n, n+1), 시간 제한(컷오프 근처) 같은 관점으로 생각하세요.

예: API가 “최대 100개 항목”을 허용한다면 3개만 테스트하지 말고 100과 101을 테스트하세요.

2) 실패 모드(안전하게 실패함을 증명)

실패 모드는 시스템이 고장나는 방식입니다: 잘못된 입력, 누락된 의존성, 부분 결과, 상류 오류 등. 좋은 실패 모드 테스트는 이상적인 조건에서의 출력만 확인하지 않고 스트레스하에서의 동작을 검증합니다.

예: 데이터베이스 호출이 실패하면 함수가 명확한 오류를 반환하고 부분적인 데이터 기록을 피하는가?

3) 불변성(항상 지켜져야 하는 규칙)

불변성은 호출 전후에 항상 참이어야 하는 진리들입니다. 이것들은 모호한 올바름을 날카로운 어서션으로 바꿉니다.

예:

  • “잔액은 출금 후에도 절대 음수가 되면 안 된다.”
  • “ID는 빠르게 생성해도 고유해야 한다.”
  • “오류 시 상태 변경 없음”(새 행 없음, 플래그 변경 없음).

이 세 가지를 집중하면 테스트 수는 줄어들지만 각 테스트의 시그널은 커집니다.

준비: 테스트 작성 전에 작은 계약(contract) 추출하기

너무 일찍 테스트를 요청하면 공손한 “예상대로 동작한다” 확인 묶음이 나오기 쉽습니다. 간단한 해결책은 먼저 작은 계약을 작성한 다음 그 계약에서 테스트를 생성하는 것입니다. Claude Code 테스트 생성 프롬프트를 실제 버그를 찾는 도구로 바꾸는 가장 빠른 방법입니다.

유용한 계약은 한숨에 읽을 수 있을 만큼 짧아야 합니다. 입력, 출력, 그리고 다른 어떤 변경이 일어나는지를 답하는 5~10줄을 목표로 하세요.

5-10줄 계약 템플릿

계약은 코드가 아니라 평이한 언어로 작성하고, 테스트할 수 있는 내용만 포함하세요.

  • 입력: 타입, 허용 범위, 무엇이 “빈” 또는 “누락”인지
  • 출력: 반환값 또는 오류 형태, “성공”이 보장하는 것
  • 부작용: 상태 변경, DB 행, 네트워크 호출, 파일, 로그
  • 가정: 호출자가 자주 실수하는 사항(타임존, 인코딩, 인증, 정렬)
  • “절대 일어나면 안 되는 것”: 크래시, 무언의 데이터 손실, 이중 청구, 부분 쓰기

계약을 작성한 후에는 현실이 가정들을 깨뜨릴 수 있는 지점을 스캔하세요. 그 지점들이 경계(최소/최대, 0, 오버플로우, 빈 문자열, 중복)와 실패 모드(타임아웃, 권한 거부, 고유 제약 위반, 손상된 입력)가 됩니다.

작업 예: reserveInventory(itemId, qty) 같은 기능을 위한 계약

계약에는 qty가 양의 정수여야 하고 함수는 원자적이어야 하며 음수 재고를 만들면 안 된다고 쓴다면 즉시 고신호 테스트가 떠오릅니다: qty = 0, qty = 1, 사용 가능한 수량보다 큼, 동시 호출, 데이터베이스 오류를 강제로 발생시켰을 때 등.

Koder.ai 같은 비브-코딩(vibe-coding) 도구를 사용한다면 같은 워크플로를 적용하세요: 먼저 채팅에서 계약을 작성한 다음 그 계약을 직접 공격하는 테스트를 생성하세요.

프롬프트 패턴: 고신호 테스트 청사진

보다 적지만 각 테스트가 의미 있는 결과를 내는 테스트를 원할 때 이 Claude Code 테스트 생성 프롬프트를 사용하세요. 핵심은 먼저 테스트 계획을 강제하고, 계획을 승인한 후에 테스트 코드를 생성하게 하는 것입니다.

You are helping me write HIGH-SIGNAL unit tests.

Context
- Language/framework: \u003cfill in\u003e
- Function/module under test: \u003cname + short description\u003e
- Inputs: \u003ctypes, ranges, constraints\u003e
- Outputs: \u003ctypes + meaning\u003e
- Side effects/external calls: \u003cdb, network, clock, randomness\u003e

Contract (keep it small)
1) Preconditions: \u003cwhat must be true\u003e
2) Postconditions: \u003cwhat must be true after\u003e
3) Error behavior: \u003chow failures are surfaced\u003e

Task
PHASE 1 (plan only, no code):
A) Propose 6-10 tests max. Do not include “happy path” unless it protects an invariant.
B) For each test, state: intent, setup, input, expected result, and WHY it is high-signal.
C) Invariants: list 3-5 invariants and how each will be asserted.
D) Boundary matrix: propose a small matrix of boundary values (min/max/empty/null/off-by-one/too-long/invalid enum).
E) Failure modes: list negative tests that prove safe behavior (no crash, no partial write, clear error).
Stop after PHASE 1 and ask for approval.

PHASE 2 (after approval):
Generate the actual test code with clear names and minimal mocks.

실용적인 트릭은 경계 매트릭스를 간결한 표로 요구하는 것입니다. 그러면 빈칸이 쉽게 드러납니다:

DimensionValid edgeJust outside“Weird” valueExpected behavior
length0-110,000error vs clamp vs accept

만약 Claude가 20개의 테스트를 제안하면 반박하세요. 유사한 케이스를 합치고 실제 버그(오프바이원, 잘못된 오류 타입, 무언의 데이터 손실, 불변성 파괴)를 잡을 것만 남기라고 요구하세요.

단계별: 프롬프트 실행하고 출력을 테스트로 바꾸기

고신호 테스트를 더 빠르게 작성하세요
계약을 채팅에서 바로 집중된 테스트 계획으로 전환하세요.
무료로 사용해보기

원하는 동작에 대한 작고 구체적인 계약으로 시작하세요. 함수 시그니처, 입력/출력의 간단한 설명, 기존 테스트(해피-패스뿐이라도)를 붙여넣으면 모델이 실제 코드에 기반해 동작하게 됩니다.

다음으로 테스트 코드를 요청하기 전에 리스크 테이블을 요구하세요. 세 열을 요구합니다: 경계 케이스(유효 입력의 가장자리), 실패 모드(잘못된 입력, 누락 데이터, 타임아웃), 불변성(항상 유지되어야 하는 것). 각 행에 한 문장으로 “왜 이것이 깨질 수 있는가”를 적으세요. 간단한 표가 수많은 테스트 파일보다 빠르게 누락된 부분을 드러냅니다.

그다음 각 테스트가 고유한 버그 포착 목적을 가지도록 가장 작은 테스트 집합을 선택하세요. 두 테스트가 같은 이유로 실패하면 더 강한 쪽을 남기세요.

실용적인 선택 규칙:

  • 서로 다른 경계를 누르는 테스트는 유지하세요(최소, 최대, 빈값, 오프바이원).
  • 실패 시 안전한 동작을 증명하는 테스트(명확한 오류, 부분 쓰기 없음, 크래시 없음)를 유지하세요.
  • 불변성을 주장하는 테스트(정렬, 합계, 멱등성, 중복 없음)를 유지하세요.
  • 정상 입력만 반복하는 테스트는 삭제하세요.

마지막으로 각 테스트에 한 줄 설명을 추가하세요: 실패 시 어떤 버그를 잡았을지. 설명이 모호하면(“동작을 검증한다” 등) 그 테스트는 아마 저가치입니다.

불변성을 어서션으로 인코딩하는 방법

불변성은 어떤 유효한 입력을 주더라도 항상 참이어야 하는 규칙입니다. 불변성 기반 테스트에서는 먼저 규칙을 평이한 문장으로 쓰고, 이를 실패 시 명확히 드러나는 어서션으로 바꿉니다.

1~2개의 실제로 보호해 주는 불변성을 선택하세요. 좋은 불변성은 안전성(데이터 손실 없음), 일관성(같은 입력에 같은 출력), 한도(상한 초과 금지) 등입니다.

불변성을 검증 가능한 체크로 바꾸기

불변성을 짧은 문장으로 작성한 다음 테스트가 관찰할 수 있는 증거를 결정하세요: 반환값, 저장된 데이터, 방출된 이벤트, 의존성 호출 등. 강한 어서션은 결과와 부작용을 모두 확인합니다. 많은 버그가 “응답은 OK지만 잘못 쓴 경우”에 숨어 있습니다.

예: 쿠폰을 주문에 적용하는 함수가 있다면

  • 불변성: 최종 합계는 절대 음수가 아니다.
  • 불변성: 같은 쿠폰을 두 번 적용해도 두 번 할인되지 않는다.

이를 다음과 같이 어서션으로 옮깁니다:

expect(result.total).toBeGreaterThanOrEqual(0)
expect(db.getOrder(orderId).discountCents).toBe(originalDiscountCents)

“기대되는 결과를 반환한다” 같은 모호한 어서션을 피하고 구체적 규칙(비음수), 구체적 부작용(할인이 한 번만 저장됨)을 확인하세요.

테스트를 예리하게 유지하기 위한 반례 노트 추가

각 불변성마다 어떤 데이터가 그것을 위반할지에 대한 짧은 메모를 테스트에 추가하세요. 이렇게 하면 테스트가 시간이 지나며 해피-패스 확인으로 흐려지는 것을 막을 수 있습니다.

간단한 패턴:

  • 불변성을 테스트 이름에 넣으세요.
  • 출력에 대해 불변성을 어서트하세요.
  • 핵심 부작용(또는 부작용 없음)을 어서트하세요.
  • 위반 사례를 한 줄 주석으로 남기세요(예: 매우 큰 쿠폰 값, 중복 적용).

실패 모드: 안전하게 실패함을 증명하는 테스트 작성

고신호 테스트는 종종 코드가 안전하게 실패한다는 것을 확인하는 테스트입니다. 모델이 해피-패스 테스트만 작성하면 입력과 의존성이 엉망일 때 기능이 어떻게 동작하는지 거의 알 수 없습니다.

먼저 이 기능에 대해 “안전하게 실패한다”가 무엇을 의미하는지 정하세요. 명확한 타입의 오류를 반환하는가? 기본값으로 폴백하는가? 한 번 재시도한 후 중단하는가? 한 문장으로 기대 동작을 적고 테스트로 증명하세요.

Claude Code에 실패 모드 테스트를 요청할 때 목표를 엄격히 하세요: 시스템이 깨질 수 있는 방식들을 다루고 원하는 정확한 응답을 어서션하세요. 유용한 한 줄은: “많은 얕은 테스트보다 더 강한 어서션을 가진 적은 수의 테스트를 선호한다.”입니다.

좋은 테스트를 만들어주는 실패 카테고리:

  • 잘못된 입력: 형식 불일치, 필수 필드 누락, 범위 벗어남
  • 의존성 실패: 타임아웃, 500 응답, 빈 응답, 손상된 페이로드
  • 순서 문제: 이벤트 순서 어긋남, 중복, 부분 쓰기
  • 동시성: 레이스 조건, 멱등성 체크
  • 복구 동작: 오류를 반환할지 폴백할지 재시도할지

예: 사용자 생성 엔드포인트가 회원 가입 후 환영 이메일을 보내는 서비스에 호출한다고 합시다. 저가치 테스트는 “201을 반환한다”만 확인합니다. 고신호 실패 테스트는 이메일 서비스가 타임아웃될 때 사용자를 생성하고 201과 함께 "email_pending" 플래그를 반환하는지, 아니면 503을 반환하고 사용자를 생성하지 않는지 중 어떤 동작을 택하는지 확인합니다. 한 동작을 선택하고 응답과 부작용을 모두 어서트하세요.

또한 노출하지 말아야 할 것을 테스트하세요. 유효성 검사 실패 시 DB에 아무 것도 쓰이지 않는지, 의존성이 손상된 페이로드를 반환하면 처리되지 않은 예외나 스택 트레이스가 반환되지 않는지를 확인하세요.

저가치 테스트를 만드는 흔한 함정

더 적지만 더 강한 테스트를 얻으세요
경계, 실패 모드, 불변성을 타깃으로 6-10개의 테스트를 요청하세요.
테스트 생성

저가치 테스트 세트는 보통 모델이 양적 보상을 받을 때 생깁니다. Claude Code 테스트 생성 프롬프트가 "단위 테스트 20개"를 요청하면 거의 같은 변형이 많이 나오지만 새로운 것을 잡지 못합니다.

흔한 함정:

  • 서로 비슷한 테스트: 다른 문자열이나 숫자만 바꾼 같은 정상 입력 테스트 반복
  • 코드 복제: 관찰 가능한 동작 대신 private 단계나 헬퍼 호출을 어서트
  • 모든 것을 모킹: DB, 시계, 네트워크, 설정을 한꺼번에 모킹
  • 약한 어서션: 단지 "에러 없음", "null 아님", "상태 200"만 확인
  • 더러운 공유 상태: 시드된 데이터, 전역 변경, 캐시된 값 남김

예: "사용자 생성" 기능이 있다고 가정합시다. 열 개의 해피-패스 테스트는 이메일 문자열만 바꿀 수 있고 중요한 것을 놓칠 수 있습니다: 중복 이메일 거부, 빈 비밀번호 처리, 반환된 사용자 ID의 고유성 보장 등.

검토를 돕는 가드레일:

  • 각 테스트가 커버하는 위험(경계, 실패 모드, 불변성)을 이름에 명시하게 하세요.
  • 구현 전용 체크는 관찰 가능한 동작을 변경하지 않는 한 피하세요.
  • 모킹을 최소화하고 실제 통합을 소수의 테스트에서 허용하세요(가능하면).
  • 강한 어서션을 요구하세요: 정확한 출력, 상태 변경, 오류 타입/메시지.
  • 테스트가 순서에 의존하지 않도록 정리 규칙을 추가하세요.

예: 하나의 기능을 작은 강한 테스트 집합으로 바꾸기

기능: 체크아웃에서 쿠폰 코드를 적용하기.

계약(작고 테스트 가능한): 카트 소계(센트 단위)와 선택적 쿠폰을 받아 최종 합계를 센트 단위로 반환한다. 규칙: 퍼센트 쿠폰은 센트 단위로 내림(round down), 고정 쿠폰은 고정 금액을 빼고, 합계는 절대 0 미만이 될 수 없다. 쿠폰은 무효, 만료, 이미 사용되었을 수 있다.

단순히 applyCoupon()에 대한 테스트를 요청하지 마세요. 대신 이 계약에 묶인 경계 케이스, 실패 모드, 불변성을 요구하세요.

에지 동작을 강제로 만드는 경계

수학이나 검증을 깨뜨리는 입력을 고르세요: 빈 쿠폰 문자열, subtotal = 0, 최소 구매액 바로 위/아래, 고정 할인액이 소계보다 큰 경우, 33% 같은 퍼센트로 반올림이 발생하는 경우.

안전한 동작을 증명하는 실패 모드

쿠폰 조회가 실패하거나 상태가 잘못되었을 수 있다고 가정하세요: 쿠폰 서비스가 다운, 쿠폰이 만료, 사용자에 의해 이미 사용됨. 테스트는 이후 동작(쿠폰 거부와 명확한 오류, 합계 변경 없음)을 증명해야 합니다.

최소한의 고신호 테스트 세트(5개)와 각 테스트가 잡는 것:

  • 빈 코드 또는 공백 코드 거부: 빈값을 유효로 받아들이는 버그 및 트리밍 문제를 잡음.
  • 퍼센트 쿠폰 반올림(소계 101, 33%): 반올림 실수와 센트 오프바이원을 잡음.
  • 고정 할인액이 소계보다 큰 경우(소계 500, 할인 1000): 합계가 음수가 되지 않는 불변성 증명.
  • 최소 구매 경계(소계 999 vs 1000): 잘못된 비교 연산자(< vs <=) 버그를 잡음.
  • 쿠폰 조회 실패 또는 타임아웃: 안전한 폴백(할인 없음) 및 안정적 오류 처리 증명.

이 테스트들이 통과하면 중복된 해피-패스 테스트로 스위트를 채우지 않고도 일반적인 취약점을 커버한 것입니다.

고신호 AI 생성 테스트를 위한 빠른 체크리스트

코드를 이식 가능하게 유지하세요
테스트와 동작이 안정되면 소스 코드를 내보내 소유권을 유지하세요.
코드 내보내기

모델이 생성한 결과를 수락하기 전에 빠른 품질 점검을 하세요. 목표는 각 테스트가 특정하고 그럴듯한 버그로부터 여러분을 보호하는 것입니다.

체크리스트:

  • 입력별 경계: 각 입력 필드(문자열, ID, 타임스탬프, 플래그)에 대해 하나 이상의 엣지 케이스(빈값/공백, 최대 길이, 0 vs 음수, 선택적 필드 누락, 한계 초과)를 포함했는가?
  • 의존성 실패: 의존성 오작동(DB 타임아웃, 서드파티 500, 만료된 토큰) 사례를 최소 1개 포함하고 안전한 동작(명확한 오류, 부분 쓰기 없음)을 증명하는가?
  • 강한 어서션이 있는 불변성: 1-3개의 규칙을 선택하고 직접 어서트하는가? “응답이 OK” 같은 모호한 어서션을 피했는가?
  • 테스트마다 고유한 버그: 각 테스트 제목을 읽고 “이 테스트가 어떤 정확한 버그를 잡을 것인가?”라고 물어보세요. 같은 답을 하는 두 테스트는 병합하세요.
  • 삭제 테스트: 테스트를 하나 삭제해 보세요. 의미 있는 것을 잃지 않으면 그 테스트는 자리 차지를 하고 있는 것입니다.

생성 후의 실용적 팁: 테스트 이름을 “should <동작> when <엣지 조건>” 또는 “should not <나쁜 결과> when <실패>”로 바꾸세요. 깔끔하게 이름을 바꿀 수 없다면 초점이 흐려진 것입니다.

Koder.ai로 빌드한다면 이 체크리스트는 스냅샷과 롤백 워크플로와 잘 맞습니다: 테스트를 생성하고 실행하고, 새 세트가 노이즈를 추가하면서 커버리지를 개선하지 못하면 롤백하세요.

다음 단계: 이걸 반복 가능한 워크플로로 만들기

프롬프트를 일회성으로 사용하지 말고 재사용 가능한 하니스로 취급하세요. 경계, 실패 모드, 불변성을 강제하는 블루프린트 프롬프트 하나를 저장하고 새 함수, 엔드포인트, UI 흐름마다 재사용하세요.

빠르게 결과를 개선하는 간단한 습관: 각 테스트가 어떤 버그를 잡을지 한 문장으로 적게 하세요. 그 문장이 일반적이면 그 테스트는 아마 소음입니다.

제품 도메인 불변성의 살아있는 목록을 유지하세요. 머릿속에 두지 말고 저장하세요. 실제 버그를 발견할 때마다 추가하세요.

가볍게 반복할 수 있는 워크플로:

  • 작은 계약 추출: 입력, 출력, 오류 처리, 3~5개 불변성
  • 블루프린트 프롬프트 실행: 경계, 실패 모드, 불변성 + 한 줄 정당화 요구
  • 서로 다른 리스크를 커버하는 상위 5~10개 테스트만 구현
  • 리팩터링 후 프롬프트 재실행으로 새로 나타나는 리스크 확인
  • 중복 제거하고 과거 사고를 잡았을 테스트만 유지

채팅으로 앱을 빌드한다면 이 사이클을 Koder.ai(koder.ai) 내부에서 실행하세요. 계약, 계획, 생성된 테스트가 한곳에 남습니다. 리팩터링으로 동작이 예기치 않게 바뀌면 스냅샷과 롤백으로 비교하여 고신호 세트가 안정될 때까지 반복하세요.

자주 묻는 질문

함수당 얼마나 많은 단위 테스트를 생성해야 하나요?

기본 권장: 실제 버그를 잡을 수 있는 작은 집합을 목표로 하세요.

짧게 말하면 보통 함수(모듈)당 6–10개의 테스트가 좋은 기준입니다. 더 필요하면 보통 그 단위(unit)가 너무 많은 일을 하거나 계약이 불명확하다는 신호입니다.

많은 해피-패스 테스트를 생성하는 것이 왜 문제인가요?

해피-패스 테스트는 주로 예제가 여전히 동작한다는 것만 증명합니다. 운영에서 깨지는 부분을 놓치는 경향이 큽니다.

고신호 테스트는 다음을 목표로 합니다:

  • 경계(0/1/최대, 빈값/널, 오프바이원)
  • 실패 모드(타임아웃, 잘못된 입력, 종속성 오류)
  • 불변성(예: "오류 시 부분 쓰기 금지" 같은 항상 지켜져야 하는 규칙)
AI에 테스트를 생성하도록 요청하기 전에 무엇을 적어야 하나요?

먼저 짧은 계약(tiny contract) 을 적어보세요. 한 번에 숨을 고르며 읽을 수 있을 정도로 간결해야 합니다:

  • 입력: 타입, 허용 범위, 무엇이 빈값/누락으로 간주되는지
  • 출력: 성공 형태와 오류 형태
  • 부작용: 무엇이 쓰이거나 변경되는지(DB, 파일, 네트워크 등)
  • “절대 일어나면 안 되는 것”: 크래시, 무언의 데이터 손실, 이중 청구, 부분 쓰기

그 계약에서 테스트를 생성하세요. 단순 예제만으로 묻지 마세요.

어떤 경계 케이스를 우선 테스트해야 하나요?

우선 테스트할 가치가 높은 경계부터 테스트하세요:

  • 최소/최대 값(0, 1, max, max+1)
  • 빈값 vs 존재("", [], null/nil)
  • 오프바이원(n-1, n, n+1)
  • 형식의 경계(공백만 있는 문자열, 선행 0 등)
  • 시간 컷오프(만료 직전/직후)

입력 차원별로 하나 또는 두 개만 골라서 각 테스트가 고유한 위험을 다루게 하세요.

얕은 테스트 대신 좋은 '실패 모드' 테스트는 어떻게 작성하나요?

좋은 실패 모드 테스트는 두 가지를 증명합니다:

  1. 함수가 명확하고 예상 가능한 오류를 반환한다(타입/메시지/상태).
  2. 실패 시 안전하게 실패한다:
  • 부분 상태 변경이 없다
  • 내부 세부 정보가 노출되지 않는다
  • 불필요한 재시도나 의도치 않은 부작용이 없다

DB 쓰기가 관여하면 실패 후 저장소 상태를 항상 확인하세요.

불변성을 테스트 어서트로 어떻게 바꾸나요?

기본 접근: 불변성을 관찰 가능한 결과로 변환해 assertion을 작성하세요.

예:

  • “총합은 음수가 아니다” → expect(total).toBeGreaterThanOrEqual(0)
  • “오류 시 상태 변경 없음” → 새 행이 추가되지 않았음을 확인하거나 플래그가 바뀌지 않았음을 확인
  • “멱등성” → 두 번 호출하고 두 번째 호출이 상태를 변경하지 않음을 확인

반환값과 부작용을 모두 확인하는 것을 선호하세요. 많은 버그가 “정상 응답이지만 잘못된 쓰기” 형태로 숨어 있습니다.

언제 해피-패스 테스트를 유지해야 하나요?

해피-패스 테스트는 불변성을 보호하거나 중요한 통합을 검증할 때 유지할 가치가 있습니다.

유지할 만한 이유:

  • 정상 입력에서 핵심 불변성을 주장할 때(예: 반올림 규칙)
  • 호출자가 기대하는 API 계약을 고정할 때
  • 과거 사고 회귀를 방지할 때

그렇지 않다면 더 많은 클래스의 버그를 잡는 경계/실패 테스트로 교체하세요.

테스트 코드를 생성하기 전에 모델에게 무엇을 출력하라고 요청해야 하나요?

모델에게 PHASE 1: 계획만 먼저 요구하세요.

요구사항:

  • 제안된 테스트 6–10개(최대)
  • 각 테스트마다: 의도, 셋업, 입력, 기대 결과, 왜 고신호인지
  • 작은 경계 매트릭스
  • 실패 모드 목록
  • 3–5개의 불변성과 각 불변성의 어서트 방법

계획을 승인한 다음에만 코드 생성을 요청하세요. 이렇게 하면 "거의 같은 테스트 20개" 같은 결과를 피할 수 있습니다.

모킹을 너무 많이 해서 brittle한 테스트를 피하려면 어떻게 해야 하나요?

기본 원칙: 소유하지 않은 경계(DB/네트워크/시계)만 모킹하고 나머지는 실제로 두세요.

과도한 모킹을 피하려면:

  • 구현을 그대로 반영하려고 내부 헬퍼를 과도하게 모킹하지 마세요
  • 가능한 경우 인메모리(real) 또는 동작이 명확한 작은 페이크를 사용하세요
  • 어설션에 영향을 주는 경우에만 시계나 랜덤을 모킹하세요

리팩터링 후 동작이 변하지 않았는데 테스트가 깨지면 보통 과도한 모킹이나 구현 의존성 때문입니다.

AI가 생성한 테스트가 저가치인지 빠르게 어떻게 구분하나요?

간단한 삭제 테스트를 사용하세요:

  • 해당 테스트를 삭제했을 때 경계, 실패 모드, 불변성 중 아무 것도 잃지 않는다면 그 테스트는 가치가 없습니다.

중복 확인도 하세요:

  • 두 테스트가 같은 버그에 대해 실패한다면 더 강한 어서션을 가진 하나만 남기세요.
  • 어서션이 단지 “null 아님”이나 “status 200”이라면 강화하거나 제거하세요.
목차
왜 정상 경로(happy-path) 테스트 생성은 시간을 낭비하는가세 가지 목표: 경계, 실패 모드, 불변성준비: 테스트 작성 전에 작은 계약(contract) 추출하기프롬프트 패턴: 고신호 테스트 청사진단계별: 프롬프트 실행하고 출력을 테스트로 바꾸기불변성을 어서션으로 인코딩하는 방법실패 모드: 안전하게 실패함을 증명하는 테스트 작성저가치 테스트를 만드는 흔한 함정예: 하나의 기능을 작은 강한 테스트 집합으로 바꾸기고신호 AI 생성 테스트를 위한 빠른 체크리스트다음 단계: 이걸 반복 가능한 워크플로로 만들기자주 묻는 질문
공유
Koder.ai
Koder로 나만의 앱을 만들어 보세요 지금!

Koder의 힘을 이해하는 가장 좋은 방법은 직접 체험하는 것입니다.

무료로 시작데모 예약