Unit Testing

Created at 2026년 08월 09일

Updated at 2026년 08월 09일

By 강병준

이 책을 읽게 된 이유

사내에서 E2E 테스트를 만들고 운영하는 과정에서 테스트가 주는 신뢰를 직접 경험하고 있었기에, 테스트의 가치를 모르고 있었던 것은 아니다.

그런데 이상하게 누군가 나에게 “테스트 코드를 왜 작성해야 하는가?”, “테스트가 왜 중요한가?”라고 묻는다면 명확하게 답하기 어려웠다. 버그를 발견하고 코드가 의도대로 동작하는지 확인하기 위해서라는 애매한 답만 반복했고, 늘 찝찝함이 남았다.

돌이켜보면 나는 모두가 중요하다고 말한다는 이유로 ‘테스트는 중요하다’는 전제를 받아들인 채 테스트 코드를 작성해온 것인지도 모른다. 어떤 테스트가 가치 있는지, 어느 계층에서 검증해야 하는지, 테스트가 주는 신뢰와 유지 비용 사이에서 어떻게 균형을 잡아야 하는지 내 기준으로는 설명할 수 없으니 말이다.

이 질문은 AI를 활용해 개발하면서 더 중요해졌다. 테스트는 AI가 작성한 코드가 요구사항대로 동작하는지 검증하고, AI의 작업을 제어하는 수단으로도 활용된다. 그렇다면 나 역시 테스트를 단순히 중요한 도구로 받아들이는 데 그치지 않고, 무엇을 왜 테스트해야 하는지 근본적으로 이해할 필요가 있었다.

그래서 나는 테스트에 대해 나만의 판단 기준을 가지고자 단위 테스트를 읽기 시작했다.

이 책을 읽고 나서

책에서 가장 인상 깊었던 문장은 단위 테스트의 목표가 _소프트웨어의 지속 가능한 성장_을 _가능_하게 하는 것이라는 것이었다.

이전까지만 해도 테스트의 목적을 주로 버그를 발견하고, 내가 작성한 코드가 의도대로 동작한다는 것을 보장하는 데 있다고 생각했다. 물론 이것도 테스트가 제공하는 중요한 가치다. 다만 책을 읽으며 지금 운영하고 있는 서비스의 테스트 코드를 다시 살펴보니, 그것은 여러 가치 중 하나일 뿐이라는 생각이 들었다.

서비스가 오래될수록 누군가 과거에 만들어 둔 순수 함수부터 여러 외부 의존성이 얽힌 기능까지 수많은 코드가 쌓인다. 당연하게도 새로운 작업자가 그 코드의 모든 구현과 의존 관계를 처음부터 완벽하게 파악하는 것은 어렵다. 그럼에도 기존 동작을 크게 두려워하지 않고 수정과 배포를 시도할 수 있는 것은, 테스트가 바뀌면 안 되는 동작을 보호하고 예상하지 못한 회귀를 알려주기 때문이다.

결국 테스트의 근본적인 가치는 오늘의 코드가 맞는지 확인하는 것에서 끝나지 않고, 시간이 지나도 소프트웨어를 안전하게 변경할 수 있는 상태로 유지하는 것, 즉 책에서 말한 소프트웨어의 지속 가능한 성장을 가능하게 하는 것이었다.

다만 모든 테스트가 지속 가능한 성장을 돕는 것은 아니다. 테스트 역시 작성하고, 읽고, 실행하고, 수정해야 하는 코드다. 이미 폐기됐어야 할 레거시 정책이 테스트에 남아있거나, 제품의 알고리즘을 테스트 코드에 그대로 옮겨 같은 오류를 공유하거나, 내부 호출 순서와 구현 세부사항을 검증하는 테스트도 있다. 이런 테스트는 무엇을 보호하는지 설명하기 어렵고, 요구사항 변경이나 리팩터링 때 불필요하게 깨지면서 변경을 돕기는커녕 방해할 수 있다.

그렇기에 우리는 최종 목표인 소프트웨어의 지속 가능한 성장을 가능하게 하도록 테스트를 작성해야 하고, 무엇을 검증하고 어떻게 관리할지 고민해야 한다.

AI 시대의 테스트

책을 읽고 완전히 답하지 못한 질문이 하나 있다.

❓ 모두가 AI로 코드를 작성하고 관리하는 시대에도 기존의 테스트 원칙이 그대로 유효할까?

전통적인 테스트 피라미드는 작성과 유지 비용을 중요한 전제로 삼고, 빠르고 자주 실행할 수 있는 단위 테스트를 중심으로 구성됐다. 하지만 AI가 테스트를 작성하고, 실패 원인을 분석하고, 변경된 코드에 맞춰 테스트까지 수정하는 지금은 이 비용 구조 자체가 달라질 수 있다.

