우연히 알게된 블로그입니다. 테스트에 대한 멋진글이 연작으로 올라오고 있어서 소개해 드립니다. Yagur의 Juggling이라는 블로그의 테스트와 장인 입니다. 현재까지 6개가 올라와 있습니다만 앞으로 계속 쓰실거 같습니다. 제목에서 벌써 포스가 느껴지시지 않나요. ^^
테스트와 장인1 - 품질 분석 그리고 개선(Quality analysis and improvement) 테스트와 장인2 - 주기적 테스트(Cyclic Test) 테스트와 장인3 - 테스트 집합 그리고 재사용성(Test-sets and Reusability) 테스트와 장인4 - 테스트 의존성과 진화(Test dependency and evolution) 테스트와 장인5 - 테스트 엔트로피(Test Entropy) 테스트와 장인6 - 테스트 의존성의 함정(Trap of Test Dependencies)
명확한 기준은 있을수 없다. 단위 테스트의 대상이 뭐냐에 따라 달라지기 때문이다. 만일 특정 클래스에 대한 단위 테스트라면 클래스나 오퍼레이션이 될거고, 컴포넌트라면 컴포넌트가 될거다. 하지만 단위 테스트 특성상 컴포넌트와 컴포넌트간의 결합이 있는 경우라면 이를 분리하는게 맞을거 같다. 단위가 너무 커버리면 단위 테스트와 통합 테스트의 경계가 모호해 지는 문제가 있다. 이에 대한 기준을 현재 단위 테스트를 개발하는 프로젝트 컨텍스트에 맞게 정의해야 한다.
사실 이렇게 까지 장황하지는 않았구요. 대충 이랬습니다. ^^ ACM에서 나온 재밌는 논문이 하나 있네요. 보통 단위 테스트의 범위는 스케일이 작은게 보통인데 이를 이용해서 스케일이 큰 테스트를 어떻게 하는가에 대한 방법을 제시하고 있는 논문입니다.
단위테스트 코드를 더 잘 작성하고 싶다면 어떻게 해야 할까요 ? 자료를 찾다가 괜찮은 사이트를 하나 발견했습니다. MARC CLIFTON이라는 분의 사이트인데 제 눈에 확 띄는 글은 Unit Test Patterns 이네요.
단위테스트를 작성해야 한다는건 많은 개발자가 공감하는 부분입니다. 하지만 어렵죠. ^^ Marc Clifton은 어려워 하는 이유를 두가지로 들고 있습니다.
첫번째, 정형화된 단위 테스트 엔지니어링 원칙의 부재
두번째, 단위 테스트를 작성하는데 필요한 설계가 선행되지 않기 때문에 작성하기 어렵다.
이 두가지 문제를 해결 하기 위한 대안으로 Unit Test Patterns를 제시하고 있습니다. 총 24개의 패턴을 다음과 같은 카테고리로 구분해서 다이어 그램과 같이 잘 정리해 놨습니다.
pass/fail patterns
collection management patterns
data driven patterns
performance patterns
process patterns
simulation patterns
multithreading patterns
stress test patterns
코드가 없는게 흠인데 그건 아마 이 패턴을 특정 플랫폼에 국한해서 설명하고 싶지 않아서 그러지 않았을까. 저자는 닷넷쪽 전문가 같습니다. 현장에서 테스트 코드 작성을 독려하면서 제가 대안으로 제시했던게 설계단계에서 테스트를 고려해서 단위테스트를 설계하라고 가이드 한적이 있습니다. 사실 이렇게 한 이유는 간단합니다. TDD를 설계까지 올린것 뿐입니다. 시간내서 꼼꼼히 뜯어봐야 겠습니다. 문제는 시간인데..^^
지난주 월요일부터 목요일까지 진행된 ASTA 국제 테스트 컨퍼런스에 참가했습니다. 이번 행사는 STA를 비롯한 여러 단체의 주관으로 삼성역 컨퍼런스 센터에서 열렸고 2일간의 튜토리얼과 2일간의 컨퍼런스로 진행됐다.
튜토리얼은 한 명의 강사에게 하루종일 같은 주제로 강의를 듣는 식이었는데 깊이 있는 이야기를 나눌수 있어서 무척 마음에 들었다. 내가 들은건 Klaus Olsen의 "SCRUM을 테스트 조직에 적용한 사례"와 Rex Black의 "테스트 케이스를 효율적으로 설계하는 방법"에 대한 주제 였는데, 특히 Rex Black의 강의는 새로운 경험이었다. 역시 포스가 느껴지는게~. (정리해서 블로깅하려고 준비중이니 기대하시라. ^^)
컨퍼런스는 주제별로 한시간 내외로 진행이 되서 여러 주제를 접할수 있는건 좋았지만 역시 시간과 공간의 한계때문에 튜토리얼을 들은 나한테는 내심 아쉬웠다. 차라리 튜토리얼을 4일 해주었으면 하는 바램이 물밀듯이..^^
컨퍼런스 둘째날에 들은것중에 테스트 계획에 대한 세션이 있었습니다. 이 세션에서 재밌는것이 기억난다.
테스트 계획을 크게 두 부분으로 나눈다.:위험하고 중요한 부분(critical & major)과 그렇지 않은 부분. 그리고 각 부분에 대해서 어떻게 테스트를 하느냐에 따라 다시 두 영역으로 구분한다. 수동테스트와 자동테스트(manual & automation)
또 하나 재미있는 세션하나가 오랫동안 테스트 업무를 해온 분이 경험을 이야기하는 세션이었는데 산 경험에서 나온 내용이어서 현실적이었다. 그중에 기억나는게 KISS.
Keep It Simple and Short
사실 비싼 비용때문에 참가를 망설였던게 사실이다. 참가를 하기로 결정한 후에도 튜토리얼만 들을지 컨퍼런스 까지 들을지 고민도 했고..국내에서 처음 열린 테스트 컨퍼런스라는데 큰 의미를 들수 있겠지만 개인적으로 많은 아쉬움이 남는데..
비싼 참가 비용 : STA에서는 국제 컨퍼런스를 저렴한 비용으로 국내에서 들을수 있다라고 홍보했다. 하지만 많은 사람들의 자발적인 참여를 이끌어 내기 위해서는 좀 더 다양한 형태의 등록방법을 제공했을수도 있을거 같다. 예를 들어 중식비나 저녁, 기념품 같은걸 제외하고 실비만 받는 등록형태라던가 아니면 이런 기념품을 없애고 등록비를 낮출수도 있지 않았을까.
운영 미흡 : 국제 컨퍼런스라는것에 걸맞는 운영은 아니었던거 같다. KOEX 1층에 컨퍼런스를 알리는 안내 하나 보지 못했다. 그리고 4일 내내 참여하면서 매일 중식비를 받아야 했는데 왜 귀찮게 이렇게 한건지 이해가 안간다.
컨퍼런스 내용 : 일부 후원사에서 제공했던 세션은 그 수준이 다른 발표자에 비해 많이 떨어지는 내용이었다. 물론 모든 세션이 다 좋을수는 없을것이다. 하지만 무료 행사가 아니지 않은가.
이번 테스트 컨퍼런스에 참여하면서 여름에 있었던
Web App Conference 2007 이 생각났다. 비록 하루 였지만 수많은 사람들이 12시간이 넘게 떠들었던 기억이.. 이 테스트 컨퍼런스가 이번 한번으로 끝나지 않고 내년, 후년에도 계속되서 한국의 척박한 소프트웨어 개발의 좋은 토대를 만들어 주길 기대한다.
테스트 자동화라는 것을 현장에 적용하기 위해서는 단순히 솔루션을 설치하는것으로는 부족하다. 현장의 Context를 이해하고, 현장의 요구사항을 수집하고, 소프트웨어 아키텍처, 개발프로세스를 분석하여 문제점을 찾아야 한다.
이를 바탕으로 테스트 자동화를 적용여부를 판단하여야 한다. 인프라만을 적용할 것인가 ? 단위테스트를 작성할 것인가 ? 등등..
자바언어를 사용하는 경우 클래스명, 메소드명, 패키지명,변수명 등을 한글로 하는것이 가능하다. 그러나 주위를 둘러봐도 이렇게 하는 사람은 없다. 왜 없을까 ?
소위 말하는 자바 컨벤션에 어긋나서 ? 에디터에 따라서 한글이 깨지는 현상 때문에 ? 왠지 불안해서 ?
그럼 좋다. 테스트케이스를 한글로 만드는것은 어떻게 생각하는가. 테스트 클래스는 관두고 그 안에 각각의 메소드를 테스트 하는 메소드를 한글로 하면 안될까 ?
보통 테스트메소드라 하면 testXXX() 식으로 이름을 짖는다. 이걸 test_게시물등록() 이런식으로 말이다. 결과를 봐도 직관적이고 좋을거 같은데..
테스트케이스를 만들때 흔히 고민하는 것중 하나가 새로운 데이터를 추가하고 삭제하는 부분이다. 새 데이터를 추가하고 나서
동일한 데이터를 추가하는 테스트가 실행되면 TestCase에는 문제가 없어도 에러를 발생시킨다. 삭제의 경우에도 이미 삭제한
데이터에 대해서 다시 테스트가 실행되면 똑같은 에러가 발생한다. 이런 경우를 피하기 위하여 TestCase를 작성할때 특정
TestCase에 의존할수도 없다. 왜냐하면 모든 TestCase는 다른 TestCase에 대하여 독립이여야 하기 때문이다.
새로운 데이터를 추가하는 TestCase 를 먼저 작성한다. 테스트가 성공하면 삭제에 대한 TestCase를 추가하지 않고
기존의 테스트 데이터를 추가하는 TestCase를 수정하여 삭제를 추가한다. 이렇게 하면 두가지 이점이 생긴다.
- 새글이 작성되었는지 확인이 가능하다.
- 글을 삭제할때 삭제할 글이 없어서 생기는 문제가 발생하지 않는다.
“시간이 흐르고 현실의 복잡성이 증가하면서 프로그래밍 언어가 변화를 축적해 나아가다가 결국 더 높은 추상성을 가지고 있는
새로운 언어에게 자리를 내어준다는 사실과, 프로그래머의 안목이 높아지고 실력이 늘어나면 그가 작성하는 코드의 추상성이 차츰
높아진다는 사실 사이에는 ‘추상성’의 증가라는 공통점이 존재하는 것이다.”
마소 6월에서 읽은 칼럼에서 따왔다. 이 칼럼에서도 Struts의 폐혜(?)를 들고있다. 한때 나도 Struts의
광팬이었지만 지금은 그 Configuration의 복잡함에 질려버린 상태다. 가장 쓰기 싫어하는 프레임웍중 하나라고 생각하면서
대안을 제시 못하는 자신이 싫다.
개발자 두명당 테스터를 한명씩 붙인다면 버그는 확실히 줄어들것이다. 어떻게 들으면 미친소리 같이 들리기도 하다. (이거 내가 처음 한말이 아니다. 조엘이
했다.) 하지만 조금 긍정적으로 생각해보자.테스트 만큼 지겹고 따분한 일이 없다. 비싼 돈 주고 어렵게 구한 개발자에게 왜
그런일을 시키는가.차라리 아르바이트생을 고용해서 붙여주지. 그럼 그만큼 개발자에게는 더 많은일을 시킬수가 있게된다. 이게 더
이익아닌가 ? 가끔은 돈으로 해결할수 있는일이 제일 쉬운일이라는 생각이 든다.
테스트용이성(testability) 이란 아키텍처를 구성하는 구성요소들이 얼마나 테스트에 적합한가를 나타내는 품질속성이라
할수있다. 테스트용이성을 좋게 하기 위해서는 아키텍처를 설계하는 단계에서부터 이를 고려하지 않으면 안된다. 구성요소들간의 관계와
구성요소 자체를 어떻게 구현하느냐가 모두 테스트 용이성에 영향을 미치기 때문이다.
자동화된 단위테스트는 격리된 상태로 유닛을 테스트한다. 외부 호출을 처리하기 위한 일련의 기능들이 생성되고, 내부 호출을
제공하기 위한 드라이버가 만들어진다. 이를 테스트 드라이버라고 한다. 이 테스트드라이버를 만들수 있는가 역시 테스트용이성에 따라
결정된다.
상속을 사용하게 되면 이미 테스트를 완료한 코드를 전혀 수정하지 않고 손쉽게 재사용하고 확장 할 수 있다. 상속을 사용하지
않고 기존 애플리케이션을 재 사용 했다고 가정해 보자. 문제가 발생하지 않는지 확인하기 위해 애플리케이션 전체를 다시 테스트
해야만 한다. 하지만 상속을 사용한 경우라면 이야기가 달라진다. 서브클래스(subclass)를 정의했다 하더라도
수퍼클래스(superclass)의 소스는 전혀 수정하지 않았기 때문에 그 부분에 대한 테스트는 필요없다. 새롭게 추가된 부분만
테스트 하면 된다.
오버라이딩(Overriding)은 메소드의 인터페이스/시그너처를 변경하지 않고 내부적으로 동작하는 방식을 '재작성'하는
것이다. 오버라이딩으로 서브클래스에서 메소드를 재정의 하게되면 위에서 말한 이점을 더욱 살릴수 있다. 오버라이딩된 메소드만
테스트 하면 수퍼클래스의 신뢰된 메소드를 모두 사용할 수 있다. 그러나 오버로딩(Overloading)은 다르다. 시그너처가
다른 n개의 메소드가 독립적으로 존재함으로 각각의 경우마다 테스트가 필요하다.