gyuwon
202
2019-07-22 03:55:46 작성 2019-07-22 04:08:43 수정됨
8
1368

테스팅을 모르면서 테스팅을 미워하는 사람들


자신이 잘 알지 못하는 대상을 증오하는 건 부끄럽고 해악한 일입니다. 정치사회적으로 생각해보면 쉽게 납득됩니다. 비슷한 일이 테스트 자동화와 관련해서도 많이 발견됩니다.

테스팅이 쓸모 없거나 시간만 잡아먹는다고 말하는 사람들은 제대로 된 테스팅 학습이나 현장 경험이 없습니다. 인터넷이나 세미나에서 귓동냥 정도 얻은 것이 전부거나, 공부도 안하고 무작정 시도해 보다가 금새 어렵다고 포기한 사람들이죠. 제대로 사용하는 수준에 이르기 위해 공부를 안해도 되거나 어려운 난관이 없는 소프트웨어 개발 도구는 한 번도 본 적이 없습니다. 준비없는 무모한 시도나 이른 포기는 테스팅의 잘못이 아니라 자신의 잘못인데 테스팅을 비난하기 시작합니다.

이것과 관련되어 몇 년 전 엉클밥 인터뷰가 있으니 관심있는 분들은 읽어보시는 것도 좋겠습니다. 엉클밥은 이 인터뷰에서 설계가 얼마나 중요한지, 또 코딩과 설계가 얼마나 밀접한 것인지도 얘기합니다.

https://blog.cleancoder.com/uncle-bob/2016/03/19/GivingUpOnTDD.html

*참고로 저는, 국내에도 많은, 엉클밥 추종자들 중 한명이 아닙니다.

그리고 테스트 케이스는 버그가 있다는 것은 알려주지만 버그가 없다는 것은 알려주지 않습니다. 이것도 이해하지 못하고 TDD 하면 버그가 하나도 없느냐고 반박하는 사람들이 있습니다. 버그를 완전히 박멸해주는 개발 도구는 아직 발견되지 않았습니다. 테스팅과 TDD는 만능이 아닙니다. 그저 여러가지 도구 중 하나입니다. 손톱을 깎을 때 니퍼를 쓰다 다치면 그건 니퍼가 아니라 사람 잘못이에요. 위 글에서 엉클밥은 TDD는 암을 치료하지도 세계 평화를 가져다주지도 못한다고 했죠.

마지막으로, 다음 글은 켄트벡이 말하는 TDD의 효과(번역)입니다.

https://gyuwon.github.io/blog/2018/06/24/what-tdd-solves.html

