정보공간_1

[4기 강북 송용길] Unit test with JUnit 본문

IT 놀이터/Elite Member Tech & Talk

[4기 강북 송용길] Unit test with JUnit

알 수 없는 사용자 2013. 11. 23. 02:04

안녕하세요

 강북 멤버십 22기 송용길입니다.

엘리트 회원이라는 자격으로 이렇게 멤버십 블로그에 저의 족적을 남길 수 있다는 사실에 제 스스로가 무척이나 자랑스럽습니다. 여타 다른 훌륭한 회원들과 함께 소프트웨어멤버십의 회원으로서 이 글을 읽고 계신 분들께 어떤 글을 써야 하나 고민이 많았습니다. 그러던 중 소프트웨어 개발자로서 가장 중요한 것임을 알지만 간과하기 쉬운 단위 테스트에 대해 글을 써보는 것은 어떨까하는 생각이 들었습니다. 그리하여 저의 포스팅 주제는 JUnit툴을 이용한 단위테스트 입니다.

 JUnit이란 툴을 설명하기에 앞서 단위테스트에 대하여 알아보도록 하겠습니다.

 지난 번에 제가 과제를 진행하면서 JUnit을 통해 팀원들이 작성한 코드를 테스트해야하는 업무를 담당한 적이 있었습니다. 사실 그 때 만해도 저는 단위테스트에 대해서 아는 것이 많지 않았습니다. 또 '왜 굳이 개발자가 테스트를 해야하지?'라는 생각도 가지고 있었습니다. 하지만 맡은 바 업무를 달성하기 위해서는 단위테스트에 대하여 공부할 필요가 있었습니다. 공부를 위해 책을 선택하고 그 책의 서론을 읽고나서 제 생각은 180도 바뀌게 되었습니다. '코드의 테스트는 그 코드를 작성한 (그 코드에 대해서 가장 잘 아는) 개발자가 하는 것이 옳다!'는 것이 요즘의 제 생각입니다. 그 책에서 읽었던 단위테스트에 대한 것과 왜 개발자가 테스트를 진행해야 하는 지에 대한 몇 가지를 소개해 드리겠습니다.

 1. 확신을 갖고 코딩하기

 마감에 쫓기며 고군분투하는 개발자 두 명이있습니다. 한 친구는 (A라 칭하겠습니다.) 코드를 아주 빠르게 만들어 냈습니다. 종종 멈추어서 그 코드가 제대로 컴파일 되는 지를 확인해 나갓습니다. A는 빠른 시간 안에 코드를 완성하였습니다. 자, 이제 컴파일이 아닌 최종 실행의 단계가 왔습니다. 하지만 원하는 결과가 나오는 것은 고사하고 아무것도 나오지 않습니다. A는 생각합니다. '이제 디버깅을 할 차례군...' 마감 일은 다가오고있고 버그를 찾기 위해 A는 몇 날 며칠 밤을 지새웁니다. 그렇지만 아직도 결과가 나오고 있지 않습니다.

 한편 다른 한 친구 B는 그렇게 빠르다고는 할 수 없는 속도로 코드를 작성합니다. B는 클래스를 작성할 때마다, 혹은 클래스내의 메소드들을 작성할 때마다 짧은 테스트 코드를 함께 작성하였습니다. 정말 짧은 테스트 코드입니다. 그저 이 메소드가 제대로 내가 원하는 값을 내놓는지 확인을 하기 위한 코드였습니다. 예를 들자면 Add함수가 제대로 더하기를 하는지 확인하는 코드가 되겠지요. B는 그런식으로 자기가 작성한 클래스나 메소드가 검증이 되기 전까지는 일을 진행하지 않았습니다. B는 디버거도 거의 사용하는 일이 없었습니다.

 마침내 다가온 마감일. 결과는 이 글을 읽고 계신 모두가 알고 계시겠지요? 자 그렇다면 A와 B의 차이는 무엇일까요? 네 B는 각각의 코드에 대한 단위테스트를 굳게 믿었고, 새로 작성한 코드를 사용하기 전에 반드시 테스트하여 검증 후 사용했다는 점입니다. A의 문제라면 '내가 생각한 대로 이 코드는 돌아가 줄거야' 라고 기정사실화하고 그 코드를 사용했다는 것입니다. 

 2. 단위 테스트란 무엇인가?

 자 그렇다면 B의 업무를 성공으로 이끈 단위테스트는 무엇일까요?

 단위 테스트는 말 그대로 테스트 대상 코드의 아주 작은 '특정 영역''실행'해 보는 '개발자가 작성한' 코드 조각입니다.

 예를 들어 계산기의 기능을 하는 클래스를 작성한다고 가정해보겠습니다. 계산기에는 여러가지 오퍼레이터가 있습니다. +, -, *, / 등등... 이 오퍼레이터들은 계산기 클래스 내에서 메소드로 구현되어 있을 것입니다. 이 계산기가 오작동 하지 않으려면 오퍼레이터 메소드들이 사용자가 원하는 결과 값들을 제대로 반환해 주어야 합니다. 

 이 경우 자신의 코드를 백퍼센트 믿는 자신감도 중요하지만, 이 메소드는 제대로 동작한다는 검증과 확신이 필요합니다. 그 확신을 갖기 위해 검증의 절차를 갖는 것이 단위테스트입니다. '+' 오퍼레이터 메소드를 테스트 하기 위해서 메소드의 인자로 두 항을 넣고 원하는 결과 값이 나오는 지를 확인해 보는 과정이 단위테스트를 진행했다고 할 수 있겠습니다.

 앞서 말씀드렸던 '대상 코드(계산기 클래스)의 아주작은 특정 영역(+ 오퍼레이터 메소드)실행(인자를 넣고 원하는 값이 나오길 기다림)해 보는 개발자(코드 작성자)가 작성한 코드 조각(단위 테스트)' 이라는 문장이 이해가 가시나요?

 3. 왜 내가 귀찮게 단위 테스트를 해야 하지?

 단위 테스트는 우리 개발자들의 삶을 편하게 해줍니다. 설계를 좀 더 좋게 만들어 주고, 디버깅에 낭비하던 시간을 극적으로 줄여 줍니다.

 첫 번째 사례에서 나왔던 A라는 친구는 자신의 코드에 제대로 확신하지 못한 채, 가정만으로 트럼프 카드 탑을 쌓아 올리고 있었습니다. 굳이 쌓아 보지 않은 사람이라도 그 탑이 얼마나 위태로운지는 알고 있습니다.

 하위 레벨의 코드를 신뢰할 수 없다면, 낮은 레벨의 코드만을 고친다고 해서 문제가 해결되진 않습니다. 하위 레벨의 잘못된 코드는 그 상위로, 또 그 위로, 그 위로 영향을 끼치다 결국 전체로 영향을 끼쳐 악영향을 끼치게 됩니다. 개발을 해보신 분들이라면 이런 말 한 번씩은 해보지 않았나 싶습니다. '아...도대체 어디서 뭐가 잘못 됐는지 모르겠어.' 보통 이런 말들이 자기 코드를 충분히 검증하지 못했음을 알려주는 아주 좋은(?) 징표입니다.

 이러한 일을 막기위해 개발자는 자신의 코드에게 '너 무슨일을 하고 있니?'라고 물어봐야하고 그 결과가 내가 원하는 것과 같은지 확인해야하는 절차가 반드시 필요합니다.

 4. 단위 테스트는 어떻게 해야 하는가?

 단위테스트는 어렵지 않습니다. 정말 쉬운 기법입니다. 이 쉬운 기법을 더 쉽게, 더 효과적으로 하기 위해 따를 수 있는 지침과 일반적인 단계가 잇습니다.

 첫 단계는 문제가 되는 메소드를 어떻게 테스트 할지를 결정하는 것입니다. 이 결정은 코드를 작성하기 전에 하는 것이 옳습니다. 그래야 결정해 놓은 테스트 방법을 통과시키기 위한 코드가 작성되니 말입니다. 

 다음으로 테스트와 시스템의 그 부분에 있는 다른 테스트들을, 또는 전체 시스템의 테스트들까지도 실행해 봐야합니다. 테스트는 '모두'통과해야 합니다. 테스트가 모두 통과되는 것은 후 일 일어날 수 있는 버그를 예방하는 것입니다.

 마지막으로 모든 테스트는 자신이 통과되는지 아닌지 판정할 수 있어야 합니다. 만약 테스트 코드를 짰는데 이 코드가 제대로 된 결과가 나왔는지 일일이 눈으로 확인해야 한다면 그 테스트 코드는 가치가 없습니다. 스스로 판정하는 방법은 후에 포스팅될 프레임워크 사용법에서 자세히 다루도록 하겠습니다.

 지금까지 개발자가 꼭 갖추어야할 자질인 단위 테스트의 당위성에 대해 설명하였습니다. 서론이 조금 길었습니다. 하지만 단위테스트가 개발자에게 얼마나 중요한지를 생각해 본다면 길지만은 않은 설득이라 생각합니다. 다음 포스팅에서는 첫 단위 테스트를 주제로 찾아뵙겠습니다. 지루한 제 글을 읽어주신 모든 분께 고개숙여 감사의 인사를 전하며 이만 물러가 보도록 하겠습니다.



참고서적

[1] 데이비드 토머스, 앤드류 헌트, "단위 테스트 with JUnit", 2004