테스트를 자주 만드는 개발자들은 알겠지만, 테스트를 만드는 것은 그닥 어렵지 않다. 테스트를 잘 만드는 것이 어려울 뿐이다.

테스트를 만들고 코드를 작성하고, 테스트를 변경하고 코드를 변경하고....반복된 작업을 하다가 보면, 내가 무슨 짓을 하고 있는지 감을 잡기도 어렵고, 테스트를 매번 고쳐주는 것도 싫증이 난다.

자꾸 테스트가 깨지는 이유가 무엇일까?
그 중에 대표적인 경우가 테스트할 메소드 안에서 테스트된 메소드나 다른 메소들을 호출을 할때 새로운 메소드가 추가가 되면서 깨지는 경우가 많다. 그 경우 메소드 안에서 호출한 메소들이 모두 깨지게 되는데 이 현상을 해결하려면 하나의 로직을 변경했다고 하더라도 테스트를 통과하기 위해 여러개의 단위 테스트 메소드에 손이 가야 한다. (음..말이 좀 어렵군) 단위 테스트에 다수의 경험이 있으신 분들중에 이 고민 안해본적 없을 것이다.

난 3가지 경우로 문제를 해결을 한다.
1. delegate class
2. method overriding
3. 자신의 레퍼런스를 mock으로 치환

1번의 경우 작업들이 비교적 순차적이고, 응집성이 높은 작업들을 할때 extract class를 통해서 가독성도 좋아지고, host class의 dependency가 이뻐보이게 될떄는 1번을 사용한다. 이 방법이 가장 정석적인 방법이다.

근데, 애매한 메소드들이 있다. host와 dependency가 거의 같고, seperate를 하자니 클래스도 많아지고 웬지모를 찜찜한 기분이 들떄는 과감하게 2번을 사용한다.  약간의 노출수위(private->protected)가 거슬리기는 하지만, 견고한 테스트를 만든다면, 약간의 노출은 괜찮다는 생각이다.

3번의 경우는 클래스를 테스트할 때 특정메소드에 집중해서 테스트를 할때 사용이 된다. 특정 메소드를 중점으로 테스트를 하고 나머지 부분들은 단순 콜만 된다면, 만족스러운 테스트인 경우이다. 테스트할 메소드의 갯수에 따라서 서비스 코드를 잘 짜야 하는 경우이다.

3 번의 경우도 몇번 고려는 했었는데, 특이한 경우 안이면, 난 1,2번을 선호하는 편이다. 1번은 테스트의 정석인 방법이라 제일 먼저 고려를 해보는 방법이고, 2번은 mock을 만들지 않고 비교적 쉽게 테스트가 가능하다는 것이 장점이다.

3번의 경우를 고려해 볼수 있는 것은 거의 대부분 1번으로 처리를 하려고 하고, 1,2번 사이에서 메소들의 행위나 특성들이 애매할 경우는 범위를 고려해서 3번을 선택한다.

갑자기 이 글을 쓴 것은 아래 글을 읽다가 나도 비슷한 경우의 경험을 많이 해서 흔적으로 남기고 싶어서이다. 아래 내용을 읽고 위에 내용을 보면, 좀더 이해가 쉬울 것이다. EP처럼 구체적인 예로 적을 수도 있지만, 워낙 설명을 잘해놔서 아래 내용을 참고하는게 더 나을거라는 생각이다. 내가 제시한 3가지 사례중 주로 3번에 대한 내용을 구체적으로 잘 설명을 했다.
http://colus.egloos.com/4639268
Posted by ologist
운영 및 유지보수라는 단어의 의미는 너무나 다양하고, 광범위하게 쓰인다

소프트웨어 유지보수의 중요성 을 보면서 다시 한번 유지보수에 대해서 생각을 하게 되었고, 테스트의 중요성에 대해서 생각을 해봤다.

시스템에 따라서 행위가 많이 달라지기 때문이다. 개발자들은 유지보수를 많이 해봐야한다. 유지보수를 해보지 않고, 신규 개발을 잘하기는 정말 어렵다. 시스템의 라이프싸이클이 개발하는 기간보다는 유지보수를 하는 기간이 훨씬 길다는 사실은 너무나 잘 아는 이야기이다.

나는 하나의 시스템을 가지고,  4년동안 유지보수를 해본 경험이 있다. 앞으로도 쉽게 가질 수 있는 소중한 경험이었다. 그 경험은 나에게 큰 도움이 되고 있다. 유지보수를 오래할 수록 안정적이게 된다. 물론, 그 도메인 영역에 대한 이해도가 높아져서이기도 하지만, 자주 있는 일에 대한 테스트를 하나씩 만들어서 추가를 하기때문이기도 하다.

