티스토리 뷰
AI 바이브코딩 시대가 오면서 테스트 코드 작성이 압도적으로 쉬워졌다. 딸깍 한 번이면 몇 백 줄짜리 테스트 코드가 쏟아져 나온다. 주변에서는 커버리지가 올랐다고 기뻐하지만, 쏟아지는 테스트 코드를 볼 때마다 묘한 위기감을 느낀다.
"테스트는 통과하는데, 왜 시스템은 점점 더 구려지는 걸까?"
1. 원래 '높은 결합도'의 가장 큰 벌칙은 '테스트의 불가능'이었다
굳이 객체지향을 고민하고, 결합도를 낮추려 애썼던 가장 현실적인 이유는 고상한 철학 때문이 아니었다. 결합도가 높은 나쁜 구조를 만들면 당장 테스트 코드를 작성하는 것 자체가 고문이었기 때문이다.
어떤 클래스가 내부 세부 구현에 강하게 얽혀 있거나 온갖 상태에 의존하고 있으면 테스트 코드를 짜다가 화가 난다. "아, 도저히 테스트를 못 짜겠다. 구조를 쪼개야지."
즉, '테스트 작성의 괴로움'은 나쁜 아키텍처와 높은 결합도를 막아주는 가장 강력한 즉각적 피드백 장치(억제기)였다.
2. AI라는 깡패가 억제기를 부숴버렸다
하지만 요즘 AI는 완전히 다르다.
심하게 꼬인 결합도와 내부 상태, 엉망인 의존 관계를 가져다줘도 AI는 불평 한마디 하지 않는다. 무지막지한 깡생산성(체급)으로 밀어붙여 어떻게든 작동하는 200줄짜리 테스트 코드를 3초 만에 뱉어낸다.
나쁜 구조가 마땅히 받아야 할 페널티(테스트 작성 불가능)를 AI가 무력으로 대신 막아주는 셈이다. 결합도가 높든 말든 AI가 뚫어버리니 개발자는 착각에 빠진다.
"테스트가 통과하네? 내 코드 구조에 문제없나 보다."
그렇게 AI의 압도적 생산성 뒤로, 시한폭탄 같은 높은 결합도의 코드들이 차곡차곡 쌓여간다.
3. AI가 짠 테스트 코드도 결국 '사람이 평생 고쳐야 할 코드'다
여기서 간과하는 사실이 있다. AI가 3초 만에 짠 테스트 코드도 결국 프로덕션 코드의 연장선이며, 사람이 계속 읽고 유지보수해야 할 부채라는 점이다.
높은 결합도를 AI가 억지로 뚫어낸 테스트는 당연히 그 나쁜 구조의 세부 구현을 그대로 캡처하고 있다. 프로덕션 로직을 조금만 바꿔도 AI가 깡으로 뚫어둔 테스트 수십 개가 모조리 터져나간다.
생성 비용은 0원에 수렴할지 몰라도, 읽고, 이해하고, 유지보수하는 비용은 폭발한다. 나쁜 결합도를 AI의 힘으로 덮어두었더니, 그 결과물이 오히려 나쁜 구조를 영원히 고치지 못하게 만드는 벽이 되어 돌아온다.
(이렇게 '배설'된 코드들을 테스트코드라는 이유만으로 동료 개발자에게 코드리뷰로 들이미는것이 과연 정당한가? 너무 괴롭다.)
4. 그렇다면 우리는 무엇을 해야 하는가?
팀원들에게 "AI 쓰지 말고 아키텍처를 고민하면서 직접 테스트 코드를 짭시다" 라고 말하는 건 비현실적이다. AI의 생산성을 포기하자는 주장은 아무도 듣지 않는다.
대신 내가 선택한 액션 아이템은 "테스트 코드 작성 시 아키텍처와 스킬을 선언하게 만드는 것"이다.
AI가 테스트 코드를 대신 작성해 줄 수는 있지만, 그 코드가 품고 있는 아키텍처적 부채를 설명하고 선언하는 건 오직 개발자 자신만 가능하다.
- 결합도 및 픽스처 자진 신고: 이 테스트를 돌리기 위해 무리하게 무거운 픽스처(Fixture) 객체나 장황한 전/후처리를 몰아넣고 있진 않은가?
- 코드 스멜 선언: AI가 만들어준 테스트 코드가 지나치게 길거나 세부 구현을 흉내 내고 있다면, 단순히 PR에 올리는 게 아니라 "현재 프로덕션 코드가 결합도가 높아 테스트가 장황함"을 명시하기.
- 아키텍처 의도 말하기: AI가 뱉은 코드를 그대로 제출하지 말고, 이 테스트가 어떤 스킬(상태 검증, 행위 검증 등)을 사용했고 왜 이런 구조를 선택했는지 동료들에게 설명하기.
AI 시대에 좋은 개발자의 진짜 역량은 테스트 코드를 쳐내는 속도가 아니라고 생각한다. AI가 무식한 깡생산성으로 결합도를 뚫어버렸을 때, 그 장황한 테스트 코드 뒤에 숨은 '나쁜 구조의 경고 신호'를 알아채고 프로덕션 코드를 리팩토링할 수 있는 안목이 진짜 역량이다.
AI가 내 테스트 코드를 대신 짜줄 수는 있어도, 내 시스템의 아키텍처까지 책임져주진 않는다.
'Development' 카테고리의 다른 글
| 유닛 테스트에서 '비즈니스 Fixture 객체'를 버려야 하는 이유 (0) | 2026.01.25 |
|---|---|
| ORM은 레거시가 될까? (0) | 2025.12.27 |
| Next.js와 Supabase를 접고 다시 스프링으로 (0) | 2025.11.18 |
| Exception throw를 두려워하지 말자. (0) | 2025.11.02 |
| MSA에서 헥사고널 아키텍처가 적절하지 않은 이유 (0) | 2025.07.01 |