Frudy
6k
2019-04-05 16:24:26
5
1485

테스트를 잘하고싶어요.


오늘 글 읽다가 발견한 글귀에요.


https://d2.naver.com/news/3435170

따라서 최종적으로 UI와 통합하기 전에 개발한 API를 스스로 테스트해야 할 필요성이 더 커졌습니다. 오류를 있다는 제보를 다른 개발자로부터 받아서 수정 후 재배포하고 다시 알리는 비용은 스스로 오류를 발견했을 때보다 굉장히 크기 때문입니다. 


'시간이 없어서 테스트를 못 만들었다’는 말은 '나는 테스트 코드를 만드는데 시간이 많이 걸린다’는 말과 동일합니다. 해당 언어에 대한 숙련도가 떨어지는 사람일수록 테스트 코드를 작성하는데 부담을 크게 느끼는 경우도 많이 봤습니다. 능숙해질수록 테스트 작성 시간은 줄어들어 테스트에 투자한 대비 이득이 커집니다. 가끔 테스트를 작성할 때 이 테스트 덕분에 어느 시점에 실제적인 이득이 있을지 나누어 생각할 때가 있습니다. 예를 들면 아래와 같습니다.

  • 유지보수 기간의 생산성을 높여주고 새로 프로젝트에 투입될 사람에게도 이득을 주는 테스트
  • 프로젝트 오픈 일정 직전까지의 코드 변경과 버그 발견에 도움을 주는 테스트
  • 오늘 당장 프로그램을 목표한 곳까지 작성하는 일을 더 빨리 마치게 해주는 테스트


저도 이에 적극 동의하지만,

정작, "어떻게 테스트 해야하는가?" 는 항상 막막해요.


정작 제가 갖고있는 테스트용 라이브러리인 ThreadUtils.java는...

단순히 버그났을 때 버그빨리찾을수있게하는 메소드가 좀 있을뿐,


아예 거꾸로 생각해서, 나는 해커다!!! 마음가짐으로

어떻게 해야 내 프로그램에 고의로 버그를 유발할수있을까? 라고 생각해도

아직 실무 안접해본 뉴비 입장에서 떠오르는생각은 그리많지않네요 ㅠㅠ


그래도 하나씩 노하우랑 아이디어가 생기긴하는데

정작 실무가서 쓸수있을진모르겠어요.


오늘은, 스프링 MVC프로젝트 톰켓 Start하는데 15초 20초걸리길래,

톰캣에 안올리고도 테스트할수있는 방법쪽으로 머리를 굴려보며 하루를 보내요...

