kakasoo

왜 테스트를 해야 하는가? 본문

프로그래밍/Backend

왜 테스트를 해야 하는가?

카카수(kakasoo) 2023. 4. 28. 23:32
반응형
- 모든 것을 테스트한다는 오해

카카수 : 테스트 코드를 도입하려고 해요.
개발자1 : 좋아요. 하죠. 근데, 그걸 한다고 모든 문제가 사라질 건 아니에요.
- 작업 방식에 대한 오해

카카수 : 테스트 코드를 도입하려고 해요.
개발자2 : 좋습니다. 근데 GET 요청은 테스트할 필요 없는 거죠?
- 시간 낭비에 대한 오해

카카수 : 테스트 코드를 도입하려고 해요.
기획자 : 우리 안그래도 비즈니스가 급한데, 정말 괜찮을까요? 어느 정도 버그는 그냥 넘어가도 되는데?

테스트 주도 개발 이라는 말을 처음 지은 사람은 욕을 먹어야 한다는 얘기를 들었을 때, 그 이유를 이해 못했다.

하지만 이걸 팀원들에게 설명하고 도입하려고 하니 “굳이 왜 테스트를 해야 하느냐”는 질문들이 돌아왔다.

테스트를 해야 하는 이유는 다음과 같다.

  1. 테스트, 즉, 설계에 최대한 많은 시간을 쏟을수록 수정사항이 적어지고 전체 개발 시간을 줄일 수 있다.
  1. 기능들이 늘어나고 서로 영향을 주기 시작하면 한 가지 기능을 수정하기 위해 봐야 할 코드의 양이 늘어난다.
  1. 기능 수정 및 배포에 개발자들이 자신감을 가질 수 있다.
    • “고작이라고 생각할 수 있지만, 우리가 이거 때문에 뺏기는 시간이 얼마인데?”

 

왜 TDD는 반대에 부딪히는가?

테스트 코드를 짜자는 말에 이렇게 많은 반발이 올 거라고는 생각하지 못했다.

반대하는 사람들의 주된 논리는, 첫째는 시간 낭비라는 것이고 둘째는 어차피 모든 테스트는 불가능하다는 논리다.

하지만 이 부분에 대해서는,

  1. 테스트는 설계도의 역할도 수행한다는 점에서, 사실 TDD가 아니어도 해야 할 과정이었으며, 이미 하고 있다!
  1. 마찬가지로 배포 전에도 잘 동작하나 확인하기 때문에 코드 레벨에서 이루어지지 않을 뿐 원래 하던 과정이다.
  1. 이 방식이 익숙하냐 아니냐의 차이일 뿐, 결국 들어가는 시간은 작업자의 능률에 달린 문제일 뿐이며,
  1. 둘째의 경우 애초에 군대 무사고 100일처럼 완벽한(?) 시스템을 구축하려고 한 게 아니기 때문에 상관없다.
  1. 불가능하다고 해서 아예 안해도 좋을 게 아니라, 어디까지 할 것인지를 정하면 될 문제다.

오히려 숙달되고 나면 시간을 확보할 구석이 많아지는 것이 TDD의 장점이다.

 

10개의 기능을 가진 상태에서 1개의 기능이 추가되면, 그 1개의 기능이 기존 10개의 기능에 영향을 주는지 본다.

만약 10개가 아니라 100개라면, 그 100개는 어떻게 볼 것인가?

그리고 200개, 300개, 하물며 천 단위를 넘는 기능들은 어떻게 확인할 것인가?

기능이 늘어남에 따라 기능 하나를 만드는 데 들어가는 시간이 늘어나는데, 이는 기능 개발이 어려워서가 아니다.

그냥 봐야 할 게 점점 많아지니깐 그렇지.

 

모든 것을 테스트한다는 오해

- 테스트에 대한 오해

카카수 : 테스트 코드를 도입하려고 해요.
개발자1 : 좋아요. 하죠. 근데, 그걸 한다고 모든 문제가 사라질 건 아니에요.

TDD는 단순히 테스트만을 말하는 게 아니며, 테스트 또한 모든 로직을 테스트하자는 것이 아니다.

우리는 기능 개발을 할 때 우선순위를 정하고 개발을 한다.

그 우선순위는 단순히 개발자가 하고 싶은 순서가 아니라, 비즈니스에서 중요시되는 순서일 것이다.

가장 먼저 회원가입과 로그인이 중요할 것이며, 그 다음이 결제 로직인데, 이는 모두 돈을 벌어들이는 로직이다.

우리 서비스가 고객에게서 돈을 받기 위해서 갖추어야 할 최소 사항, 즉, 크리티컬 패스를 최우선시한다.

마찬가지로 테스트 코드를 작성하는 것도, 결국 이 크리티컬 패스가 가장 중요할 수 밖에 없다.

사실 테스트 코드를 짜는 쪽도 테스트가 재밌기 때문에 테스트를 하는 것이 아닌데 지나친 오해를 받는다.

테스트를 짠다고 해서 그게 비즈니스를 도외시하는 것은 결코 아닌데?

 

이거 안 되면 아직 만든 거 아니야!

