Scientia Conditorium

TDD에 관한 의견들 정리 본문

프로그래밍

TDD에 관한 의견들 정리

크썸 2024. 5. 31. 01:53

※ 해당 글은 인터넷 이곳 저곳에 있는TDD 관련 의견들을 모아놓은 것입니다.

※ 본 블로그 주인장은 TDD에 다소 부정적인 의견을 가지고 있습니다.

※ 아래 내용에 블로그 주인장 의견을 일절 없음을 미리 말씀드립니다.

※ 자세한 출처는 생략하고 대략적인 URL 주소와 위치만 제일 하단에 남깁니다.

※ 마지막 업데이트 : 2024년 12월 26일

 

 

  1. TDD의 문제점1
    • 실제 돌려야 할 코드를 작성하는 사람이 테스트 코드도 작성한다.
    • 테스트 코드 자체에 문제가 있다면 결국 도돌이표
    • 테스트 코드부터 만드느라 실제 코드를 만드는데 지장이 생기는 경우가 있다.
    • 그럼에도 코드의 질이 극적으로 좋아진다는 어떠한 근거도 찾을 수 없다.
    • TDD 방법론이 나온지 20년이 지났지만, 측정 가능한 장점들은 존재하지 않는다.
      대부분 난 이걸 썼더니 좋아졌다라는 경험이 전부다.
    • 특히 렌더링 파트에서는 적용 불가능한 쓰레기 이론
    • 무결성이 정말 중요한 부분의 설계에 취약함
      • 논리, 수학적으로 복잡한 사고를 요하는 부분은 TDD로 커버 안되는 경우가 허다함
      • 변수가 늘면 테스트 경우의 수가 지수승으로 느는 경우가 많기 때문에 모든 테스트를 만드는 게 불가능
      • 금융처럼 정말 안정성이 중요한 곳이라면 알고리즘적으로 무결함을 증명하는 방식이 더 중요
  2. TDD 사용하기 적합한 부분과 부적합한 부분
    • 소프트웨어 개발, 테스팅 또한 경제적인 활동이다. 자원(시간, 인력)을 적게 투입하여 최대한의 효용을 뽑아내야 한다.
    • 코드에 따라 유닛 테스트는 필요할 때도 있고, 아닐 때도 있다.
      • 1) 알고리듬이 매우 복잡하지만 수학적으로 잘 정의된 경우, 구현 상의 명백한 버그를 없애기 위해 필요
      • 2) 제품이 실제로 사용되고 발전하면서 사양/기획이 자꾸 변하거나 가정이 틀리는 부분의 버그를 없애기 위해 필요
      • 1) 에서는 TDD가 어느 정도 유용할 수 있으나 2)에서는 쓸모가 없다. 코드의 어떤 부분이 변경될지 예측하기 어렵기 때문이다.
      • 1)은 애초에 변하지 않는 부분이며 TDD 방식으로 모든 코드에 대해 테스트 코드를 작성할 경우 특히 2) 에서 코드를 변경해야 하는데 테스트가 발목을 잡는다
    • 일단 코드를 그냥 작성하고, 실제로 버그가 일어나고 가정이 틀리는 시점에서 그에 대한 테스트 코드를 작성하는 것이 더 효율적이다.
    • 요구사항이 설계시부터 변하지 않는 기능들은 당연히 자동화 테스트를 넣는 게 좋다(TDD가 아니라 API 호출 테스트 여도 동일). TDD에 심히 열광하는 사람들은 private 메서드까지 public 메서드로 만들고 유닛테스트에 mock을 끼워넣기 위해 필요없는 인터페이스를 만들기도 한다. 결국 모든 클래스마다 인터페이스를 하나씩 만드는 사람들도 존재.
  3. 테스트 코드 작성하는 부분에 관하여
    • 테스트 코드는 결국 사람이 작성하는 것이다. 즉, 테스트 코드가 완벽할 수가 없다.
    • 내 코드가 제대로 동작한다는 확신은 자기 자신이 작성한 테스트 코드가 아니라 다른 사람이 검증해주어야 한다.
    • TDD가 중요한 게 아니라 내가 작성한 코드를 검증하는 게 중요하다. 자기 코드를 손으로 테스트 못하는 사람들은 TDD에서 말하는 유닛 테스트 코드도 작성하지 못할 확률이 높다.
    • 내가 생각하던 값은 개발하면서 눈으로 확인했으니 테스트 코드를 작성했을 때 어지간하면 통과한다. 결국 모든 사례를 상상해서 작업해야한다는 뜻인데 그게 가능한 지능이라면 굳이 테스트 코드를 만들 필요가 없다.
    • 유저 DB에서 데이터를 가져와 가공하는 코드를 작성하는 경우, 테스트 코드를 어떻게 작성하는 것이 좋은가를 생각해보자. 테스트를 유의미하게 만드려면 더미 유저데이터를 꼼꼼하게 엣지케이스까지 생각해서 생성하는 담당자가 있어야 하기 때문에 결국 불가능한 방법론이 된다.
    • 어떤 버그가 일어날지 실패하는 테스트 코드를 먼저 작성한다고 가정해보자. 그걸로 인해 버그가 난다면 애초에 코드를 작성하기 전에 비지니스 로직을 아예 이해하지 못했다는 뜻이다. 
    • 본인이 작성한 코드가 의도한 대로 동작하는 지 확인하는/검증하는 것은 기본 중에 기본이다.
    • 'TDD = 테스트 코드 작성' 이 아니다.
    • TDD를 반대하는 것이 테스트를 하지 말라는 게 아니다. 테스트는 많이 할수록 좋다.
    • 테스트는 중요하지만 TDD가 만병 통치는 아니다. TDD 한다고 주객전도하지 말하야 한다.
    • 사람은 기본적으로 실수를 하기 마련이다. 그렇기 때문에 테스트 코드를 작성한다는 것은 이미 실수가 내장되어 있다는 뜻이고 바뀌는 부분과 안 바뀌는 부분까지 테스트 코드를 만드는 것은 매우 비효율적이다.
      바뀌는 부분은 어차피 나중에 오류가 생기기 마련이고 그 때 유닛테스트를 만들면 된다. 처음부터 여러 유닛테스트를 만들게 되면 비지니스 로직이 바뀔 때마다 여러 유닛테스트 함수를 수정해야하므로 시간, 돈 낭비가 된다.
    • 수학 문제를 풀고 검사하는 과정을 생각해보자. 내가 옳았는지 확인하기 위해 검산을 하는데 정작 검산 과정에서도 같은 실수를 하는 경우가 많기 때문에 검산을 할 때는 반드시 문제를 풀었던 방식과 다른 방식으로 접근해야 한다. 테스트 코드 역시 동일하다. 가장 쉬운 방법은 다른 사람이 검산/테스트 하는 것이다.
  4. TDD 장점?!
    • 구현하는 함수든 클래스의 명세를 더 정확히 할 수 있고, 유지 보수 측면에서 테스트 자동화를 이미 깔고 가기에 안정감을 얻을 수 있다.
    • 이에 대한 반대 의견
      • 클래스 명세 부분은 OOP와 함수의 선조건 후조건으로 해결해야할 부분인데, 그걸 못하니 TDD로 해결하려는 것 같다. TDD로 해결하려다 보면 필요없는 인터페이스를 양산하게 되어 오히려 클래스의 의미가 모호해지는 부작용도 있다. TDD 주창자인 kent back도 자기는 무조건 인터페이스와 구현을 분리하려고 하는 성향이 있어서 TDD가 잘 맞을뿐이라고 블로그 글을 작성한 적이 있다.
      • 실제 kent back도 자기가 테스트 먼저 작성하는 이유가 '내 코드가 잘 작동한다는 자신감을 가지고 싶어서'라고 말했다. 하지만 내가 자신감을 가지는 것보다 다른 사람이 검증해줘서 확인받는 것이 더 중요하다.
  5. TDD 반대파에서 본 TDD 선호하는 사람들
    • 극단적으로 말하자면 자기가 만든 코드에 대해 예측이 안되는 사람들
    • 객체지향 설계, 전체 로드맵이 머릿속에 없는 사람들
      • 버그가 어느 구간에서 발생했는지 예측이 안 된다 → 버그를 못 찾거나 찾는데 한 세월
        → 버그 없이 프로그램을 쌓을 순 없을까? → 오오 TDD라는 마법의 방법론이 있었다니?
        이런 경우가 상당히 많다.
    • 입으로 일하는 사람들이 성과 부풀리려고 만든 개념
      • 애초에 프로그래밍이라는게 함수라는 영역에서 정의역과 공역이 일정할 수 밖에 없는데 결과가 예측이 안되서 테스트를 돌린다? 프로그래머로서 자질이 떨어진다는 뜻
      • 대학은 걸출한데 나왔는데 코딩은 못하는 이론 프로그래머들이 직장 내에서 자신을 보호하기 위해 만든 개념
  6. TDD 장점 (주장하는 사람들의)
    1. 구현하는 함수든 클래스의 명세를 더 정확히 할 수 있고, 유지 보수 측면에서 테스트 자동화를 이미 깔고 가기에 안정감을 얻을 수 있다.
      • 이에 대한 반대 의견
      • 클래스 명세 부분은 OOP와 함수의 선조건 후조건으로 해결해야할 부분인데, 그걸 못하니 TDD로 해결하려는 것 같다. TDD로 해결하려다 보면 필요없는 인터페이스를 양산하게 되어 오히려 클래스의 의미가 모호해지는 부작용도 있다. TDD 주창자인 kent back도 자기는 무조건 인터페이스와 구현을 분리하려고 하는 성향이 있어서 TDD가 잘 맞을뿐이라고 블로그 글을 작성한 적이 있다.
      • 실제 kent back도 자기가 테스트 먼저 작성하는 이유가 '내 코드가 잘 작동한다는 자신감을 가지고 싶어서'라고 말했다. 하지만 내가 자신감을 가지는 것보다 다른 사람이 검증해줘서 확인받는 것이 더 중요하다.
    2. 만들 때는 귀찮아도 단순 반복 작업을 확 줄여주고 시스템 안정성 및 심적 안도감을 크게 해준다.
    3. 불안감이 제거된다.
    4. 테스트 코드를 통해 스펙 문서화가 가능하다
      • 실제로 파라미터가 뭐가 있는지, 반환 값은 어떤 모양인지 등등
    5. 디자인 개선 효과
    6. 버그를 추적하는 시간이 현저하게 줄어들고 테스트를 안해서 아낀 시간만큼 개발 생산성이 향상된다.
    7. 비즈니스 로직의 허점을 발견하기도 하여 프로젝트 생산성 향상된다.
    8. 동시에 한 가지 이상의 일을 하지 않도록 통제하여 집중력이 향상된다.
    9. 삶의 만족도를 높여준다
    10. 빠른 피드백을 통해 직무의 탈진 가능성을 낮춰준다.
    11. 학습 동기 부여가 된다
    12. 동작하는 코드에 대한 자신감이 올라간다
    13. 피쳐를 만들기 전에 spec을 짜고 플로우를 미리 테스트 코드로 짜는 과정에서 되는 생각정리 + 코드정리 + 도큐먼트 생성
    14. 개발이라는게 큰 단위의 작업을 최대한 작게 쪼개는게 좋은 방법이라면 TDD는 그걸 하기 제일 좋은 방식
      전체 기능에서 함수로 뽑아서 테스트하면 훨씬 더 작은 단위로 결과를 확인하면서 개발할 수 있고, 쪼갤 수 없는 경우에도 e2e 테스트 등 케이스를 분리해서 개발 가능함.
  7. 트위터에서 설문조사 결과

 

 

 

출처

  1. 유튜브 포프TV : 효율적인 테스크 코드 작성법(https://youtu.be/gs1qM1TF5zA?si=LvmWWSp7PJZam6Br)
  2. OKKY The Real TDD 후기 : OKKY The Real TDD 후기 (nesoy.github.io)
  3. 트위터 설문조사 https://x.com/housecor/status/1797662670973497750
  4. 유튜브 포프TV :  유닛테스트 찬양했다가 짤린 주니어 프로그래머 이야기(https://youtu.be/KnXXzITTsK8?si=Ibt_Y-ZVGPYpY4PP)
  5. ㅇㅇ

 


 

블로그 주인장 개인 의견

  • 개발 방법론에서 불안감이라던가 삶의 질 향상 이딴 얘기가 왜 나오는지 모르겠다
  •