목차
테스트를 “짜면 좋지만 바쁘면 생략하는 것”으로 여기기 쉽다. 그런데 안 짠 값은 나중에, 고칠 때마다 무서워지는 코드로 돌아온다.
고치기가 무서운 코드
오래된 코드베이스에 기능 하나를 더한다. 한 줄 고쳤는데 어디가 터질지 아무도 모른다. 그래서 다들 안 건드리고 피해 다니고, 코드는 점점 굳는다.
무서운 이유는 하나다. 바꾼 게 다른 걸 깼는지 확인할 방법이 없어서. 손으로 다 눌러볼 수도 없다 - 화면이 수십 개고, 경우의 수는 그보다 훨씬 많다.
손으로 확인하는 건 곧 한계에 부딪힌다
처음엔 수동 확인으로 버틴다. 기능이 다섯 개면 고칠 때마다 다섯 개를 눌러보면 된다. 그런데 기능이 쉰 개가 되면?
- 매번 쉰 개를 다 눌러볼 사람은 없다. 그래서 “방금 고친 데 근처만” 확인한다.
- 하필 안 본 데가 깨진다. 그게 회귀(regression) - 멀쩡하던 게 딴 데를 고치다 도로 망가지는 것이다.
수동 확인은 기능 수에 비례해 늘어나는데, 사람의 시간은 안 늘어난다. 그래서 반드시 샌다.
테스트는 회귀를 잡는 안전망이다
자동 테스트는 언제든 다시 눌러주는 로봇이다. 한 번 “이 입력엔 이 결과가 나와야 한다”를 적어두면, 그 뒤로는 명령 한 번에 전부 다시 검사한다.
코드를 고친다 → 테스트를 돌린다 → 빨간 줄이 뜬다
"네가 방금 이걸 깼다"쉰 개든 오백 개든 몇 초에 다 확인한다. 바꾼 게 딴 걸 깼는지 즉시 안다 - 사람이 못 하는 걸 대신 하는 것이다. 이게 테스트의 첫 번째 값이다.
그래서 겁 없이 바꾼다
안전망의 진짜 효과는 심리다. 테스트가 지켜주면 리팩터링도 기능 추가도 두렵지 않다. 구조를 뒤엎어도 초록불이면 “동작은 그대로”라는 뜻이니까.
테스트 없는 코드는 정반대다. 고치는 게 무서워 아무도 안 건드리고, 안 건드리니 더 썩는다. 테스트는 코드를 계속 바꿀 수 있게 살려두는 것이다. “버그를 잡는 것”보다 이게 더 큰 값이다.
테스트는 실행되는 문서다
테스트는 이 코드가 무엇을 보장하는지를 말한다.
test("잔액보다 큰 금액은 출금할 수 없다")
test("음수 금액은 거부한다")이 세 줄만 봐도 출금 규칙이 읽힌다. 주석과 다른 점이 결정적이다 - 주석은 틀려도 조용하지만, 테스트는 틀리면 빨개진다. 코드가 바뀌어 설명이 안 맞으면 테스트가 실패해 알려주니, 문서가 썩지 않는다.
테스트하기 어려우면 설계가 나쁜 것이다
어떤 코드는 테스트가 유난히 어렵다. 하나를 확인하려는데 데이터베이스·외부 API·현재 시각이 줄줄이 딸려온다. 이건 테스트의 문제가 아니라 설계의 신호다 - 그 조각이 너무 많은 것과 얽혀 있다는(결합도가 높다는) 뜻이다.
그래서 테스트는 설계에 압력을 준다. 테스트하기 쉽게 짜다 보면 자연히 의존성이 정리된다. 이 “얽힌 걸 떼어내는” 방법이 의존성 역전이고, 뒤의 테스트 더블 글에서 실제로 어떻게 떼는지 본다.
공짜는 아니다
테스트도 코드다. 쓰는 시간이 들고, 코드가 바뀌면 같이 손봐야 한다. 그래서 “무조건 다 테스트”가 답이 아니다 - 잘못 짜면 오히려 짐이 된다(사소한 변경마다 우수수 깨지는 테스트처럼).
그래서 무엇을 테스트하고 무엇은 안 하나가 늘 문제다. 이건 따로 한 편에서 다룬다. 지금 알아둘 건 하나 - 테스트는 값이 있지만 공짜는 아니라서, 골라 써야 한다는 것.
실무에서: 늦게 잡을수록 비싸다
버그를 언제 잡느냐가 비용을 정한다.
- 짤 때 테스트로 잡으면 - 몇 초, 내 자리에서.
- 코드 리뷰나 통합에서 잡으면 - 몇 시간, 남의 시간까지.
- 프로덕션에서 잡으면 - 사용자가 먼저 겪고, 급하게 고치고, 신뢰를 잃는다.
테스트는 이 버그를 앞으로 끌어와 싸게 잡는 장치다. 안 짜는 게 아니라 나중에 비싸게 치르는 것뿐이다. 물론 테스트가 배포 전을 지킬 뿐, 배포 후에 실제로 어떻게 도는지는 관측가능성이 본다 - 둘은 다른 자리를 지킨다.
정리
- 손으로 확인하는 건 기능이 늘면 반드시 샌다. 안 본 데가 깨지는 게 회귀다.
- 테스트는 회귀를 잡는 안전망 - 바꾼 게 딴 걸 깼는지 즉시 안다. 그래서 겁 없이 바꾼다.
- 테스트는 안 썩는 문서이자, 짜기 어려우면 설계가 나쁘다는 신호(설계 압력)다.
- 공짜는 아니라 골라 써야 하고, 버그는 늦게 잡을수록 비싸다 - 테스트가 앞으로 끌어와 싸게 잡는다.
다음 글은 그 테스트를 어느 층에 얼마나 짜야 하는지, 테스트 피라미드로 간다.