// 게시글 신고에 대한 테스트

1. 글을 신고할 때는 이유를 기재해야 한다.
2. 글을 신고할 때 동일한 글을 두 번 신고할 수 없다.
3. 자기 자신의 글을 신고할 수는 없다.
4. 글이 신고된 시점에 그 글의 내용을 저장해두어야 한다.

어떤 로직이 정확하게 동작하는 것을 보장하기 위해 레이어 단위의, 유닛 단위의 테스트를 할 필요는 없다.

당장은 그 기능이 기획 의도대로 동작한다는 것을 보장해주는 것만으로도 충분하다.

위처럼 게시글 신고에 대한 테스트를 할 때, “이거 안 되면 배포 못해요.” 라는 기준이 분명 있을 것이다.

최소한 그 정도 기능을 테스트해야 한다는 말에 반대하는 사람은 없을 것이다.

 

이미 돌아가는 걸 왜 테스트해야 하는가?

이미 돌아가기 때문에 나중에도 잘 돌아간다는 것은 아니기 때문에 테스트는 여전히 필요하다.

물론 1 + 1에 대해서 2라고 계속 해서 검증할 필요는 없다.

하지만 점점 복잡해지는 비즈니스 로직들은 이전 코드들에 대해서 무시못할 영향을 주기 시작한다.

그렇다면 추후에도 안정성을 보장하고 문제가 발생하면 빠르게 찾아내기 위해서라도 테스트가 필요하다.

용광로는 온도를 관리하기 위해서 온도계를 달아두는데 테스트 코드의 역할 중 하나도 이런 것이다.

문제가 생길 때 바로 확인하기 위한 장치, 화재 경보기 같은 역할을 수행하는 셈이다.

 

물론 그건 우선 순위가 낮을 수는 있지

이미 돌아가는 것을 테스트하는 게 못마땅할 수는 있다.

나도 설득할 때 그것부터 하자고 말하지는 않으니, 테스트 순서는 이렇게 정하면 되겠다.

  1. 앞으로 만드는 로직들은 설계 ( = 테스트 )를 반드시 선행한다.
  1. 새로 개발 중인 게 없다면 기존 로직 중 매출과 직접적으로 관련있는 것들부터 테스트를 작성한다.
    • 이미 잘 돌아가고 있더라도, 나중에 문제 생기면 바로 식별하기 위해서라도 필요하다.
  1. 더 이상 테스트할 게 없다면 중요도가 낮은 로직부터 테스트를 작성해둔다.

 

우선 순위 문제는 우선 순위를 조정하면 될 일이지 아예 하지 말자고 말할 수는 없는 것이다.

 

작업 방식에 대한 오해

- 작업 방식에 대한 오해

카카수 : 테스트 코드를 도입하려고 해요.
개발자2 : 좋습니다. 근데 GET 요청은 테스트할 필요 없는 거죠?
카카수 : ... (여기서부터 시작해야 하는 구나)

GET 요청도 당연히 테스트가 필요하다.

다만 이런 질문이 나오는 건 단순히 이 일을 하는 사람들을 개발자로 한정지었기 때문에 벌어지는 일이다.

우리는 GET, POST, DELETE, PUT을 테스트하는 게 아니다.

이게 정말 우리의 의도대로 되는지, 그리고 그게 돈을 벌어들일 만큼의 완성도를 가졌는지를 확인해야 하고,

또 추후에 문제가 생겼을 때 바로 적발할 수 있을 정도로 촘촘한지를 봐야 하는 것이다.

개발자 분이 내게 저런 질문을 한 것도 충분히 이해할 수 있는 일이었다.

 

코끼리를 삼킨 뱀이라고 좀 써놓으면 안 되나?

어린왕자의 그림을 보고 무엇인지 맞추지 못하는 사람들이 동심을 잃었다고 말하는 것은 논리적 비약이다.

그냥 제목으로 “코끼리를 삼킨 뱀”이라고 써놨으면 누구나 이해했을 것을 왜 안 써놓고 딴 소리를 한단 말인가?

나는 기획과 디자인도 이 얘기와 비슷하다는 것을 느꼈다.

요구사항은 분명 글로 정리되어 있거나 기획자와 디자이너 머릿속 어딘가에 한 번 씩 생각했던 이야기들일 것이다.

기획과 디자인은 원래 요구사항들이 모두 정의된 다음에 진행되는 프로세스가 아닌가?

그런데 왜 우리는 피그마를 보면서 “우리 디자이너님은 무엇을 원하시는 걸까?” 추론하고 있는 걸까?

 

기획부터 개발까지 모든 영역에 걸쳐서

테스트를 해야 한다.

내가 1년 동안 작성한 코드의 라인 수는 31만 줄이었다.

그 중에 23만 줄이 사라졌으니 이런 데이터를 볼 때 다른 개발자들의 반대를 이해 못할 것은 결코 아니었다.

테스트 코드는 전체 개발 중 20%에 해당하는 기능 개발에 조금 더 공을 들이는 대신에

80%에 해당하는 설계, 유지보수에서 비용 이점을 얻어서 들인 공보다 이득을 보려는 전략으로 해석할 수 있다.