1
  • 댓글 5

  • 계정세탁
    472
    2019-04-05 16:28:24

    헐, 어제 제가 읽었던 글과 똑같은 글을 읽으셨네요! 저도 저 글 뿐만 아니라 최근 어떤 영상에서도 개발자에게 중요한 것 중 하나로  '테스트를 작성하는 것'을 꼽길래 책도 읽으려고 빌리고, 현재 회사에선 우연히도 자동화 테스트 프로그램 작성을 맡게 되어서 이것저것 해보고 있네요. 전 회사에서 단위테스트는 어느 정도 작성해봤지만 여전히 어렵습니다 @_@

  • lllllllllllllll
    8k
    2019-04-05 16:33:23

    전 테스트할때 별개의 프로젝트에서 그거만 돌려보고 잘된다 싶으면 main에 갖다붙이는 식으로 했었어요 (그리고 print문 여기저기 찍어서 값이 잘 들어오는지 체크해보고..)

  • fender
    20k
    2019-04-05 16:43:39 작성 2019-04-05 16:51:40 수정됨

    개인적으로 테스트의 유용성은 큰 틀에서 공감하지만, 개발자들 사이에서 다소 교조적으로 받아들여지는 경향이 있다고 생각합니다. 나중에 시간이 난다면 한 번 다루어 보고 싶은 주제네요.

    테스트 케이스를 작성하고 싶은데 어떤 내용을 넣어야 할지 모르겠다면 테스트를 대상 API의 규약이나 명세를 검증하는 것, 혹은 그런 내용을 코드로 표현하는 것이라는 관점으로 접근하는 것을 추천 드리고 싶습니다.

    특히 각 API 메서드의 입출력 값, 그리고 호출 전후의 상태 변화 등을 검증하는 코드를 마치 명세에 대한 예시를 작성한다는 느낌으로 만들어 보는 것도 좋습니다.

    이후 여력이 되면 목업이나 픽스쳐를 자동으로 제공하는 방법 같은 내용을 공부해보시는 것도 추천드리고 싶습니다.

  • vollfeed
    1k
    2019-04-05 17:01:49

    테스트를 작성하는 것은 문제가 아닙니다. 

    사실 별거 없어요. 

    그냥 환경이 이렇고, 입력이 이러면 결과가 이래야한다를 사례별로 쓰는것 뿐이거든요. 

    (Given When Then 포맷도 있구요)

    문제가 생기는 케이스(경계 조건이 합니다)를 생각하는건 순전히 프로그래머 역량이긴하나,

    격지 않은 문제를 예측하는게 어렵지,

    일단 문제가 생겨서 격어보면 재현 코드는 쓸 수 있습니다. (애초에 랜덤 확률등장이면 안되지만요..)

    그래서 테스트 작성은 난관이 아닙니다. 


    TDD를 진행하는데 있어 가장 큰 문제는 테스트를 작성하는게 아니라,   

    첫째는 tester가 testee의 모든것을 통제/감시 할수 있어야 한다는 것입니다.

    둘째는 어떤 결과를 보고 이상없음을 확인 해줘야하는데,

    tester는 그걸 계산할수 없고, testee만 계산 할수 있는데,  검증은 tester가 해야한다는게 문제죠.


    또, 개발진행하면서 변경사항이 발생할때 테스트를 일일이 수정해야하면 

    그건 그것대로 또 지옥도가 펼쳐지죠. 

    예전에 저는 이걸  oop설계로 해결할수 있을거라 생각했었는데, 안되더군요. 

    지금은 나름대로 다른 해법을 찾아서 시도해보고있는데, 쉽게 덤벼들 부분은 아닙니다. 


    쉽게 생각하고 하려고하면,

    tester 프로그램이 더이상 완벽히 환경을 통제할수 없을 때,

    더 이상 TDD의 결과를 신뢰 할 수 없다로 귀결 되어버리기 때문이죠.


    대부분의 팀/조직에서 TDD도입이 실패하는 이유가 이것 때문이라고 판단하고있습니다.

    TDD만드는게 보통일이 아닌데, 

    어느 순간, 그걸 더이상 신뢰할수 없게 되버리면 의욕도 목적도 없어지거든요.

    또한 TDD할 시간에 개발하는게 낫다. 라는 결론도 같이 나오죠.


  • fender
    20k
    2019-04-05 17:35:19

    Frudy //

    단순히 로그인기능을 예시로 든다면 테스트코드를..
    1. 값 잘 넣어서 원하는 유저DTO 성공반환하는 코드
    2. 틀린 정보 넣었을 떄 null을 반환하는 코드
    이런느낌으로 작성하라는 말씀이신가요?

    참고로 TDD와 단위 테스트는 다른 것입니다만, 이 경우에는 조금 쯤 TDD의 관점을 차용해 보는 것이 문제를 이해하는데 도움이 될 것 같습니다.

    TDD는 단위 테스트를 개발 방법론으로 확장한 것이고, 방법론은 보통 사용자 요구 조건에 대한 명세를 작성하는 방식을 제시합니다.

    예를들어 로그인에 대한 '유즈 케이스(use case)'는 보통 다음과 같은 내용을 담고 있습니다:


    내용을 보면, 기본적인 흐름이외에 '예외 조건'과 '성공 조건'을 정의하는 것을 알 수 있습니다. 그리고 원론적으로 말하면 코딩은 위와 같은 사용자 시나리오를 코드, 혹은 API로 표현하는 것이고, 테스트는 그런 표현이 원래의 설계한 내용에 적합한지에 맞게 검증하는 것입니다.

    그렇다면 이를 테스트로 표현한다면, 로그인에 대한 테스트 스윗(suite)에 정상적인 로그인 케이스(test case), 그리고 로그인 실패 케이스 등을 정의하고, 테스트 구현은 위의 예제에서 '기본 흐름'이라고 정리된 내용을 코드로 표현하고, 성공 케이스에 대해서는 성공 조건(post condition)을 검증(assert)하며, 실패 조건에 대해서는 예외 흐름(혹은 'alternative flow')를 검증하는 것을 각 테스트 케이스의 목적으로 삼으면 됩니다.

    참고로 테스트의 세분성(granularity)은 테스트의 성격에 따라 다를 수 있기 때문에, 가장 상세한 단계의 단위테스트라면 로그인과 같은 비즈니스적인 요구조건을 테스트하기 보다는 개별 메서드 단위의 API 검증을 목적으로 하는 경우가 있습니다. 하지만 이 경우는 해당 API의 요구조건 및 성공 조건, 예외 조건 등을 분석해서 테스트를 작성한다는 점에서는 위에서 예로든 로그인의 경우와 크게 다를 바가 없습니다.

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