구글 테스팅 블로그의 CRAP 지표(2011)가 해커뉴스에 재등장, 커버리지 대신 분기만 잰다는 반론과 옛 동료 회고까지
- 구글 테스팅 블로그가 2011년 공개한 CRAP 지표는 함수 복잡도와 테스트 커버리지를 묶은 CRAP1(m) = comp(m)^2 * (1 - cov(m)/100)^3 + comp(m) 공식으로, 복잡한 코드는 테스트가 적다는 전제에서 나쁜 코드를 탐지하려는 것임
- 제목의 CRAP은 코드 리뷰에서의 Change Risk Anti-Pattern을 뜻하며, 원문 제목은 "This code is CRAP"인데 해커뉴스 표시 제목에서는 단어 하나가 빠졌다는 지적이 나옴
- 댓글에서는 사이클로매틱 복잡도 같은 지표가 설계 품질의 대리값으로 과대평가됐다고 비판함. 간접 호출도 조건 분기이고, 복잡도가 낮은 코드는 오히려 장황한 경우가 많으며 객체 구조에 복잡도를 숨겨 지표를 게임할 수 있다는 것
- 커버리지를 공식의 핵심 변수로 둔 점에 반론이 몰림. 커버리지를 강제하는 코드베이스가 동작 커버리지는 더 나쁘다는 굿하트 법칙 사례가 나오고, AI 생성 커밋이 단위 테스트를 10배로 늘려 커버리지가 쓸모없는 파라미터가 됐다는 의견도 나옴
- CRAP 점수를 계산하는 도구로 Rust의 cargo-crap과 Go의 go-crap이 언급됐고, 한 댓글은 cargo-crap 준수를 위해 에이전트를 밤새 돌렸더니 diff가 코드베이스 40%를 건드려 한 번에 머지할 수 없었다고 밝힘
Hacker News opinions
2026년 구글은 이런 장난 같은 글 절대 못 쓸 거임.
아침에 이런 옛 글이 올라올 줄은 몰랐음. 예전 스타트업에서 Alberto랑 Bob이랑 같이 일했는데, 오늘 이걸 본 다른 사람들도 반가울 듯.
제목이 편집된 거임. 원래는 "This code is CRAP"이고 CRAP은 리뷰 중인 변경의 Change Risk Anti-Pattern을 뜻함. (2011) 표시도 빠졌음.
이 업계는 복잡도 지표 쪽으로 너무 많이 기울었음. Sandi Metz의 All the Little Things 강연에서 사이클로매틱 복잡도가 매 단계 설계 품질의 대리값처럼 소개되는데, OO 메서드 디스패치로 생기는 제어 흐름 간접성은 그 지표에 안 잡힘. 짧은 함수가 한때 유행이었다가 지금은 긴 함수가 트렌드인 것만 봐도 그렇고.
DFS나 AI를 좀 쓰면 이 지표를 현대화할 수 있을 듯. 해석 중에 몇 단계 추상화를 거치는지, 논리문이 얼마나 흩어져 있는지 같은 걸 재는 식으로.
Hillel Wayne이 소프트웨어 품질의 실증 근거에 대해 한 강연을 봤는데, 짧은 함수나 복잡도 줄이기, TDD 같은 유행은 뒷받침이 없었음. 확실한 원칙은 코드 양을 줄이는 것과 사람을 혹사하지 않는 것 두 가지뿐이었음.
사이클로매틱 복잡도는 설계 품질이 아니라 분기를 재는 지표임. 복잡도 낮은 코드는 그냥 장황한 경우가 많았고, 객체 사이에 복잡도를 숨겨서 지표를 게임하는 것도 가능함.
간접 호출은 전부 조건 분기임. 조건이 시간적으로도 공간적으로도 아주 멀리 떨어져 있을 뿐.
PG-13 면책 문구가 아이러니하게 느껴짐. 요즘 각 잡힌 기업 메시지에서는 상상도 못 할 문장임. 근데 그 문구가 제목이랑 URL에서 이미 단어를 쓴 다음에 나옴.
CRAP 공식이 커버리지를 핵심 지표로 쓰는 게 틀렸음. 처음부터 올바르게 작성하는 코드가 많아서 커버리지가 애초에 적용 대상이 아닌 경우가 많음. 코드가 테스트되지 않는 이유는 복잡해서가 아니라 단순해서인 경우도 많고.
회사 코드베이스를 cargo-crap 준수로 만들려고 에이전트를 밤새 돌린 적이 있는데, diff가 코드베이스 40%를 건드려서 한 번에 머지하는 건 무리였음. 지금은 기회 될 때마다 조금씩 하고 있음.
AI 생성 커밋이 예전보다 단위 테스트를 10배 많이 넣는데 상당수가 의미 없고 동어반복임. CRAP1 계수를 업데이트해야 할 듯. 아니면 커버리지가 노이즈가 너무 커져서 아예 못 쓰는 파라미터가 될 수도 있고.
LLM 나오기 전에도 단위 테스트가 별로 유용하지 않아서 CI에서 막았음. 지금은 순마이너스임. 통합 테스트랑 e2e 몇 개면 단위 테스트가 하는 일 이상을 함.
커버리지를 강제하는 코드베이스가 동작 커버리지는 더 나쁜 경우를 봤음. 굿하트 법칙의 전형임. 테스트가 코드를 실행하긴 해도 입력에 따라 올바른 출력이 나오는지 확인 안 하는 건 아주 쉬움.
측정값은 그걸 보고 행동을 취해서 실제로 나아질 때만 유용함. 측정은 쉬운데 취할 행동이 없는 지표가 많음. 속도 지표가 대표적인데, 속도로 청구서를 낼 수는 없음.
Rust는 cargo-crap, Go는 go-crap 같은 CRAP 점수 계산 도구가 있음. 아직 실전에서 써본 적은 없지만.