4
4
  • 댓글 8

  • fender
    14k
    2019-07-22 09:23:43 작성 2019-07-22 09:47:19 수정됨

    개인적으로 좀 더 경험이 쌓이면 한 번 글을 써보려고 생각 중인 주제입니다. 결론부터 이야기하자면 전 TDD에 대해선 상당히 회의적이고 테스트 자체에 대해서도 효용은 인정하지만, 본문에서 이야기한 무지에 의한 거부 뿐 아니라 맹신에 의한 거품 효과가 공존하는 것이 아닌가 하는 생각을 지울 수 없습니다.

    기능을 위한 코드는 물론이고 그 기능을 테스트하기 위한 코드 또한 작성을 위해서는 시간이 필요합니다. 또한 어떤 종류의 코드이건 길어지면 길어질수록 유지 보수를 위한 노력을 해야합니다.

    단위 테스트의 효용은 그런 '비용'보다 회귀 문제를 예방하는 등의 이익이 더 크다는 전제에서 출발하는 것이지만 제 경험적으로는 모든 경우에 그 비용이 프로젝트 생명주기 동안 감당할 수 있는 것은 아니라는 느낌이었습니다.

    테스트 작성의 문제가 어떤 교조적인 무엇 - 예를들어 테스트를 작성 안하면 무조건 개발자로서 용서 받을 수 없는 무능이고, 테스트 작성은 언제나 대단히 긍정적 결과만을 가져온다는 식의 주장 - 이 아니라 비용과 이익에 대한 문제라면, 여기서 조금 쯤 정확하게 어떤 이익과 비용이 생길 수 있는지 짚어 보는 것이 도움이 될 것입니다.

    문서화 측면에서의 테스트 코드가 주는 이익을 제쳐두고 이야기하자면, 단위 테스트 작성의 가장 큰 미덕은 코드 회귀의 방지가 아닐까 싶습니다. 그로인해 예상치 않은 문제를 피할 수 있고 좀 더 과감한 리팩터링 시에도 부담을 덜 수 있습니다.

    하지만 중요한 건 모든 종류의 코드가 동일한 회귀의 위험성, 또는 심각도를 가지는 것이 아니며, 모든 종류의 코드가 동일한 테스트 비용을 발생시키지 않는다는 점입니다.

    개인적인 경험상 회귀가 자주 발생하는 복잡한 코드일 수록 테스트를 작성하는 비용 또한 높아지는 경향이 있다고 생각합니다.

    보통 가장 깔끔하게 단위테스트를 작성할 수 있는 코드는 유틸성 메서드들이고, 그런 이유로 테스트 프레임워크 등의 예제는 대체로 이런 부류의 메서드들을 사용합니다. 하지만 유틸성 메서드가 테스트하기 쉽다는 건 외부 의존성이나 상태와 무관하기 때문이고, 바꾸어 말하면 그런 메서드는 회귀를 쉽게 발생시키지 않고 발생 하더라도 어렵지 않게 수정할 수 있습니다.

    반면 가장 회귀 빈도도 높고 고치기도 곤란한 기능은 UI 같이 디자인 변경 등 수시로 변화하거나, 혹은 운영 데이터나 이런 저런 상태에 의존하는 코드, 또는 메시징이나 검색엔진 등 외부 시스템과 연동하는 부류의 코드라고 생각합니다.

    물론 지난 20년간 목업이라거나 셀레니엄 등을 적절히 사용해서 그런 경우에도 테스트를 활용할 수 있는 기술은 많이 등장했습니다. 또한 적절한 리팩터링을 통해 그런 코드를 최대한 격리하는 것도 어느 정도 문제를 완화하는 방법일 수는 있습니다.

    하지만 그렇다고 그런 부류의 테스트를 작성하는 비용이 테스트 프레임워크의 예제와 같은 수준으로 줄어들었다는 이야기는 아닐 것입니다. 그리고 어떤 종류의 회귀에 대해선 아직 적절한 테스트 기법이 확립되지 않았습니다. 예컨대 CSS를 조금 고쳤더니 엉뚱한 페이지의 디자인이 망가진다던지 하는 경우는 흔히 겪는 문제이지만 그런 문제를 단위 테스트를 통해 원천 방지하기는 여전히 어렵습니다.

    그리고 한 번 작성하면 자주 변하지 않는 코드는 그 만큼 테스트의 효용이 떨어지게 됩니다. 반면 자주 요구조건이 변경되는 코드라면 테스트가 주는 이익은 증가하지만, 변경에 비용에는 실제 코드 뿐 아니라 테스트 코드 자체도 포함된다는 점을 무시할 수 없습니다.

    결론적으로 노력을 통해 테스트 비용을 줄이고 기대 이익을 높일 수는 있지만, 여전히 제대로된 테스트를 작성하고 유지보수하는데 상당한 비용이 드는 것은 분명합니다. 그리고 경우에 따라선 프로젝트 일정이나 팀원들의 기술 수준이 개발을 하면서 동시에 그런 수준의 테스트를 완벽하게 처리하기엔 부족한 경우는 얼마든지 있다고 생각합니다.

    개인적으로 테스트의 효용성을 맹신하는 것은 테스트에 무지한 것 만큼 위험하다고 생각합니다. 많은 오픈소스 프로젝트들이 유행을 따라 테스트 코드를 포함하고 있지만, 프레임워크와 같은 성격의 규모있는 프로젝트가 아닌 경우 대체로 가장 테스트 하기 편한 일부 API만 골라서 단위 테스트 갯수를 채워넣고 뿌듯해하는 그런 경우를 자주 볼 수 있었습니다.

    그런 경우 정말 회귀 발생의 위험이 높은 코드는 테스트가 되지 않고 있음에도, 단위 테스트를 실천하고 있다는 자신감이 생겨 문제에 대한 인식을 희박하게 할 위험도 있습니다.

    제 생각엔 조금 더 시간이 지나면 점점 테스트를 당위의 문제가 아닌 효율의 문제로 인식하는 사람들이 늘어날 것이고, 그러면 좀 더 정량적으로 어떤 경우에 어떤 테스트를 하는 것이 가장 이익이 되는지에 대한 논의도 본격적으로 시작되지 않을까 기대합니다.

    10
  • 뒷집할머니
    1k
    2019-07-22 10:38:01

    ㄴ 우와...

    1
  • Hyperglide
    381
    2019-07-22 10:51:25

    칼럼에 올리셨어도 괜찮았을거란 생각이 드는 글이네요.

    커뮤니티는 1페이지가 금방 넘어가서... ㅠㅠ

    0
  • fender
    14k
    2019-07-22 13:08:53 작성 2019-07-22 13:11:10 수정됨

    관련 내용으로 글이 여러 개있어서 좀 토론을 하기에 불편한 점이 있네요. 개인적으로 테스팅 관련한 토론에서 다루어 보고 싶은 주제 중 왜 게임 업계에서는 단위 테스트를 하지 않는가 하는 문제가 있습니다.

    사실 클라이언트 게임 개발 분야는 '소프트웨어 공학의 변방' 쯤 되는 느낌이 있습니다. 그래서 단위 테스트의 경우도 게임 엔진에 따라 제한적으로 지원하는 경우가 있지만, 제가 아는 한 다른 분야에 비해 테스트를 작성하는 경우가 압도적으로 드문 것 같습니다.

    그런 현상에는 여러 이유가 있겠지만, 크게는 게임 코드는 장기간 유지보수 하는 경우가 흔지 않고, 많은 버그가 그래픽이나 물리엔진 등과 관련되어 테스트하기 까다로운 성격을 띈다던지하는 부분이 크다고 봅니다.

    이를 조금 일반화, 단순화 해서 이야기한다면, 테스트의 효용은 대체로 유지보수 기간, 회귀 발생의 빈도에 비례하고 목업이나 픽스쳐 생성 등의 비용에 반비례한다고 정의할 수 있을 지 모르겠습니다.

    그런 면에서 프로젝트가 게임과 비슷한 성격에 가까울 수록(i.e. 단발성 코드, 복잡한 실행 환경 등) 테스트의 유용성은 감소하고, 반대로 게임 같은 분야에도 단위 테스트가 일상화 되는 수준으로 기술이 발전한다면 다른 분야에서도 테스트 작성은 지금보다도 훨씬 모든 경우에 항상 실천해야 하는 상식으로 자리를 잡지 않을까 하는 생각도 듭니다.

    0
  • PRO그래머
    1k
    2019-07-22 13:58:43

    fender

    제가 아는 범위내에서는 좀 다른데 테스트에 가장많은 시간과 비용을 투자하는게 게임업계로 알고 있습니다. QA를 따로 채용해서 테스트를 진행하고 모든 케이스를 문서화 하며 단위테스트를 하지 않는게 아니라 테스터가 있기 때문에 업무를 분배해서 진행하기에 단위 테스트를 하지 않는것처럼 보일뿐이라고 생각합니다.

    0
  • fender
    14k
    2019-07-22 14:00:20 작성 2019-07-22 14:06:19 수정됨

    PRO그래머 // 네, QA 관련 부분은 말씀하신 내용이 맞습니다. 다만 제 글의 '테스트'는 좁은 의미로 단위 테스트, 혹은 자동화된 단위/통합 테스트를 일컫는 것으로 이해해주시면 감사하겠습니다.

    조금 기술적으로 표현하면 게임 분야는 거의 전적으로 엔드 투 엔드(E2E) 테스트에 의존하고 단위 테스트는 거의 하지 않는 경향이 있다는 정도로 정리할 수 있지 않나 싶습니다.

    역시 의견이 갈릴 수 있는 부분이지만 보통은 E2E와 단위 테스트는 그 쓰임새나 목적이 달라, 어느 한 쪽이 다른 쪽을 완전히 대체할 수 있는 것으로는 생각하지 않는 편입니다.

    0
  • PRO그래머
    1k
    2019-07-22 17:20:27

    fender


    테스트가 중요하다는 점에는 이견이 없으나 테스트에도 다양한 종류가 있고 상황과 환경에 맞는 테스트 방법이 있다고 봅니다. 직접언급하신 내용이기에 다시 적을 필요는 없어보이나 효용 이라는 측면에서의 최적의 테스트 방식이 E2E 라고 생각했기에 그렇게 진행하고 있다고 봅니다.


    굳이 테스트의 범주를 좁은 의미로로 국한하고 게임업계는 그 좁은 의미의 테스트 방식을 잘 사용하지 않으니 문제가 있다로 결론을 내리시는건 조금은 편향적인 결론이 아닌가 하는 생각이 듭니다.


    0
  • fender
    14k
    2019-07-22 17:39:26 작성 2019-07-22 17:44:41 수정됨

    PRO그래머 //

    테스트에는 다양한 종류가 있는 것 뿐 아니라, 그 목적에도 차이가 있음을 이해할 필요가 있습니다. 즉, 단위테스트이건 E2E 테스트 건 모두 동일한 목적을 위해 존재하는데 상황에 따라 어떤 것을 사용할지 택한다기 보다는, 특히 단위 테스트의 경우 단순히 최종 결과물의 결함을 줄인다는 목표 이외에도 다른 용도가 더 존재합니다.

    테스트 작성을 방법론으로 활용하는 TDD의 경우는 말할 것도 없지만, 예컨대 단위 테스트의 중요한 역할 중 하나인 리팩터링시 코드의 올바름을 보장하는 기능의 경우도 E2E 테스트 같이 피드백이 오래 걸리는 방식으로는 충족하기 어려운 내용입니다.

    또한 단위 테스트 코드는 그 자체로 테스트 대상이 되는 API의 문서 역할을 하기도 하는데, 이 또한 E2E 테스트로 대체할 수 없는 단위 테스트의 고유한 영역입니다.

    게임 업계에서 단위 테스트를 잘 사용하지 않는 까닭은 말씀대로 효용의 문제, 그리고 이런 저런 문화(예컨대 좋은 설계보단 빠른 코드를 선호), 또는 게임 엔진이라는 기술적인 제약 등 여러 복합적인 이유가 있습니다.

    하지만 중요한 건 게임 분야라고 무언가 원천적으로 단위 테스트 자체의 효용성이 없어지거나 E2E 테스트로도 충분하다기 보다는 언급한 현실적인 문제로 인해 도입이 쉽지 않다는 정도로 생각하는게 합리적이라고 봅니다.

    늦게나마 유니티 엔진 등이 단위 테스트를 지원하기 시작하고 게임 개발자들도 조금씩 관련 기술에 노출되는 단계임을 감안하면 결국 시간이 지나면 다른 소프트웨어 분야와 비슷한 방향으로 발전하지 않을까 하는 생각을 합니다.


    1
  • 로그인을 하시면 댓글을 등록할 수 있습니다.