sitelink1 | http://wiki.javajigi.net/pages/viewpage.action?pageId=278 |
---|---|
sitelink2 | |
sitelink3 | |
extra_vars4 | |
extra_vars5 | |
extra_vars6 |
JUnit을 이용한효율적인테스트전략
Table of Contents
테스트란?
- 자동화된 테스트란? 유형은?
- 단위테스트 : JUnit
- 통합/컨테이너 내부 테스트 : Cactus
- 수락/기능 테스트 : HttpUnit.
Preview
- 자동화된 테스트란? 유형은?
- 자동화된 테스팅이란 특히 XP에서 중요시 되는 활동이다.
- 물론 어느 방법론에 국한될 필요는 없으나
- 어떤 점에서 잇점이 있는지의 여부의 판단은 중요하다고 생각한다.
- XP의 중요한 문제는 리팩토링이다.
- 리팩토링이란 간단하게 설명하면 오브젝트
책임의 명확성과 중복의 제거,
- 그리고 코드의 간결함 일것이라 생각한다.
- 자동화된 테스팅은 리팩토링을 하는 프로그래머에 확신을 준다.
- 그리고 리팩토링은 궁극적으로 테스트를 통해서 완성이 된다.
- 자동화된 테스트 유형
- unit test는 가장 많이 언급되는 테스트 유형이나 이것은 전체테스팅의 일부이다.
- 단위테스트는 통합테스트, 기능 테스트, 기타 테스트와 함께 사용되어 시스템의 동작이 의도에 맞게 동작함을 보증한다.
- 테스트의 종류 ( 간략하게 정리 )
- 단위테스트 : JUnit
- 단위테스트는 단위 코드에서 문제 발생 소지가 있는 모든 부분을 테스트 하는 작업이다.
- 보통 클래스의 public method 를 테스트 한다.
- 좋은 단위 테스트란 모든 메서드를 테스트 하는 것이 아니라,
- 상식 수준의 확인을 통해 단위 코드가 의도한 대로 동작하는지 여부를 판단하는 단계이다.
- 이상적으로는 코딩전에 테스트 케이스를 작성하여 구현시 보조자료로 활용하는 것이 좋다. ( TDD의 기법 )
- 단위테스트 후에 개발팀은 테스트를 프로젝트 테스트 스위트에 추가하여 매일 여러번 수행하고 모든 테스트를 항상 통과하게 해야 한다.
- 기회가 된다면 Code Coverage 를 하는 것이 좋은데
- 오픈소스로는 JCoverage 등이 있다. - 참고 : j2eestudy자료
- 통합/컨테이너 내부 테스트 : Cactus
- 좋은 단위 테스트는 시스템내의 복잡한 부분에 관계없이 클래스 내의 함수들을 검사하는 것이다.
- 단위 테스트는 가능한 의존성 없이 독립적으로 처리되어야 한다.
- Mock Object 로 테스트를 하는 경우도 있지만,
- Cactus 는 J2EE 컨테이너에 접근하는 방법을 제공한다.
- 컨테이너 안에서 코드 테스트가 가능하도록 하기 위해서 Cactus 는 상세하거나 또는 까다로운
- 실제와 같은 모형을(mock-ups) 개발자에게 제공한다.
- 이 방법은 실행되는 코드가 제품이 출시되는 환경에서 실행되기 때문에 또 다른 피드백 기준을 제공한다.
- 컨테이너 서비스와 상호 작용하는 단일 오브젝트 경우에 컨테이너 내부 테스트를 사용하여 간편한 단위 테스트를 할 수 있다.
- 수락/기능 테스트 : HttpUnit
- 기능 테스트는 전체 시스템이 의도한 바대로 동작하는 지를 검사하는 과정이다.
- 이 방법은 완성된 시스템을 고객으로부터 검사받는 방법이므로 수락 테스트라고도 한다.
- 기능 테스트는 구조적 기능에 대하여 어떤 프로그램의 기능에 대한 시험이며 진척 상태를 확인하고
- 이전의 테스트나 누락된 결점을 잡아내거나 미완성 또는 불완전한 부분에서 발생된 문제를 찾아내는 것이 중요하다.
- 수락 테스트는 고객에 의해 작성된다.
- 기능 테스트는 항상 100% 구현될 필요는 없으나 제품 출시 전에는 100% 수행 되어야 할것이다.
- 기능 테스는 종종 매우 구체적인 내용들을 테스트 하기도 한다.
- 아직은 통괄적인 수락 테스팅 툴은 나오지 않았고 Junit은 어떤 자바클래스에서도 수행될 수 있으나
- 수락 테스팅 도구는 특정 애플리케이션 요구에 따라 작성되어야 한다.
- HttpUnit을 이용하면 테스팅 API를 이용하여 웹 리소스에 대한 호출과 응답 값 조회를 프로그래밍 할 수 있도록 한다.
**부하테스트 : JMeter, JUnitPerf등
**인수테스트 : .
- 단위테스트 : JUnit
About Junit
기존에 TDD의 개념은 있었으나 도와주는 도구의 부재로 자바 개발자들은 주로 main() 에서 테스트 하는 방식을 주로 이용했을 것이다.
먼저 JUnit이 무엇이고 테스트란 무엇인지 알아보자.
테스트 코드는 작성시에 일반적으로 권장되는 몇가지 사항이 있다.
- 이름짓기 규칙
- 테스트 코드는 이런 작업들을 수행하도록 설정한다.
- JUnit 이란 독립된 테스트를 할 수 있도록 도와주는 framework이다.
- JUnit은 웹에서 무료로 다운로드할 수 있다. 설치는 classpath 환경 변수에 추가해주면 완료.
- 우리는 이클립스 환경에서 사용할 것이므로 별다른 설치 없이 이클립스에서 제공하는 기능을 사용한다.
- 이클립스의 Junit화면
- JUnit의 단정메서드들 ( assert )
- 이 assert 메서드들은 테스트 대상이 되는 메서드의 검증을 위해 테스트 메서드 하나에는 assert 메서드가 여러개 들어간다.
assert 메서드가 하나라도 실패하면 테스트 메서드는 중단되고, 나머지 assert 메서드들은 실행되지 않는다. - JUnit프레임워크
- import문으로 junit클래스들을 참조
- 테스트를 포함한 클래스는 모두 TestCase를 상속해야 한다.
- 테스트 클래스는 각 test.... 메서드를 정의한다.
- 모든 test..... 메서드는 Junit에 의해 자동으로 실행된다.
- Junit 테스트 조합
- test suite가 이것을 가능하게 하는데 모든 테스트 클래스는 suite라는 이름의 정적 메서드를 가질 수 있다.
- public static Test suite();
- 원하는 테스트 묶음을 반환하는 suite() 메서드를 작성하면 된다.
( 이 suite() 메서드가 없으면 JUnit은 모든 test.... 메서드를 자동으로 실행한다. )
- 테스트별 준비 설정과 정리
- setUp() 메서드는 각 test..... 메서드들이 실행되기전에 호출된다.
- tearDown() 메서드는 각각의 테스트 메서드들이 실행되고 난 다음에 호출된다.
// 이 코드는 간단한 프레임워크및 실행순서를 보여준다. oneTimeSetup(){} //- 한번만 실행되는 스위트를 시작할 때의 준비설정코드와 끝날때의 정리코드 setUp(){} //- 메서드별로 테스트 메서드 이전에 실행되는 준비설정코드와, 이후에 실행되는 정리코드 testMethod(){} tearDown(){} setUp(){} testMethod2(){} tearDown(){} oneTimeTearDown(){}
예를들어, 테스트마다 db연결 객체가 필요하다고 가정할때,
데이터베이스에 연결하고 접속을 종료하는 코드를 각 테스트 메서드에 일일이 넣을 필요 없이
setUp()과 tearDown() 메서드를 이용하여 해결하면 될것이다.
ex)
public Class TestDb extends TestCase(){ private Connection dbConn; protected void setUp(){ dbConn = new Connection( "oracle", 1521, "scott", "tiger"); dbConn.connect(); } protected void tearDown(){ dbConn.disconnect(); dbConn = null; } public void testEmpAccess(){ //dbConn 사용 어쩌고 저쩌고.... } public void testDeptAccess(){ //dbConn 사용 어쩌고 저쩌고.... }
- 이 간단한 예제에서는 setUp이 호출된 다음에 testEmpAccess() 가 호출이 되고 tearDown() 이 호출된다.
- 그리고 setUp() 이 다시 호출되고 testEmpAccess() 가 실행되고 난 후에 tearDown()이 다시 호출된다.
대개는 이렇게 테스트별 준비 설정만으로 충분하지만
어떤 상황에서는 "전체" 테스트 스위트를 실행하기위해 어떤것을 설정하거나 정리해야 할 필요가 있다.
이런 경우 스위트별 준비 설정과 정리가 필요한데 이 설정은 조금 더 복잡하다.
필요한 테스트들의 스위트를 반들어서 TestSetup 객체 안에 감싸 넣어야 한다.
public static Test suite() { TestSuite suite = new TestSuite(); // Only include short tests suite.addTest(new TestClassTwo("testShortTest")); suite.addTest(new TestClassTwo("testAnotherShortTest")); junit.extensions.TestSetup wrapper = junit.extensions.TestSetup(suite) { // TestSetup 클래스의 setUp과 tearDown() 메서드를 재정의 한다. protected void setUp() { oneTimeSetUp(); } protected void tearDown() { oneTimeTearDown(); } }; return wrapper; } public static void oneTimeSetUp() { // 한번만 실행되는 초기화 코드가 여기에 들어간다. tsp = new TSP(); tsp.loadCities("EasternSeaboard"); } public static void oneTimeTearDown() { // one-time cleanup code goes here... tsp.releaseCities(); }
- JUnit에서 제공하는 asssert 메서드만 사용하는 것보다 직접 사용자 정의 클래스를 만들어 상속하여 사용하는 것이 좋다.
- JUnit과 예외
- 테스트에서 발생하는 예상된 예외
- 뭔가 크게 잘못 되어서 발생하는, 예상하지 못한 예외
우리가 일반적으로 생각하는 것과는 달리 예외는 무언가 잘못되었다는 것을 알려주는 굉장히 유용한 도구다.
가끔 테스트에서는 테스트 대상이 되는 메서드가 예외를 발생시키기를 '바라는' 경우도 있다.
sortList()라는 메서드를 생각해보자. 이 메서드는 빈 목록을 받았을때 예외를 발생시켜야 한다.public void testForException(){ try{ sortList(null); fail("Should have trown an exception"); } catch (RuntimeException e){ assertTrue(ture); } }
이 테스트 메서드의 경우 sortList를 테스트 할때 null이 넘어가면 예외를 발생시키는게 맞는 제어흐름이므로
catch절에 assertTrue(ture); 가 수행이 된다.
즉, 이는 나중에라도 코드를 잘못 해석할 가능성을 막아주는 강력한 문서화 기법이다.
다만 assertTrue(ture); 가 호출되지 않는다 하더라도 테스트가 실패하는 것은 아니라는 것은 명심하라.
그렇다면 예상하지 못한 예외들은?
사용자가 직접 처리하는 메서드를 구현할 수 있겠으나
메서드 선언부에 throws 절을 명시해 준다면 JUnit 프레임워크가 발생한 모든 예외를 잡아서 실패한 assert메서드를 출력하며
버그에 이르기까지 "전체" 호출 스택을 출력해 주므로 무엇때문인지 알아볼 때 많은 도움이 된다.
이것은 ,, 실제 테스트할 준비가 될때까지 메서드의 이름을 test로 시작하는 메서드가 아니라면 실행을 하지 않게 할수 있다는 것을 의미한다.
다만, 익숙해져선 안되는 것은 바로 테스트가 실패하는데도 이를 무시하는 습관이다.
! 무엇을 테스트 할것인가?
- 결과가 옳은가? - 당연한 말이다.
- 경계조건 - 대부분의 버그는 보통 '경계'에 서식한다.
- 역관계 확인 - 논리적 inverse를 적용하여 검증해 볼 수 있다.
- 다른 수단을 이용한 교차확인
- 에러조건을 강제로 만들어내기
- 성능특성
모의객체 사용하기 - 단위 테스트의 목표는 한번에 메서드 하나를 테스트 하는 것이다. 하지만, 테스트 하기가 어려운 상황이라면?
- 간단한 스텁 - 설계를 테스트 하는 동안 코드에서 임시로 만들어 사용한다.
예)public long getTime(){ if( debug ){ return debug_cur_time; }else{ return System.currentTimeMillis(); } }
하지만 우리에게 필요한것은 똑같은 일을 해내면서 더 깔끔하고, 더 객체지향 적인 방법이다.
- 모의 객체
모의 객체를 사용하기 위한 세단계
*객체를 설명하기 위해 인터페이스를 사용한다.
*제품 코드에 맞게 그 인터페이스를 구현한다.
*테스트에 쓸 모의 객체의 인터페이스를 구현한다.
참고자료
http://sourceforge.net/projects/mockobjects
http://www.easymock.org
모의 객체의 사용법의 핵심은 각자가 흉내내는 뭔가에 의존하는 객체를 테스트 하기 위한것이다.
- 좋은 테스트의 특징
- 자동적 : 테스트를 실행하는 경우와 결과를 확인하는 경우를 모두 의미하는 것.
- 철저함 - 문제가 될 수 있는 것은 모두 테스트한다.
- 반복가능
- 독립적
- 다른 테스트로부터도 독립적, 환경, 다른 개발자 로부터도 독립적
- 전문적 : 전문적 표준을 유지하면서 작성되어야 한다.
- 프로젝트에서 코드의 구조화의 방법
- 팀작업에서 소스 공유시 테스트 예절은 말 하지 않아도 중요하다는 것에 모두 동의 하실 것이다.
- 테스트빈도의 종류
Using JUnit Simple Demo
먼저 테스트 해 볼 것은 간단한 예제로 주어진 배열중 가장 큰수를 리턴하는 메서드를 작성하는 테스트를 작성해 보기로 한다.
그리고 TestSuite의 사용법을 위해 TestCase를 더 작성후 TestSuite를 작성해본다.
Make TestCases













Make TestSuite






JUnit을 이용한 테스트 전략
전략을 논한다.
현재 내가 알고 있는 지식으로는 어불성설인것 같다.
쉽게 생각하고 접근하기도 너무 넓게 보고 접근하기도 힘든 부분이 없지않아 있다.
Test 를 함에 있어서 자동화된 테스트의 개념이 매우 중요하게 자리잡고 있다.
자동화된 테스트를 위해서는 ANT나 Maven등의 빌드 툴의 사용 또한 익혀야 하며 지속적인 소스통합에 대한 전략과 함께
CodeCoverage 를 할 수 있는 ( 얼마나 빌드했으며 실패율과 성공률을 보기위한 ) 툴이 필수 인듯 싶다.
JUnit과 TestCase, 자동화된 테스트등을 보아오면서 느낀점은
프로그램을 작성하기전 무엇을 테스트 할것인가와 더불어 어떻게 테스트 할 것인가에 대한 전략을 세우는 것이 가장 어렵고도 중요한 작업이다.
정리는 차차 해 나가기로 하겠다.. **********
맺지 못한 이야기
간단한 게시판 어플리케이션을 JUnit과 Cactus를 이용하여 작성하는 sample
참고서적
- http://www.javajigi.net
- 실용주의 프로그래머를 위한 junit
- java tools for extreme programming
논외
*TDD는 다음과 같은 순서로 진행을 하면 된다. 이 순서는 켄트벡이 제시한 순서이다.
1. Quickly add a test(테스트 프로그램을 작성한다.)
2. Run all tests and see the new one fail
(모든 테스트 프로그램을 수행시키고 테스트에 실패한 부분을 확인한다.)
3. Make a little change(소스를 추가하거나 변경한다.)
4. Run all tests and see them all succeed
(다시 모든 테스트를 수행시키고 모두 테스트를 통과했는데 확인한다.)
5. Refactor to remove duplication(중복을 제거하기 위해 Refactoring 한다.)
*이클립스에서 TestCase자동생성




문서에 대하여6
*작성자 : 장회수
*작성일 : 2005년 7월 7일
*문서버전 : 1.0
상태 : *작성중
*참고자료
-
- http://www.javajigi.net
- 실용주의 프로그래머를 위한 junit
- java tools for extreme programming
댓글 0
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
13 |
이클립스에서 JUnit 사용하기
![]() | 황제낙엽 | 2019.04.02 | 172 |
12 | JUnit 간단 정리 | 황제낙엽 | 2007.09.17 | 81 |
11 | JUnit 3.8에서 JUnit 4, TestNG 활용으로 | 황제낙엽 | 2007.09.17 | 421 |
10 | 이클립스에 JUnit Test 환경 설정하기 | 황제낙엽 | 2007.08.28 | 102 |
9 | Unitils 를 이용해 Spring Test의 편리성 획득하기 | 황제낙엽 | 2007.09.04 | 128 |
8 | Assertions : 비교 확인, 조건 확인, Null 확인 | 황제낙엽 | 2007.09.03 | 209 |
7 | JUnit 4로 뛰어들기 (한글) | 황제낙엽 | 2007.09.03 | 180 |
6 | Test-Driven Development by JUnit | 황제낙엽 | 2006.02.21 | 150 |
5 | jWebUnit 프레임웍으로 웹 애플리케이션 테스트를 간단하게 | 황제낙엽 | 2006.02.21 | 69 |
4 | [re] jWebUnit 프레임웍 로그인 테스트 예제 | 황제낙엽 | 2006.02.22 | 70 |
3 | jWebUnit 의 원조 HttpUnit | 황제낙엽 | 2006.02.23 | 70 |
» | Junit 을 이용한 효율적인 단위 테스트 전략 | 황제낙엽 | 2007.01.30 | 368 |
1 | JUnit의 구조 | 황제낙엽 | 2007.07.25 | 88 |