예를 들어 과거에는 특정 함수나 분기에 밀착된 좁은 범위의 테스트를 부채에 가깝게 바라봤다. 내부 구조가 조금만 바뀌어도 테스트가 깨지고, 누군가 그 테스트를 계속 수정해야 했기 때문이다. 그래서 외부 동작이 그대로라면 테스트가 깨지지 않아야 했고, 이러한 리팩터링 내성은 좋은 테스트의 중요한 조건이었다. 하지만 테스트의 작성과 수정을 AI가 담당한다면, 과거에는 유지 비용 때문에 포기했던 테스트도 저렴한 안전장치로 활용할 수 있지 않을까?

테스트 커버리지도 비슷하다. 과거에는 커버리지 100%를 달성하기 위해 모든 분기와 코드에 테스트를 추가하는 일이 비용에 비해 큰 의미가 없다고 생각했다. 높은 커버리지가 중요한 동작의 검증을 보장하지 않기 때문이다. 하지만 AI가 거의 추가 비용 없이 누락된 분기의 테스트를 작성할 수 있다면, 커버리지 100%가 LLM이 간헐적으로 남기는 실수를 보정하는 가드레일로서의 의미가 있을 수 있지 않을까?

통합 테스트와 E2E도 마찬가지다. 과거에는 인증, 격리·병렬 환경 구성, 테스트 데이터 준비, 브라우저 조작, locator 관리와 실패 원인 분석에 많은 비용이 들었기 때문에 대표적인 몇 가지 시나리오만 남기는 것이 합리적이었다. 하지만 AI가 테스트 환경을 구성하고, 변경된 UI에 맞춰 테스트를 수정하고, 실패 원인까지 분석할 수 있다면 더 많은 사용자 여정을 검증하고, 기능을 사용자에게 더 안전하게 전달할 수 있지 않을까?

그렇다면 많은 단위 테스트와 소수의 통합·E2E 테스트로 구성된 기존의 피라미드, 기존의 테스트 원칙들은 여전히 가장 합리적이고 유효한 전략일까?

솔직히 아직 명확한 답은 내리지 못했다. 다만 AI가 바꾼 것은 전통적인 테스트 원칙 자체라기보다 테스트의 경제성에 가깝다고 생각한다. 테스트를 작성하고 수정하는 비용은 낮아질 수 있지만, 실행 비용과 실패 결과를 얼마나 신뢰할 수 있는지는 여전히 별개의 문제다. 무엇보다 어떤 동작이 중요한지, 어떤 위험을 먼저 보호해야 하는지는 AI가 대신 결정해주지 않는다.

그래서 AI 시대에는 테스트 코드를 작성하는 능력보다 테스트 시나리오를 설계하는 능력이 이전보다 더 중요해질 수 있을 것 같다. 테스트 코드의 문법과 반복적인 설정은 AI가 대신 작성할 수 있지만, 어떤 사용자 행동을 보장해야 하는지, 어떤 도메인 규칙이 깨지면 안 되는지, 어느 경계에서 실패를 감지해야 하는지는 사람이 정의해야 한다.

AI 시대의 테스트 피라미드는 지금과 다른 모양이 될 수도 있다. 도메인과 환경에 따라 더 많은 통합 테스트나 E2E를 선택할 수도 있고, 짧게 사용하고 버리는 지역적인 테스트가 늘어날 수도 있다.

하지만 피라미드의 모양이 달라지더라도 테스트의 중요성까지 달라지는 것은 아니다. 테스트는 변경으로 인해 발생한 회귀를 막고, 문제를 조기에 발견할 수 있게 한다. AI가 테스트를 작성하고 관리하는 방식을 바꿀 수는 있어도, 변경을 검증하는 안전망으로서 테스트의 역할은 여전히 남는다.

마치며

과거에 테스트 코드를 보며 ‘그렇구나’ 하고 넘겼던 개념과, 질문을 받아도 제대로 설명하지 못했던 것들을 이 책을 통해 많이 배울 수 있었다. 그럼에도 좋은 테스트를 판단하는 기준이나 확고한 방향성을 얻은 것은 아니다. 오히려 이전보다 고려해야 할 것이 더 많아졌고, AI라는 불확실성까지 더해지면서 테스트를 판단하는 일은 전보다 어려워졌다.

그럼에도 분명히 나아진 점이 있다. 이제 테스트에 관해 이야기할 때 다른 사람의 기준을 그대로 따르는 대신 내 생각을 한마디 덧붙일 수 있게 되었다. 아직 완성되지 않았더라도 내가 중요하게 보는 가치와 판단의 근거가 생겼다는 점이 좋다.

이 책을 통해 내가 얻은 결론은 테스트의 목적이 오늘의 코드가 맞는지 확인하는 데서 끝나지 않고, 소프트웨어를 지속해서 안전하게 변경할 수 있게 하는 데 있다는 것이다. AI는 테스트 작성과 유지 비용을 낮추고 테스트 피라미드의 모양을 바꿀 수 있지만, 회귀를 막고 문제를 조기에 발견하는 테스트의 역할까지 없애지는 않는다. 결국 어떤 동작을 보호하고 어떤 시나리오를 테스트할지는 여전히 사람이 판단해야 한다.