제일 중요한 포인트는 어떤 방식으로던지 테스트가 가능해야 하다는 것이다. 테스트를 1초라도 빨리할 수 있으면 유지보수시에 잦은 변경사항을 적은 노력으로 버그를 최소화하면서 변경을 할수가 있다. 초보시절에는(junit을 사용하기전에는) 주로  웹서버에서
굵게주로 테스트를 하는 mock페이지를 많이 만들었는데, 몇 년전부터 지금까지는 junit을 이용해서 단위 테스트를 가능한 많이 만들고 있다.

단위 테스트만큼 빠르게 테스트가 가능한 것은 없을 것이다.
난 더욱더 테스트 중독에 빠지려고 한다.





Posted by ologist

2006/07/16 11:48 Developer

SQL 쿼리 테스트

쿼리가 3개가 있다고 하자.
퍼포먼스 테스트가 필요한 순간이다.

DB를 잘 아는 사람은 벤더에 맞는 plan계획과 기타 주요정보가 나오는 곳에서 쿼리를 한개씩 돌려서  특정 횟수를 실행한 다음 그래프를 그리고, 평균을 내서 보고서를 작성하면 된다.
물론, 오차를 일으킬수 있는 element들을 표시해주면 더 좋은 보고서가 될 것이다. 쿼리 최적화에는 좋을거 같다.

하지만, 최적의 쿼리를 랭귀지를 통해서 쓴다면, 경우가 틀려질수도 있다. 퍼포먼스(비용)가 틀려질수가 있는 것이다. 일단, DB를 넘어서서 프로그램 랭귀지 안에서 테스트를 생각해보자. 단위 코드들들 작성을 할 것이다. 오차를 일으킬 만한 것들을 최소한을 하고, 네크웍 연결이라던가..기타등등....

그리고, 한방에...그래픽컬하게 볼수 있고, 그런 방법이 뭐가 있을까?
자바진영에서는 여기에 가장 손쉽게 이용할 만한 라이브러리중에 JUNIT이 있다.
코드 개발뒤에 테스트, 테스트를 하면서 개발, 퍼포먼스 체크를 위한 테스트...모두에 JUNIT은 유익한 툴일 것이다.

같은 결과를 원하는 3가지의 쿼리를 테스트한다고 가정을 하자.

1. setup : 메소드에 DB연결정보를 넣는다.
2. 각각의 메소드를 구현한다.
3. run을 한다.

웹에 적용할 쿼리지만, DB연결 자체에서 오는 네크워크의 오차를 줄일수가 있고, 쿼리와 자바랭귀지 안에서의 처리까지 테스트가 가능한다. 자바에서 그 쿼리 실행을 위해서 순수하게 쓰이는 퍼포먼스에 가깝게 구할수가 있다. 
Posted by ologist
 TAG junit
  • 자동적
    테스트는 자동으로 실행이 되야 한다. IDE에서 버튼 하나, 명령 프롬프트에서 명령하나로 실행. 테스트에서 수동단계가 있으면 자동 모델이 망가질수 있다.
  • 철저함
    코드의 모든 줄 하나하나 코드가 취할수 있는 모든 분기, 코드가 일으키는 모든 예외 등을 테스트한다.
  • 반복 가능
    모든 테스트들은 다른 테스트들로부터 독립적이어야 한다. 환경으로부터도 독립적이어야 한다. 어떤 순서로든 여러 번 반복 실행될 수 있어야 하고, 늘 같은 결과가 나와야 한다.환경으로부터의 독립적으로 만들기 위해서 mock object를 사용한다.
  • 독립적
    환경이 다른 개발자들에게서 독립적인 상태를 유지해야 한다. 어떤 테스트도 다른 테스트에 의존하지 않는다는 것을 의미한다. 어느 순서로든, 어떤 개별 테스트라도 실행해 볼수 있어야 한다.
  • 전문적
    단위 테스트를 이해서 작성하는 코드는 진짜다. 전문적인 표준을 유지하면서 작성되어야 한다는 것을 의미한다. 함수나 객체 같은것은 보이지도 않고 코드의 같은 줄만 계속 써가면서 같은 일만 여러번 반복하는 코드는 좋지 않다. 데이터 주도적 테스트를 돕는 코드를 만들어야 한다.
Posted by ologist
 TAG junit, TDD
이전버튼 1 이전버튼

블로그 이미지
ologist

공지사항

Yesterday191
Today137
Total34,709

달력

 « |  » 2012.02
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29      

최근에 받은 트랙백

글 보관함