functional test vs. unit test

권순선의 이미지

functional test가 더 효과적인 경우는 언제이고, unit test가 더 효과적인 경우는 또 언제인가요?

각각이 장단점이 있을테고 무조건 어느 한가지만으로 코드의 품질이 향상되지는 않을 텐데... 이에 대한 다른 분들의 경험이 궁금합니다. 특히 unit test와 관련... 실제로 이를 어느 수준까지, 어떻게 수행하고 계신지 상당히 궁금하네요.

johan의 이미지

제 일터의 경우 3가지 정도의 테스트 셋을 갖고 있는데요, 모두 실제 설계 혹은 사용례를 바탕으로 테스트 합니다:

1. 비공개 인 함수들을 사용하는 테스트 - 저희는 유닛 테스트라고 부릅니다.
2. Public API만을 사용하는 테스트 - 저희는 API 테스트라고 부릅니다.
3. Web Browser를 사용하는 테스트 - 저희는 웹 UI 테스트라고 부릅니다.

저희는 각각 로우레벨에서 하이레벨까지 위의 세부분의 셋을 갖고 있는데요, 이를테면, 로긴시 예외상황에 대해 1에서는 원하는 exception object가 발생하는가, 각 상황에 맞게 실제 컴퓨터 내부(이를테면 DB)에 옳바른 작업이 수행되는가 등등을 수단과 방법을 가리지 않고 테스트 합니다.
2에서는 public API에서만 점검할 수 있는 내용을 public API만 거쳐서 테스트 합니다. 예를들면 public API의 예외처리는 로우레벨보다 추가적인 일들을 해야 하는 경우가 있는데 그런 내용을 주로 테스트 합니다. 또, 인하우스 혹은 third party framework에 대해서도 테스트 케이스 있습니다.
3에서는 주로 웹브라우저상의 위젯들이 원하는 대로 작동하는지, 최종 에러 메세지, 예외상황에서의 처리 (redirection 등), Javascript 동작, 크로스 웹브라우저 작동 등을 Selenium 통해서 점검합니다. 시스템 내부의 state를 기억한 후, Selenium을 통해 특정 오퍼레이션을 한 후, 시스템 state가 원하는 대로 되었는가, 혹은 web browser의 Javascript object가 원하는 상태로 되었는가 등을 테스트 합니다.

Selenium 라이브러리만 빼고 모두 인하우스로 개발한 테스트 플레임워크 사용합니다.

어떤 테스트이든지 실제 어떻게 작동해야 한다는 구체적 설계상의 시나리오가 있어야 합니다. 아니면 뻔한 것을 테스트 하게 되던지 엉뚱한 것을 테스트 하게 되더군요.

가능한한 각 레벨에서 꼭 필요하고 레벨을 수직으로 중복하는 테스트는 없게 하려고 노력합니다.

조금만 복잡하거나 어렵다고 느껴지면 먼저 테스트 케이스부터 작성하고, 중요한 버그가 발견되었을 시에도 실수를 반복하지 않으려고 테스트 작성합니다. 모든 테스트 돌아가는 시간이 한 1시간쯤 되는 것 같네요 - 특히 Selenium을 통한 테스트는 느려서 야간에 자동으로 매일 돌아가고 결과만 보고하도록 동료가 작업하고 있습니다. 약 10년간 500여개의 테스트 케이스가 부산물로 나왔네요. 초기 200-300개 정도는 설계 직후 테스트 케이스를 만들면서 시스템 구현할 때 작성된 것들이고 나머지는 필요하다고 판단이 설때마다 만든 것들입니다.

테스트 케이스를 작성할 때는 이렇게 까지 해야하나 할때도 있지만, 결국 "기민하게 움직이도록" 해주고 이로인해 그렇게 하지 않는 것보다 총 시간과 노력은 절약됩니다:

* 새 기능 혹은 버그픽스시 기존 시스템의 중요 기능에 문제가 생기는지 기존 테스트를 돌려서 최소한의 것들을 확인할 수 있다.
* 언제 중앙 저장소에 커밋할 지 명확하다 - 모든 테스트가 통과했을 시
* 실제 구현에 앞서 테스트 작성중 스펙이나 디자인 상의 오류가 발견되는 경우가 있다
* 신입에게 (문서보조로) 테스트 케이스를 시스템에 익히는데 도움이 되는 도구로 활용
* 새로운 third party library 업그레이드 결정 전에 문제가 있을 수 있는지 빠르게 체크

테스트는 설계의 거울과도 같다고 생각합니다. 여자들이 얼굴에 그림(?)을 그릴 때 그러하듯이 조금 그려보고 거울보고 지우고 새로 그리고... 조금 설계해 보고, 테스트 만들어 보고, 다시 설계하고 다시 테스트 만들어서 돌려보고 하는 일련의 작업이 잘 이루어져야 제대로 된 예쁜 얼굴(?) 혹은 어플리케이션이 나올 수 있다고 생각합니다.

winner의 이미지

혹시 QA 팀이 없는 것은?...

johan의 이미지

최근까지 없다가 QA 담당하는 사람이 하나 생겼습니다. 그동안은 필요성이 그리 크지 않았는데 시스템이 점차 거대해지면서 미처 예상치 못한 문제들이 발생하기 시작했고 결국 QA 담당을 두게 되었습니다. 원래는 시스템 어드민 하는 사람인데, 워낙 잘해서 별로 해야할 일거리가 없기 때문에 QA도 함께 하게 되었습니다(본인도 좋아 하더군요) 똑똑하고 부지런한 사람이라 대부분 스스로 뭘해야 할지 결정합니다만, 그래도 시스템을 만든 사람보다 잘 알겠습니까? 언제든 필요한 일이 생기면 상의하고 대개의 경우 개발자들이 최우선적으로 지원해 줍니다 - 가장 고급인력인 팀리더가 그 일을 주로 합니다. 팀리더 그냥 매니저 아니라 아주 똑똑한 프로그래머 입니다 (데이터만 보고도 왜 그런 일이 발생하는지 추론하는 수학적 감각도 대단한 사람입니다).

QA만 전담으로 여러사람이 하는 회사에도 있어봤는데, 그 때도 누군가 개발자가 교대로 QA 팀 가까이에서 도왔습니다 (그때는 QA팀과 개발팀이 10시간 이상 시차상의 거리에 있었기 때문에 3-6개월 마다 개발자가 교대로 파견갔었습니다)

위에서 말한 테스트는 모두 개발팀에서 맡고 있는 것들이고, QA는 스스로 항목을 정해서 그에 따라 (아직까지는) 손수 점검하며 최근에는 개발팀과 함께 Jmeter를 이용해서 벤치마크 베이스라인 설정 및 새 버전 비교하고 있습니다. 시간이 지나면 항목들이 늘어나고 필요에 따라 자동화도 필요하고 다양한 일들이 필요하리라 봅니다.

lacovnk의 이미지

전 개인 Rails 프로젝트에서 Cucumber 이용중입니다. BDD 만세!

예전에는 Rails에서 제공하는 unit + functional + integration을 시도했었는데 아무래도 실제 사용예와는 멀어지다보니 테스트셋을 만들 의욕이 떨어지더군요. :(

아무튼 뭐가 되든, 테스트를 잘 짜기 어렵더군요. 중복되기도 쉽고.. “잘 키운 테스터 열 개발자 안부럽다”? :)