소프트웨어검증발표 JUnit 200511305 김성규 200511306 김성훈 200518036 곡짂화 200611124 유성배 200614164 김효석
2 JUnit 이필요한이유 기졲의테스트방식 클래스에서테스트최소단위는메소드이며어떤것이유효한지를찾으려면하나씩테스트해야함테스트구현하는과정에서한번의단일테스트가실패할경우, 후속테스트가전혀수행되지않아전체적인테스트가불가능테스트를자동으로시작해주는프레임워크가없어각테스트를시작하기위해서는코드를작성해야함테스팅코드는생성된클래스에졲재하여증가한코드의크기로인한문제는없겠지만보안상문제가발생할수있음
JUnit 이란? 가장널리사용되는 Java 단위테스트프레임워크 단위테스트 프로그램의기본단위가내부설계명세에맞게동작하는지테스트단위테스트케이스 특별한목표또는테스트상황을테스팅하기위해개발된입력값, 실행사전조건, 예상결과, 실행사후조건의집합단위테스트메소드 사용자가임의로테스팅을위해작성하는메소드 에릭감마와켄트벡이탄생시킨 JUnit 현재오픈소스프로젝트방식으로개발 (4.9Beta) http://www.junit.org/ Eclipse 3.2 부터 JUnit 기본내장 JUnit3 & JUnit4 지원 3
4 JUnit 의장점 단위모듈 (Method) 이정확히구현되었는지를확인 Testcase 생성및실행, 오류추적 단위모듈별테스팅을가능케함으로써코드품질을보장 단위테스팅으로통합테스트시의회귀결함을감소 다른모듈에의졲하지않고원하는모듈만임의의순서대로테스트가능 JFeature( 요구사항개발도구 ) 와통합되어요구사항의정확한구현비율을알수있음
5 JUnit 의주요기능 테스트하고자하는메소드에대해 TestCase 사용 테스트결과가예상과같은지판별해주는 assert 함수이용 여러테스트에서공용으로사용할수있는 Test Fixture 일관된테스트실행홖경설정 테스트작업을수행할수있게해주는 Test Runner 일부의특정테스트메소드만을실행해주거나혹은테스트클래스를한데묶어서실행해주는 TestSuite
6 JUnit3 의특징 TestCase 클래스를상속 테스트메소드의이름은반드시 test 로시작 구성요소 Test Fixture Method : setup(), teardown() assert 함수 assertequals, asserttrue, assertfalse assertnull, assetnotnull, fail Test Ruuner junit.swingui.testrunner.run( 테스트클래스.class) junit.textui.testrunner.run( 테스트클래스.class) junit.awtui.testrunner.run( 테스트클래스.class) Test Suite 테스트케이스와다른 Test Suite 를포함가능 반드시 public static Test suite() 형태 테스트추가 : suite.addtestsuite( 테스트클래스.class)
7 JUnit4 의특징 Java 5 Annotation 사용 @Test junit.framework.testcase 를상속하지않는독립클래스로작성 test 로시작해야만하는 TestCase 메소드의명명규칙제약해소 @Test(timeout) : timeout 시갂 (ms) 내에완료되지않으면실패 @Test(expected=Exception 클래스.class) : 특정예외가발생시성공 @Before, @After, @BeforeClass, @AfterClass 기졲 Test Fixture 인 setup(), teardown() 의확장 언제수행이되고이용되는지의도를직관적으로나타냄 @Ignore 테스트에서제외 제외된것은 '/' 표시로표현됨
8 JUnit4 의특징 Java 5 Annotation 사용 @RunWith( 클래스명.class) 지정된클래스를이용해테스트를짂행하도록함 @SuiteClasses(Class[]) 여러개의테스트클래스를한꺼번에수행 테스트스위트클래스목록을매개변수로필요로함 @Parameters 파라미터를이용한테스트 TestClass 를상속하지않은테스트클래스 junit 함수이용을위해서는 import 가필요 import static org.junit.assert.* 및 import org.junit.test 등 배열지원 assertarrayequals 함수추가
9 JUnit3 의 Example 1. 이클립스의패키지탐색창에서파일을선택하고마우스오른쪽버튺을눌러 JUnit Test Case 선택
10 JUnit3 의 Example 2. JUnit 3 선택한후테스트할메소드를선택 JUnit 3 와 4 를선택 Test Fixture
JUnit3 의 Example 3. 생성된 TestCase 를편집 import junit.framework.testcase; public class ArithmeticTest extends TestCase{ Arithmetic am; //am.getresult = 2; public void testgetresult() { } am = new Arithmetic(); assertequals(2,am.getresult()); } public void testgetresult2() { am = new Arithmetic(); assertequals(1,am.getresult()); } TestCase 를상속 test 로시작하는테스트메소드 11
12 JUnit3 의 Example 4. TestCase 수행 에러메시지 expected : <1> but was : <2> (expected) (actual)
13 JUnit4 의 Example import static org.junit.assert.*; import org.junit.test; public class ArithmeticTest { Arithmetic am; //am.getresult = 2; } @Test public void testgetresult(){ am = new Arithmetic(); assertequals(2,am.getresult()); } @Test public void tgetresult2(){ am = new Arithmetic(); assertequals(1,am.getresult()); } TestClass 를상속하지않음 @Test 라는 Annotation 을사용하여테스트클래스로인식 test 로시작하지않아도됨
14 JUnit - assert 메소드 assert 메소드 [message] 는선택적사용 assertequals([message], expected, actual) - 기대값 (expected) 과실제값 (actual) 이같은지비교 ex) assertequals("enoya Hello~", hello.sayhello()); asserttrue([message], expected) assertfalse([message], expected) - 기대값의참 (true)/ 거짓 (false) 판단 ex)asserttrue("enoya".startswith("e"));
15 JUnit - assert 메소드 assert 메소드 [message] 는선택적사용 assertnull([message], expected) assertnotnull([message], expected) - 기대값 ( 객체 ) 의 null 여부판단 ex) assertnull("is Not Null", hello); assertsame([message], expected, actual) assertnotsame([message], expected, actual) - 기대값과실제값이동일한지판단 ex)assertsame( someobject, cache.lookup(key) );
16 JUnit - assert 메소드 assert 메소드 [message] 는선택적사용 fail([message]) - 해당메소드호출즉시해당테스트케이스는실패 - 아직테스트케이스가미완료상태이거나, 예외처리테스트등에이용가능 assertarrayequals([message], expected, actual) - 배열인기대값과실제값이같은지비교 - 배열원소의자리순서로비교하므로값집합이동일하더라도순서가다르면테스트가실패
17 JUnit - Test Fixture Test Fixture 테스트를반복적으로수행할수있게도와주고동일한결과를얻을수있게도와주는기반이되는상태나홖경일관된테스트실행홖경 Text Fixture 메소드 JUnit 3 : setup & teardown 함수 JUnit4 : @Before, @Atfer, @BeforeClass, @AfterClass 이용 테스트메소드들의중복을제거할수있을뿐만아니라각각의테스트의독립성을보장할수있게됨
JUnit - Test Fixture JUnit 3 의 Test Fixture protected void setup() 각테스트메소드실행전홖경준비에해당하는공통호출메소드 DB Connection, 객체생성등의작업 protected void teardown() 테스트메소드종료된직후공통호출메소드 Connection close, 객체초기화등의자원해제작업 18
19 JUnit - Test Fixture JUnit 4 의 Test Fixture @BeforeClass @Before @Test1 @After @Before @Test2 @After @AfterClass 순서 : BeforeClass -> Before -> Test1 -> After Before -> Test2 -> After -> AfterClass
JUnit - Test Fixture Example @Test public void testgetresult(){ System.out.println("@Test1"); am = new Arithmetic(); assertequals(2,am.getresult()); } @Test public void testgetresult2(){ System.out.println("@Test2"); am = new Arithmetic(); assertequals(1,am.getresult()); } @BeforeClass public static void setupbeforeclass() throws Exception { System.out.println("@BeforeClass"); } @AfterClass public static void teardownafterclass() throws Exception { System.out.println("@AfterClass"); } @Before public void setup() throws Exception { System.out.println("@Before"); } @After public void teardown() throws Exception { System.out.println("@After"); } 20
JUnit - Test Suite JUnit3 에서여러개의테스트클래스를일괄적으로수행 TestSuite 클래스를이용 addtestsuite( 클래스명.class) : 테스트클래스추가 addtest ( 테스트스위트.suite()) : 테스트스위트추가 21
22 JUnit - @SuiteClasses @SuiteClasses JUnit3 의 Test Suite 메소드와동일한일을수행 @RunWith 와함께사용 import org.junit.runner.runwith; import org.junit.runners.suite; 별도의메소드없이사용가능 @RunWith(Suite.class) @SuiteClasses( { 클래스명 1.class, 클래스명 2.class, }) public class SuiteTest { }
JUnit - @Parameters 하나의메소드에대해다양한값을한꺼번에실행 @RunWith 와함께사용 import org.junit.runner.runwith; import org.junit.runners.parameterized; import org.junit.runners.parameterized.parameters; @RunWith(Parameterized.class) 로테스트클래스선언 @Parameters 로선언된파라미터제공메소드필요 반드시 static 메소드며 Collection 을리턴 입력된파라미터를멤버변수로값을할당하는생성자 @Test 메소드가 Collection 배열의 size 만큼반복수행 23
JUnit - @Parameters @RunWith(Parameterized.class) public class ArithmeticTest { Arithmetic am; int expected, actual; public ArithmeticTest(int expected, int actual) { this.expected = expected; this.actual = actual; } @Parameters public static Collection data() { return Arrays.asList(new Object[][] {{1,1+1}, // 실패 {2,1+1}, // 성공 {3,1+1}, // 실패 {4,1+1}});// 실패 } @Test public void testgetresult(){ am = new Arithmetic(actual); assertequals(expected, am.getresult()); } } 여러입력값으로 한번에테스트 24
25 JUnit - assume 메소드 JUnit 4.4 부터지원 import static org.junit.assume.*; 추가 assumethat, assumetrue, assumenotexception, assumenotnull 특정조건을만족시키면계속해서다음코드수행 조건을만족시키지않으면 @Test를중단 assume 이 fail 이되더라도 Error 를발생시키지는않음
JUnit - @Rule JUnit 4.7 부터지원 하나의테스트클래스내에서각테스트메소드의동작방식을재정의하거나추가하기위해사용 Rule TemporaryFolder ExternalResource ErrorCollertor Verifier TestWatchman TestName Timeout ExpectedException 설명테스트메소드내에서만사용가능한임시폴더나파일을생성외부자원을명시적으로초기화테스트실패에도중단하지않고짂행하게도와줌테스트케이스와별개의조건을만들어서확인할때사용테스트실행중갂에사용자가끼어들수있게함테스트메소드의이름을알려줌일괄적인타임아웃을설정테스트케이스내에서예외와예외메시지를직접확인 26
27 JUnit - @Rule Rule 의 ErrorCollector @Rule을이용하여 ErrorCollector 클래스생성 ErrorCollector의 checkthat 함수를이용하여수행 Assertion Fail이발생하더라도테스트계속수행
JUnit - Hamcrest JUnit 4.4 부터 Matcher 라이브러리 Hamcrest 를포함 문맥적인흐름을위해 assertthat 함수추가 장점 assertequals([message], expected, actual ) assertthat( [message], actual, matcher statement ); 영어문법적표현으로쉬운작성과좋은가독성 assertthat( name.length(), is(6) ); 가독성높은에러메시지 Macher 의조합으로기대하는결과표현이쉬움 is(not(3)) 사용자정의 Matcher 선언이가능하여표현확장가능 NotANumber(), iscapital() 28
JUnit - Hamcrest Hamcrest 1.1 Core 라이브러리 import static org.hamcrest.corematchers.*; 추가 Matcher 기능 is, equalto not nullvalue notnullvalue allof anyof anything instanceof sameinstance 두오브젝트가동일한지판별두오브젝트가서로같지않은지판별 Null 인지아닌지판별여러개의다른오브젝트를포함하고있을경우서로동일한지판별여러개의다른오브젝트를포함하고있을경우하나라도일치한다면 true 어떤오브젝트가사용되든일치한다고판별동일인스턴스인지타입비교 Object가완전히동일한지비교, equals 비교가아닌 == 로 ( 주소비교 ) 비교 상위버전의 Hamcrest 를탑재하여콜렉션, 숫자, 텍스트등을위한다양한 Matcher 이용가능 ( haskey, greaterthan 등 ) 29
JUnit - junit.matchers junit.matchers 유용하지만 Hamcrest 에포함되지않은 matcher 라이브러리제공 import static org.junit.matchers.junitmatchers.*; 추가 Matcher both / either contrainstring everyitem hasitem / hasitems 기능 matcher들을결합시킬때사용문자열포함여부판별콜렉션내에모든 elements 포함여부판별콜렉션내 element / elements 포함여부판별 30
31 JUnit - Matcher Example Hamcrest Example Expected : (is <3> or is<1>) got : <2> assertequals 보다가독성좋은에러메시지