그런데 그 기능 자체가 무의미하다고 사라져버린다면 개발에 공을 들인 시간만큼이나 더 손해를 보게 된다.

마치 인테리어를 다 해놨더니 집주인이 방 빼라고 하는 셈이다.

테스트 코드를 제대로 짜고 싶다면 개발자들만의 일로 치부할 게 아니라 요구사항부터 요구사항 승낙까지,

제품 개발에 영향을 주는 모든 이해 관계자들이 모여서 무엇을 만들려고 하는지를 확정지어야 한다.

만약 23만 줄이 사라지지 않았다면 지금 쯤 서비스를 4~5개는 더 만들 수 있었을 것이다.

 

TDD가 시간 낭비라고?

- 시간 낭비에 대한 오해

카카수 : 테스트 코드를 도입하려고 해요.
기획자 : 우리 안그래도 비즈니스가 급한데, 정말 괜찮을까요? 어느 정도 버그는 그냥 넘어가도 되는데?

그런데 우리 서비스는, 앞서 말한 것처럼, 시간이 지나면 지날수록 개발하는 기간이 점점 늘어날 수 밖에 없다.

아파트를 짓는 데에 계산을 안하고 지으면 2층을 올릴 때 1층이 멀쩡한지 기둥을 하나 씩 확인하러 다닐 것이다.

그런데 3층을 만들면 1층과 2층을 봐야 하고, 100층을 만들면 99층을 모두 살펴봐야 안전한지 알 것이다.

매번 층을 올릴 때마다 이런 짓을 하는 건 너무 시간 낭비 아닌가?

 

사실 우리 모두의 주장은 동일하다

TDD를 하자고 주장하는 사람들도 동일하게, 시간 낭비를 없애기 위해서 TDD를 하자고 말하는 것이다.

사실 우리는 같은 이야기를 하고 있는데 왜 서로가 서로의 시간을 낭비한다고 착각하는 걸까?

다시 말하지만 TDD를 안한다고 해서 우리가 설계를 안하지도, 그리고 배포 전 테스트를 안하지도 않을 것이다.

결국 어차피 들여야 하는 시간을, 처음부터 과학적으로 접근하고자 함이니 상충되는 얘기가 아닐 것이다.

그럼에도 우리가 동일한 목적을 가지고도 다르게 생각하는 까닭은 무엇인가?

경험 상 테스트 코드가 시간 낭비라고 하는 사람들은 테스트 코드를 짜본 적이 없는 사람들이다.

지금까지 나와 토론했던 사람들 중 반대를 외친 모든 사람들이, 테스트 코드를 짜보지 않은 경우가 대부분이었다.

 

테스트가 시간 낭비인 게 아니라, 할 줄 모르는 거야!

도구의 사용법을 모르는 사람이 그 도구의 효용성에 대해서 논의할 수는 없는 법이다.

테스트가 불필요하다면 각자의 선택으로 남기면 되는 것이고, 짜는 사람만이라도 짤 수 있으면 된다.

그게 효율적이라고 생각하면 하면 되고 아니라고 생각하면 안 하면 된다.

그러면 시간이 지나고 나서 누구의 말이 옳은지, 아니면 각자의 개발 성향이 다를 뿐인건지 증명될 것이다.

그런데 항상 모 아니면 도 식으로 테스트는 시간 낭비니깐 하지 말자고 말하는 사람이 있다.

제발 부탁이니 일단 한 번 해보면 좋겠다.

해보고 나면 자기 생각보다 더 효용성이 크다는 것을 바로 이해할 것이다.

 

병원 가기를 미루는 사람

테스트를 도입하자고 하면 나중에 조직이 크면 하자고 말하는 사람들이 있다.

이 논리는 조직이 커지면 더 많은 개발자가 생기니 더 빨리 오류를 잡을 수 있을 거라는 얘기인데,

두 가지의 문제가 있다.

하나는 그 문제를 방치함으로 인해서 유저들의 이탈율이 높아지고 결과적으로 우리의 성장이 저해된다는 것이다.

조직이 크면 그 때 가서 고치자고 말하는데, 사실 이런 방치가 그 고칠 때를 더 뒤로 미루는 행위 아닌가?

둘째는 조직이 커지면 생기는 오류가 당연 사람 수 만큼 늘어날 것이란 점이다.

결국 문제는 개발자 n명이 만드는 오류를 n명이서 고친다는 데에 있다.

지금의 n명으로 해결하지 못하면 n이 작던 크던 어차피 해결하지 못할 것인데 큰 조직이 무슨 소용이란 말인가?

 

환자 : 아프지만 열심히 일해서 돈을 잔뜩 모으면 그 때가서 더 좋은 병원에 갈 거야.
카카수 : ( ...하지만 일하다가 건강이 더 악화되면 어떡하지? 그게 병원비 더 드는 거 아니야? )

 

기본적으로 이런 말은 따서 갚으면 된다는 마인드에 가까운데, 이는 누구에게도 좋은 태도가 아니다.

제품 개발 과정은 처음부터 끝까지 과학적으로 진행되어야 한다.

반응형