
테스트는 사양의 고정: AI에게 작성하게 하는 시대의 '수정해도 되는 테스트'의 경계선
요약
UE5 C++ 환경에서 AI(Claude Code)를 활용해 자동 테스트를 도입하고 운용하는 실전 경험을 다룹니다. 테스트가 모두 통과함에도 실제 게임 플레이에서 오류가 발생했던 사례를 통해, 테스트를 사양의 고정값으로 정의하고 수정 가능한 범위를 명확히 하는 관리 전략을 제시합니다.
핵심 포인트
- 테스트는 게임 사양 그 자체이며, 사양이 변경될 때만 수정해야 함
- AI가 테스트를 작성할 경우를 대비해 테스트 수정 허용 범위를 사전에 정의
- 테스트 수정 시 '// DECISION:' 주석을 통해 변경 사유를 기록하여 추적성 확보
- 단위 테스트 통과가 전체 시스템의 정상 동작을 보장하지 않음을 경고
이 기사의 요점을 3줄로.
- 첫날에 결정한 것은 "테스트를 건드리지 마라"가 아니라,
"어떤 상황이라면 건드려도 되는가"의 분류였다 -
테스트가 109건 모두 통과하고 있는 상태에서, 실기(実機)에서는 적의 공격이 맞지 않는 일이 발생했다 - 최종적으로 "
테스트는 게임의 사양 그 자체. 단, 사양이 바뀌었을 때만 다시 작성한다"로 결론을 내렸다. 이를 위해 어떤 테스트가 무엇을 지키고 있는지를 코드에 라벨(Label)로 작성하고 있다
지난번에 작성한 UE5의 C++에 자동 테스트를 도입한 기록의 후속편입니다. 지난번에는 "어떻게 도입했는가", 이번에는 "도입한 후 어떻게 운용하고 있는가"에 대한 이야기입니다.
이 기사 또한 "이렇게 해야 한다"가 아니라, **"내가 이렇게 생각하고 이렇게 운용하고 있다"**라는 기록입니다. 테스트의 방식은 다양하게 논의되고 있는 부분이므로, 하나의 생각으로서 읽어주시면 감사하겠습니다.
또한, 이 기사에 등장하는 시각·건수는 모두 본인의 리포지토리(Repository) git 이력과 테스트 코드에서 실측한 것입니다. 당시의 기억이나 문서의 기술과 차이가 있는 부분은 git의 값을 채택했습니다.
첫날에 결정한 것
개인 개발로 UE5 게임을 만들면서, C++ 자동 테스트를 첫 커밋부터 도입하고 있습니다. 테스트의 대부분은 AI (Claude Code)에게 작성하게 하고 있습니다.
AI에게 테스트를 작성하게 한다면, 언젠가 "테스트를 완화하면 통과한다"라는 선택지가 나올 것이라고 생각했습니다. 그래서 첫날에, 테스트가 실패했을 때 무엇을 해도 되는지를 결정했습니다.
| 실패 원인 | 테스트를 편집해도 되는가 |
|---|---|
| ① 기대값이 사양과 달랐다 (사양 오인) | 사양과 대조한 후 OK |
| ... | ⑤ 구현 버그를 숨기기 위해 기대값을 완화함 |
즉, 첫날의 규칙은 "테스트를 건드리지 마라"가 아닙니다. 건드려도 되는 경우를 4가지 들고, 금지하는 것은 ⑤뿐인 형태였습니다. 금지 사항을 하나로 좁힌 이유는, 전면 금지를 하면 ①~④ 단계에서 작업이 멈추기 때문입니다.
그리고 ①~④ 단계에서 테스트를 수정했을 때는 // DECISION:
주석으로 이유를 남기는 것도 세트로 정했습니다. 나중에 "왜 이 테스트는 수정되었는가"를 추적할 수 있도록 하기 위해서입니다.
그럼에도, 109건이 통과하고 있는 상태에서 망가져 있었다
무슨 일이 일어났는가
어느 날 심야, 자동 테스트가 109건 모두 통과하고 있는 상태에서 실제로 게임을 움직여 보았더니 적의 공격이 맞지 않았습니다.
원인
충돌 판정(Hit detection)의 필터링 처리였습니다. 히트 후보를 판정 범위로 필터링할 때, 캐릭터의 위치를 "중심의 한 점"만으로 보고 있었던 것이 원인이었습니다.
그 때문에 경계 부근에 서면, "신체의 일부는 범위 내에 있는데, 중심이 범위 외"라는 이유로 후보에서 탈락하고 있었습니다.
충돌 판정은 2단계로 되어 있었습니다.
| 단계 | 하고 있는 일 | 무엇으로 판정했는가 |
|---|---|---|
| 전단 | 범위에 겹쳐 있는 캐릭터를 모음 | 신체의 형태 (캡슐 전체) |
| 후단 | 모은 후보를 필터링함 | 중심의 한 점 |
전단은 "신체의 일부라도 범위에 들어와 있으면 후보"로 넘깁니다. 그런데 후단은 "중심이 범위 외라면 제외"하며 버립니다. 전단과 후단에서 판정의 전제가 어긋나 있었습니다.
각각 단체로는 각각의 테스트가 정의한 대로 동작합니다. 전단의 테스트도 후단의 테스트도 통과합니다. 전달하는 부분만이 아무도 보지 않았던 것입니다.
왜 109건이 전부 통과하고 있었는가
109건의 내역은 Unit 96건 / Functional 13건이었습니다.
Functional Test (실제로 월드를 만들고 액터를 배치하여 동작시키는 테스트)는 13건밖에 없었고, 나머지 96건은 부품을 단체로 꺼내어 시험하는 테스트입니다. 당시의 테스트는 이런 것들이 중심이었습니다.
- 내부 라이브러리를 직접 호출
- 컴포넌트(Component)의 API를 직접 호출
- 좌표를 극단적으로 멀리 배치 (1000cm 떨어뜨리는 등)하여 판정하게 함
모두 부품이 올바르게 동작하는 것은 확인할 수 있습니다. 하지만 부품을 연결했을 때 일어나는 일을 확인하고 있었던 것은 13건뿐이었고, 그 13건조차 "경계 부근에 서는" 배치를 통과하지 않았습니다.
실제 게임에서 일어나는 것은 이런 흐름입니다.
적이 공격한다 → 충돌 판정이 실행된다 → 후보를 필터링한다 → 데미지를 준다
부품은 모두 올바르게 동작하고 있었습니다. 망가져 있었던 것은 부품끼리 값을 전달하는 부분입니다.
또 하나, 테스트하고 있는 값에도 편향이 있었습니다. 당시 테스트는 「1000cm 떨어뜨리기」와 같은 극단적인 배치뿐이었고, 실제 플레이에서 가장 자주 발생하는 「바로 근처에서, 아슬아슬하게 닿는 거리」를 통과시키지 않았던 것입니다. 이번 버그는 바로 그 거리에서만 발생하는 것이었습니다.
필요한 것은 두 가지라고 생각했습니다.
실제 경로를 통과하는 테스트를 우선할 것 (공격 → 히트 판정 → 데미지 적용 → 태그 업데이트, 라는 흐름을 그대로 통과시킴)
각 테스트가 무엇을 지키고 있는지를 코드에 명시할 것
두 번째는 후반부에 서술할 라벨(Label) 이야기로 이어집니다.
그럼 어떻게 대처했는가
git의 타임스탬프가 남아 있습니다.
22:54 구현 수정 (히트 판정 필터)
22:59 경계 배치 퇴화 방지 테스트 4건 추가 (109 → 113)
23:01 「테스트는 사양의 고정」을 영구 규칙으로 명문화
※ 커밋 메시지는 내부 함수명을 포함하고 있으므로, 여기서는 요약하여 나타냈습니다. 시각과 건수는 그대로입니다.
수정과 테스트 추가를 세트로 묶는 운영 방식은 여기서부터 시작되었습니다. 실기에서만 발견되는 버그가 나오면, 고치는 것만으로 끝내지 않습니다. 같은 일이 일어났을 때 알아챌 수 있는 상태로 만든 뒤에 종료합니다.
그리고 규칙을 추가했습니다. 다만 추가한 내용이 「금지」만은 아닙니다. 동시에 상충하는 두 가지를 만족시켜야 했습니다.
테스트는 사양의 고정. 구현을 변경할 때 테스트를 마음대로 편집하지 않는다.
단, 사양이 변할 수도 있으므로 그럴 때는 테스트를 다시 쓸 수 있도록 해둔다.
한쪽만으로는 돌아가지 않습니다. 금지만 하면 사양을 변경하는 순간 오래된 사양에 구현이 묶이게 됩니다. 반대로 자유롭게 다시 써도 된다고 하면, 「통과하지 않으니까 완화한다」와 구별할 수 없게 됩니다.
결국 첫날과 같은 결론으로 돌아왔습니다. 필요한 것은 금지가 아니라, 만져도 되는 경우의 정의입니다. 다른 점은 축이었습니다. 첫날은 「테스트를 고치는 방법이 올바른가」에 대한 이야기였지만, 이번에는 「사양이 변한 것인가, 구현의 사정으로 변한 것인가」를 구분할 필요가 있습니다.
그리고 이것은 규칙을 문장으로 쓰는 것만으로는 실현되지 않습니다. 실제로 판단하는 것은 테스트가 실패한 상황에 있는 AI이기 때문입니다. 그래서 두 가지를 준비했습니다.
어떤 테스트가 무엇을 지키고 있는지를 코드 측에 작성할 것 (라벨과 주석)
실패했을 때 무엇을 어떤 순서로 생각할지의 판단 플로우를 결정할 것
이하는 그 내용입니다.
테스트에 종류별 라벨을 붙이기
테스트 주석 서두에 라벨을 쓰기로 했습니다.
/**
* [SPEC] 공격이 적중하면 대상의 HP가 감소한다.
* 전투의 기본 계약을 고정한다.
...
| 라벨 | 의미 | 실패 시 대응 |
|---|---|---|
[SPEC] | 사양을 고정하는 테스트 | 사양이 변했을 때만 확인을 거쳐 다시 작성한다 |
[REGRESSION] | 과거 버그의 재발 방지 / 기존 동작의 퇴화 제로 보장 | 건드리지 않는다. 구현을 수정한다 |
[UNIT] | 구현 내부의 단위 테스트 (Unit Test) | 리팩터링 (Refactoring)에 따라 변경해도 좋다 |
과거 버그 유래의 [REGRESSION]에는 발생일과 증상을 적습니다.
/**
* [REGRESSION] 2026-04-27 22:54: 히트 판정 필터가 중심 1점만을 보고 있어,
* 경계 부근에서 공격이 적중하지 않았던 건의 재발 방지.
...
이것이 실패하면 「과거에 고쳤던 것이 다시 망가졌다」는 의미가 됩니다. 테스트를 다시 쓰는 선택지가 처음부터 없다는 것을 알 수 있는 상태로 만들기 위한 라벨입니다.
운영해 보니 정의가 어긋난 것
[REGRESSION]은 작성했을 때의 정의(과거 버그의 재발 방지)보다 더 넓게 사용하게 되었습니다.
/**
* [REGRESSION] CVar=0 (기존의 서버 권위 판정)일 때, 이 경로는 완전히 no-op
* (공격 윈도우를 기록하지 않음 · 적을 스태거(Stagger)시키지 않음). 퇴화 제로 보장.
...
CVar는 실행 시에 전환할 수 있는 설정값으로, 이 기능은 통째로 끌 수 있도록 되어 있습니다. 꺼져 있을 때 오래된 경로가 그대로 동작하는 것—그것을 고정하고 있는 테스트입니다.
이것은 과거 버그와는 관계가 없으며, 새로운 경로를 추가했을 때 오래된 경로가 망가지지 않았음을 보장하는 것입니다. 과거 버그 유래가 아니므로 날짜도 없습니다.
정의를 좁은 상태로 지키는 것보다, 실태에 맞춰 넓히는 편이 사용하기 쉬웠다는 이야기일 뿐입니다.
또한, 라벨은 배타적이지 않습니다. 하나의 파일에 [SPEC] 사양 고정 + [REGRESSION] 퇴화 방지와 같이 두 가지가 모두 붙어 있는 경우도 있습니다.
코멘트는 「무엇을・왜」를 작성한다
라벨만큼 중요하게 여기는 것이 바로 코멘트의 내용입니다.
- 이 테스트는
무엇을 테스트하고 있는가 -
무엇을 기대하고 있는가
이것을 매번 작성하게 하고 있습니다. 이유는 두 가지입니다.
하나는, AI에게 전달할 문맥(Context)으로서입니다. AI는 코드를 편집할 때 그 주변부를 거의 반드시 읽습니다.
코멘트는 「반드시 읽히는 위치」에 둘 수 있는 문맥입니다. 독자적인 구현이나 복잡한 구현이 왜 그렇게 되었는지를 그곳에 적어두면, AI가 해당 부분을 건드릴 때 그대로 효과를 발휘합니다.
또 하나는, 미래의 자신이나 혹시 함께 개발할 사람이 생겼을 때, 코멘트를 읽는 것만으로도 상황을 파악할 수 있는 상태로 만들어 두고 싶기 때문입니다. 테스트 코드를 읽고 의도를 추측하게 만드는 것은 시간 낭비입니다.
실제로 작성하고 있는 것
추상적인 이야기이므로, 제 코드에서 두 가지를 인용하겠습니다.
첫 번째는 적의 경직(Stagger) 처리입니다.
// 경직 해제 시 콤보에 당하지 않도록, 이 시점에서 전 회복시켜 둔다 (`ResolvePoiseAfterStaggerPure`).
코드가 말해줄 수 있는 것은 「경직이 풀리면 저항 수치를 전 회복한다」는 부분까지입니다. 「콤보 방지(Hame-prevention)」라는 이유는 여기에만 존재합니다. 이것이 없으면, 값을 수정할 때 「왜 전 회복인가, 절반만 해도 되지 않을까」라는 판단이 생기게 됩니다.
두 번째는 경직 애니메이션의 사전 로드입니다.
// ★경직 몽타주도 같은 배치로 **모든 머신**에서 프리로드한다 (2026-08-06 근치).
// 이전에는 server 한정 블록에서 LoadSynchronous를 사용했기 때문에 **client에는 한 번도 로드되지 않았고**,
// `PlayHitReactionLocal`이 client에서 항상 「미설정」으로 조기 리턴(early return)되는 문제가 있었다
...
(코멘트 중의 **는 제가 Markdown 용도로 강조를 위해 사용한 것입니다)
「왜 모든 머신에서 로드하는가」에 대한 답이, 과거의 버그 그 자체가 되어 있습니다. 이것이 없으면, 향후 최적화 과정에서 「서버에서만 해도 되지 않을까」라며 이전 상태로 되돌아갈 가능성이 있습니다.
즉, 이 코멘트는 퇴화 방지 테스트와 동일한 역할을 코드 측면에서 수행하고 있습니다. 테스트가 「깨지면 실패함」으로 방어한다면, 코멘트는 「건드리기 전에 읽게 함」으로 방어합니다. 앞서 작성한 [REGRESSION]에 발생일과 증상을 적는 것도 같은 발상입니다.
「반드시 읽힌다」는 양날의 검
하지만 코멘트가 반드시 좋은 결과만을 가져오는 것은 아니라는 지적이 있습니다. 제 프로젝트에서도 실제로 그런 일이 있었습니다.
개발 첫날에 작성한 「사망 처리는 나중에 구현할 것」이라는 TODO 코멘트가, 구현이 완료된 후에도 지워지지 않고 남아 있었습니다. 그리고 약 2개월 후, AI 리뷰가 그것을 근거로 「사망 처리가 미구현됨」이라는 잘못된 지적을 내놓았습니다.
이 글을 쓰기 위해 코멘트를 전수 조사해 본 결과, 동일한 유형의 코멘트가 8곳 발견되었습니다. 구현이 완료된 기능을 「구현 예정」이라고 적어둔 채, 철거된 시스템을 「추가 예정」이라고 적어둔 채. 그중에는 이미 오래전에 폐지한 옛 설계 규칙을 「원칙」이라며 계속 적어 내려가고 있는 것도 있었습니다.
반드시 읽히기 때문에, 잘못된 코멘트는 없는 코멘트보다 나쁩니다. 그래서 전수 조사와 동시에 규약에 한 줄을 추가했습니다. 미래를 이야기하는 코멘트(「~로 구현 예정」)는 그것을 구현한 커밋과 동일한 커밋에서 삭제하거나, 「구현 완료・구현 위치는 여기」로 다시 작성한다.
토큰(Token) 비용
또 다른 실무적인 제약은, 코멘트가 문맥량(Context window usage)을 늘린다는 점입니다. 이것도 측정해 보았습니다.
제 프로젝트는 코멘트를 일본어로 작성하고 있습니다. 행수로 계산하면 코멘트는 약 26%이지만, 토큰으로 개략적으로 계산하면 약 50%가 됩니다. 코드는 ASCII 기준으로 3~4글자가 1토큰인 반면, 일본어는 거의 1글자가 1토큰이기 때문입니다 (이 비율은 토크나이저(Tokenizer)에 따라 달라집니다).
다만, 이 비용이 온전히 발생하는 것은 「파일 전체를 읽게 했을 때」입니다. 실제 작업에서 AI는 검색을 통해 해당 부분을 특정하고 그 주변부만 읽습니다. 지불하는 비용은 건드리는 함수 주변의 코멘트 분량뿐이며, 세션 전체로 보면 오차 범위 내에 있습니다.
그렇다면 영어로 쓰면 토큰은 1/2~1/3 정도로 충분하겠지만, 일본어로 계속 쓰게 하고 있습니다. 이 프로젝트의 코멘트 독자에는 AI뿐만 아니라 저도 포함되어 있으며, AI의 주장을 마지막에 감사(Audit)하는 것은 저이기 때문입니다.
문서도 인수인계 메모도 커밋 메시지(Commit message)도 일본어입니다. 코드의 코멘트 계층만 영어로 하면 지식의 체계가 두 언어로 나뉩니다. AI는 어느 쪽이든 읽을 수 있으므로, 언어는 인간 측 독자인 저에게 맞추고 있습니다.
대신 줄이고 있는 것은 양 쪽입니다. 규약은 첫날부터 "통상적인 코멘트는 WHY만 작성한다(WHAT은 쓰지 않고 이름으로 표현한다)"였습니다. 이 글을 쓰기 위해 샘플링해 본 결과, 코드의 반복에 해당하는 코멘트——코드를 보면 알 수 있는 것을 그대로 읊는 것——는 거의 제로였습니다.
그렇다면 무엇이 토큰의 절반을 차지하고 있을까요? 내역을 살펴보니, 절반은 헤더 파일(Header file)에 쓰게 하는 "이 함수를 호출하면 어떤 일이 일어나는가"였습니다. 통신의 방향, 서버 측에서 실행되는 처리의 요약, 어떤 설정에서 무효화되는지 등입니다. 구현 파일(Implementation file)을 열지 않고도 호출 여부를 판단하기 위한 계약(Contract)의 기술입니다.
(규약에는 첫날부터 "WHY만"이라는 문구와 나란히 "네트워크 동작을 동반하는 코드에는 반드시 태그로 명시한다"라는 절대 규칙도 적혀 있었습니다. 그 규칙에 이끌려 계약 기술도 계속 작성되어 왔던 것이라 생각합니다. 이 글을 위해 비율을 측정하고 나서야 처음 깨달았기에, 규약을 실태에 맞게 다시 썼습니다——"쓰지 않는 것은 코드에서 복원할 수 있는 WHAT뿐. 복원할 수 없는 것은 WHAT이라도 쓴다"로)
나머지 절반은 구현 측의 "왜"에 날짜나 과거 버그의 경위까지 포함해서 쓰게 하고 있기 때문입니다.
즉, 최대한 줄인 상태에서 이 정도 양입니다. AI가 반드시 읽는 곳에는 그곳에 둘 가치가 있는 정보만을 남긴다——그 선별의 결과가 이 비율이라는 것을 알았기에, 이 비용은 인지한 상태에서 지불하고 있습니다.
실패했을 때의 판단 플로우
라벨만으로는 부족해서, 실패했을 때 무엇을 생각할지의 순서도 정했습니다.
테스트가 실패함
↓
[REGRESSION] 인가?
...
분기의 핵심은 "사양이 바뀐 것인가, 구현의 편의 때문에 바뀐 것인가"라는 단 한 점입니다. 이 부분을 매번 명확히 하지 않으면, 테스트는 "통과시키기 위해 느슨하게 만드는 것"으로 변질됩니다.
실제 비율
현재의 내역입니다 (2026-08-06 시점. 개발 중이므로 매일 늘어납니다).
| 라벨 | 파일 수 |
|---|---|
[SPEC] | 137 |
[UNIT] | 25 |
[REGRESSION] | 4 |
테스트 자체는 약 1,200건이 있으며, 위 숫자는 파일 수입니다 (1개 파일에 여러 테스트가 들어있기 때문). 앞서 언급했듯이 라벨은 병기할 수 있으므로, 합계는 총 파일 수와 일치하지 않습니다.
[REGRESSION]은 극단적으로 적은 상태를 유지하고 있습니다. 이는 예상대로이며, 이것이 늘어난다는 것은 "실제로 돌려보지 않으면 찾을 수 없는 버그를 계속해서 내고 있다"는 의미가 됩니다.
늘어나지 않았으면 하는 라벨입니다.
[SPEC]이 대다수를 차지하는 것은 자연스럽다고 생각합니다. 테스트의 대부분은 "이렇게 동작하기로 결정했다"를 고정하기 위한 것이기 때문입니다.
규칙을 기계로 강제하지 않는 이유
테스트 내용에 관한 규칙은 모두 문장으로 되어 있습니다. Claude Code를 멈추게 하는 훅(Hook)으로는 구현하지 않았습니다.
제 프로젝트에서는 훅으로 구현한 것과 문장으로 두는 것을 구분하고 있습니다.
| 규칙의 위치 | 역할 |
|---|---|
| hook | 반드시 지켜짐. 파괴적인 git 조작 거부, 재귀적 삭제(rm -rf 등) 거부 등에 사용 |
| CLAUDE.md / 메모리 | 조언. 지켜지지 않을 때가 있음 |
이 선긋기의 결과, 테스트를 삭제하는 것은 막을 수 있지만, 느슨하게 만드는 것은 막을 수 없습니다. 재귀적 삭제는 명령어 형태로 판별할 수 있으므로 hook으로 거부할 수 있습니다. 하지만 기대값을 다시 쓰는 편집은, 차분(Diff)을 봐도 "사양이 바뀌어서 고친 것"인지 "구현의 편의를 위해 느슨하게 만든 것"인지 알 수 없습니다.
알 수 없는 것을 기계에게 판단하게 하면, Tests/를 건드릴 때마다 확인을 요청하게 되어 사양 변경 시마다 손이 멈추게 됩니다. 그래서 hook으로 하지 않는 것이 저의 판단이었습니다.
따라서 현재 운용하고 있는 방식은 다음과 같습니다.
AI가 멋대로 테스트를 다시 쓰지 않는다. "이 테스트를 이렇게 변경해야 합니다. 이유는 이렇습니다. 괜찮습니까?"라고 확인을 받은 뒤에 다시 쓴다.
이것은 약속일 뿐, 강제는 아닙니다. 지켜지지 않을 가능성은 남아 있습니다. 그렇기 때문에 판단의 근거를 코드 쪽에 남겨두어야 한다는 것이 다음 이야기입니다.
AI에게 작성하게 하더라도 결정하는 역할은 남는다
테스트를 작성하는 작업은 AI에게 맡길 수 있습니다. 제 프로젝트의 테스트는 대부분 AI가 작성했으며, 약 1,200건이 된 지금도 양을 늘리는 것 자체는 비용이 되지 않습니다.
문제는 테스트가 실패했을 때입니다.
'테스트가 떨어졌으니 고쳐라'라고 했을 때, 구현(implementation)을 수정하는 방법도 있고, 테스트를 완화해서 통과하게 만드는 방법도 있습니다. 둘 다 '테스트가 통과되는 상태'에는 도달합니다. 하지만 후자는 버그를 숨긴 채 녹색으로 만들었을 뿐입니다.
제 환경에서 실제로 그런 일이 일어났는지인지는 알 수 없습니다. 약 1,200건 전체를 다시 읽어본 것은 아니기 때문에 단언할 수는 없습니다. 아마 일어나지 않았다고 생각하지만, 확인하지 않은 것을 '일어나지 않았다'고 말할 수는 없습니다.
그래서 판단의 근거를 코드 쪽에 두었습니다.
[REGRESSION]이 붙어 있다면, 그곳은 대응 방안이 정해진 장소라고 알 수 있습니다 (구현을 수정한다. 테스트는 건드리지 않는다) - 판단 플로우가 있으면 '구현상의 사정인지, 사양 변경인지'를 매번 묻게 됩니다.
- 사양 변경이라면,
확인을 받은 후에 수정한다라는 절차가 끼어듭니다.
'테스트를 작성하는 것'은 AI에게 맡길 수 있지만, '어떤 사양을 지킬지 결정하는 것'은 맡길 수 없습니다. 약 1,200건을 넘어서는 시점에서는 전부를 사람이 다시 읽어보는 것은 불가능합니다. 다시 읽어볼 수 없다면, 다시 읽어보지 않아도 알 수 있는 형태로 남겨두어야 한다는 것이 라벨을 넣은 이유입니다.
요약
- 처음부터 지금까지 결정하고 있는 것은 '건드려도 되는 경우의 정의'입니다. 바뀐 점은 축으로, '테스트를 고치는 방법이 올바른가'에서 '사양이 변경되었는지, 구현상의 사정인지'로 바뀌었습니다.
- 109건이 통과해도 망가졌다. 그중 실제 경로를 거치는 테스트는 13건이었고, 그 13건조차 경계(boundary)의 배치를 지나지 않았습니다.
- 실기에서만 발견되는 버그는,
수정하는 것에서 끝내지 않고, 퇴화 방지 테스트와 세트로 닫는다. - 안정된 형태는 '테스트는 사양의 고정. 단, 사양이 변경되었을 때만 수정한다'입니다. 이것을 글로 쓰는 것이 아니라, 라벨과 판단 플로우로서 코드 쪽에 두었습니다.
- 테스트 내용 자체에 대해서는 기계가 강제하지 않습니다.
사양 변경인지 구현상의 사정인지를 기계가 판별할 수 없기 때문입니다. 지우는 것은 막을 수 있지만, 완화하는 것은 막을 수 없습니다 -
AI는 테스트를 대량 생산할 수 있습니다. 그렇기 때문에
지켜야 할 대상을 결정하는 역할이 인간에게 남습니다
지난 기사(테스트의 최소 구성)는 UE5의 C++에 자동 테스트를 넣은 기록에 있습니다.
토론 (Discussion)

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기