1. 단위테스트란 무엇인가?
'단위 테스트' 는 테스트 대상이 되는 코드 기능의 아주 작은 특정 영역을 실행해 보는 개발자가 작성한 코드 조각이다.
( 단위 테스트는 전적으로 개발자의 몫이다! 단위테스트 계획서, 결과서 등의 산출물 역시 마찬가지이다.)
2. 어떤 것을 테스트 해야 하는가?
2.1 자신이 생각한 대로 코드가 동작하고 있는지를 증명하라
2.2 디스크가 꽉차고, 네트워크는 끊어지고, 버퍼는 오버플로우가 되는 예외 상황에서도 코드가 동작하는가?
2.3 팀원들이 자신이 작성한 코드의 사용법과 의도를 알수 있도록 단위테스트에 대한 계획과 결과를 문서화 하라
3. 실제 단위 테스트 실행
실제로 단위테스트를 진행하기 위해서는 코드를 모두 완성한 후에 한다고 착각하지 마시길 바란다.
위에서도 명명한 바와같이 우리는 자신의 코드를 조각내어 아주 작은 단위의 코드를 테스트하면서 개발할 것이다.
(테스트 주도 개발에서는 결코 모든 설계를 마치고 개발에 들어가지 않는다.
그것은 결국 폭포수 방법론을 벗어나지 못하는 것이다)
Junit 의 단정(assert) 메소드와 null 메소드를 하여 왠만한 테스트를 모두 진행 할 수 있다.
Junit 단정 메소드의 예:
assertNull()
assertNotNull()
assertSame()
assertNotSame()
assertTrue()
assertFalse()
fail()
.
.
3.1 java 코드를 junit 을 통하여 테스트할 때의 기본 골격은 아래와 같다.
-----------------------------------------------------------------------------------------------
import junit.frameWork.*
public class TestSimple extents TestCase {
public TestSimple(String name){
super()
}
//테스트할 메소드
}
-----------------------------------------------------------------------------------------------
색깔 표시된 부분은 기본적으로 코딩해야하는 골격이다.
3.2 테스트할 메소드를 추가하자
기본적으로 junit 은 test로 시작하는 메소드를 자동으로 인식한다. 그러므로 junit 으로 테스트할 메소드의 이름은
test로 시작하도록 명명하고, 만약 여러개의 테스트 할 메소드들이 존재할 경우
하나씩 단계적으로 테스트 하고 싶어질 것이다.
이럴 경우 메소드 이름은 임시로 pendingTestxxxx 이런식으로 바꾸어 놓았다가 테스트 할 차례가 되면 testxxxx로 변경하여
테스트를 수행할 수도 있다.
3.3 Junit 테스트 샘플
-----------------------------------------------------------------------------------------------
import junit.frameWork.*
public class TestSimple extents TestCase {
public TestSimple(String name){
super()
}
//테스트할 메소드
public void TestAdd(){
assertEquals(2, calculateSomeThing(2,4) );
}
public int calculateSomeThing(int A, int B ){
return 2;
}
}
-----------------------------------------------------------------------------------------------
TestAdd 메소드는 실제 테스트를 원하는 메소드이다.
assertEquals 은 Junit 에서 지원하는 단정 메소드로 테스트의 결과를 판단하기 위해 지정한다.
calculateSomeThing 메소드는 아직 코딩 되지 않았다. 하지만 TestAdd 메소드를 테스트 하기 위해 필요하므로
가상의 메소드를 코딩해 놓았다.
물론 TestAdd 메소드의 테스트가 끝나면 calculateSomeThing 를 작성하여 테스트 할 것이다.
3.4 Junit 의 테스트 조합 - suite()
테스트를 수행하다 보면 여러개의 테스트 메소드를 한번에 수행하고 싶어는 경우도 발생할 것이다.
분석한 업무 프로세스에 따라서 충분히 이러한 경우가 발생할 것인데 이럴경우에 테스트를 조합하여 수행하여 보자
-----------------------------------------------------------------------------------------------
import junit.frameWork.*
public class TestSimple extents TestCase {
public TestSimple(String name){
super()
}
//테스트할 메소드
public void testAddition(){
assertEquals(4,2+2);
}
public void testSubtraction(){
assertEquals(0,2-2);
}
}
-----------------------------------------------------------------------------------------------
testAddition 와 testSubtraction 메소드를 한꺼번에 수행해 보자
-----------------------------------------------------------------------------------------------
import junit.frameWork.*
public class TestSimple extents TestCase {
public TestSimple(String name){
super()
}
//테스트할 메소드
public void testAddition(){
assertEquals(4,2+2);
}
public void testSubtraction(){
assertEquals(0,2-2);
}
public static Test suite(){
TestSuite suite = new TestSuite();
//suite 에 테스트 메소드를 추가한다.
suite.add(new TestSimple ("testAddition"));
suite.add(new TestSimple ("testSubtraction"));
return suite;
}
}
-----------------------------------------------------------------------------------------------
main 메소드에서 suite 를 실행하면 testAddition, testSubtraction 두개의 테스트 메소드가 실행된 결과를 반환할 것이다.
그렇다면 이제 조금더 응집도를 분산시켜보자
-----------------------------------------------------------------------------------------------
import junit.frameWork.*
public class TestSimple extents TestCase {
public TestSimple(String name){
super()
}
//테스트할 메소드
public static Test suite(){
TestSuite suite = new TestSuite();
//suite 에 테스트 메소드를 추가한다.
suite.addTestSuite(TestClassOne.class);
suite.addTest(TestClassTwo.suite());
return suite;
}
}
-----------------------------------------------------------------------------------------------
import junit.frameWork.*
public class TestClassOne extents TestCase {
public TestClassOne (String name){
super()
}
public void testAddition(){
assertEquals(4,2+2);
}
public void testSubtraction(){
assertEquals(0,2-2);
}
}
-----------------------------------------------------------------------------------------------
import junit.frameWork.*
public class TestClassTwo extents TestCase {
public TestClassTwo(String name){
super()
}
public void testAddition(){
assertEquals(4,2+2);
}
public void testSubtraction(){
assertEquals(0,2-2);
}
public static Test suite(){
TestSuite suite = new TestSuite();
//suite 에 테스트 메소드를 추가한다.
suite.add(new TestSimple ("testAddition"));
suite.add(new TestSimple ("testSubtraction"));
return suite;
}
}
-----------------------------------------------------------------------------------------------
물론 이런 객체를 생성하고 실행 시키는 main 메소드를 구현해서 테스트 해야한다. 혹시해서...
3.5 Junit의 테스트 환경 세팅 및 해제 - oneTimeSetUp() oneTimeTearDown(), setUp() tearDown()
각각의 테스트는 독립적으로 실행되어야 한다.
그래야만 임의의 테스트를 임의의 시간에 임의의 순서로 실행해도 문제가 없다.
Junit 에서는 테스트 들 사이에 테스트 환경 일부를 리셋하거나 테스트 이후의 환경을 정리할 있도록 다음과 같은 메소드를
지원한다.
oneTimeSetUp() oneTimeTearDown(), setUp() tearDown()
각 메소드는 다음과 같은 라이프 사이클에 따라 실행된다.
oneTimeSetUp()
setUp()
테스트 메소드()
tearDown()
setUp()
테스트 메소드()
tearDown()
setUp()
테스트 메소드()
tearDown()
oneTimeTearDown()
oneTimeSetUp() oneTimeTearDown() 는 suite 를 실행할 때와 마지막에 각각 한번씩만 실행되고
setUp() tearDown() 는 매 테스트 메소드들 마다 실행된다.
-----------------------------------------------------------------------------------------------
import junit.frameWork.*
public class TestClassOne extents TestCase {
public TestClassOne (String name){
super()
}
protected void setUp(){
//
}
protected void tearDown(){
//
}
public void testAddition(){
assertEquals(4,2+2);
}
public void testSubtraction(){
assertEquals(0,2-2);
}
}
-----------------------------------------------------------------------------------------------
이렇게 실행하면 setUp() testAddition() tearDown() setUp() testSubtraction() tearDown()
순서로 실행된다.
-----------------------------------------------------------------------------------------------
import junit.frameWork.*
public class TestClassOne extents TestCase {
public TestClassOne (String name){
super()
}
public void testAddition(){
assertEquals(4,2+2);
}
public void testSubtraction(){
assertEquals(0,2-2);
}
public static Test suite(){
TestSuite suite = new TestSuite();
//suite 에 테스트 메소드를 추가한다.
suite.add(new TestSimple ("testAddition"));
suite.add(new TestSimple ("testSubtraction"));
// 세팅값을 적용시킨다.
TestSetup wapper = new TestSetup(suite){
protected void setUp(){
oneTimeSetUp();
}
protected void tearDown(){
oneTimeTearDown();
}
}
return wapper ;
}
public static void oneTimeSetUp(){
//한번만 실행되는 초기화 코드
}
public static void oneTimeTearDown(){
//한번만 실행되는 정리 코드
}
}
-----------------------------------------------------------------------------------------------
이와 같은 경우에는
oneTimeSetUp()
oneTimeSetUp() testAddition() oneTimeTearDown()
oneTimeSetUp() testSubtraction() oneTimeTearDown()
oneTimeTearDown()
와 같을 것이다...
만약 여기서 protected void setUp() protected void tearDown() 메소드를 추가하고
testAddition() 와 testSubtraction() 를 suite 를 적용하지 않고 실행하면
setUp() testAddition() tearDown() setUp() testSubtraction() tearDown() 순서로 실행된다.
결국 테스트별 setUp 과 suite 별 setUp이 별도로 사용된다는 것을 알수 있다.
'컴퓨터공학 기초 > Java' 카테고리의 다른 글
단위테스트 JUNIT (3) (0) | 2012.03.09 |
---|---|
단위테스트 JUNIT (2) (1) | 2012.03.08 |
Easier click Listener, OnClick의 간단한 코드작성 방법 (0) | 2012.02.14 |
[Android] 버튼 이벤트 처리 (1) | 2012.02.14 |
[Android] SharedPreferences Class (0) | 2012.02.14 |