Whiteship's Note


[스프링 3.0 테스트 확장] 애노테이션 설정 기반 테스트 러너 만들기 2

모하니?/Coding : 2009.12.15 17:35


가장 먼저 떠올랐던 기본적인 시나리오는 다음과 같습니다.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationContextLoader.class)
public class SpringAnnotationConfigTest {

    @Autowired ApplicationContext ac;

    @Test
    public void di(){
        assertNotNull(ac);
        String name = ac.getBean("name", String.class);
        assertNotNull(name);
    }

}

이런 테스트가 있고, @ContextConfigruation에 아무런 locations를 지정하지 않았을 때는 테스트 클래스 이름 + AppConfig.java 파일을 찾아서 해당 클래스를 애노테이션 설정 클래스로 인식하는 겁니다.

@Configuration
public class SpringAnnotationConfigTestAppConfig {

    @Bean
    public String name(){
        return "keesun";
    }

}

즉 위와같은 애노테이션 설정 클래스를 기본 설정으로 인식하는거죠. 물론 AppConfig라는 이름을 다른 이름으로 변경할 수 있도록 확장성을 고려해야겠습니다.

그 다음 시나리오는 조금 복잡한데, @ContextConfiguration에 AppConfig 같은 @Configuration을 사용한 자바 설정 파일과 springsprout.org.config 같은 패키지 명을 설정할 수 있게 하는 겁니다.

@ContextConfiguration(locations = {"AppConfig.java", "classpath:../"})

@ContextConfiguration(locations = {"classpath:./AppConfig.java", "../"})

.java로 끝나는 location 정보는 AnnotationConfigApplicationContext의 register를 이용하며, .java로 끝나지 않는 location 정보는 패키지로 인식하여 AnnotationConfigApplicationContext의 scan을 이용해주는 겁니다. 물론, 각각의 resource 정보는 스프링의 Resource prefix인 classpath:, file, url:을 이용할 수 있어야겠습니다.

이제 구현 ㄱㄱㅆ

top


WebTUnit 사용 시나리오 2. 웹 테스트 + 테스트 메서드 단위 데이터 관리

모하니?/Coding : 2009.05.15 12:50


이번에는 이전 시나리오와 비슷하지만, 테스트 데이터를 클래스 단위가 아니라 메서드 단위 즉, JUnit에서 테스트 단위로 관리하는 방법입니다. 아직은 미완성이라고 볼 수 있는데, 지금 상태에서도 아래와 같이 코딩을 한다면, 이 시나리오가 가능합니다.

@RunWith(WebTestRunner.class)
@WarConfiguration("springsprout")
//@DataConfiguration(fileName="testData.xml")
public class SampleWebTest {

    @WebTest
    public void sinario1(){
        DataManager dm = new DefaultDataManager("integration/sample/testData1.xml", DataType.XML);
        dm.insertTestData();
        System.out.println("test1");
    }

    @WebTest
    public void sinario2(){
        DataManager dm = new DefaultDataManager("integration/sample/testData2.xml", DataType.XML);
        dm.insertTestData();
        System.out.println("test2");
    }

}

@DataConfiguration을 클래스에서 제거하면 되고, 소스코드에서 직접 DataManager API를 사용하여, 테스트 데이터를 넣을 수 있습니다. 위 예제에서는 두 개의 테스트에서 각각 다른 테스트 데이터를 넣고 있습니다.


테스트 데이터를 매번 지우고 싶다면, deleteTestData() 메서드를 이용해도 되지만, insertTestData가 내부적으로 DBUnit의 CLEAN_INSERT를 이용하기 때문에 그럴 필요는 없습니다.

이 코드는 차후에 JUnit 4.7의 인터셉터 기능을 이용해서 개선할 예정입니다. 지금은 스냅샷 정도록 생각해주세요
top


웹 테스트 프레임워크(WebTUnit) 사용 시나리오 1. 웹 테스트 + 테스트 클래스 단위 데이터 관리

모하니?/Coding : 2009.05.15 11:36


해당 테스트 클래스를 웹 테스트 하고, 그 안에 있는 모든 테스트들이 공통의 데이터를 이용할 때 사용할 수 있습니다. 단, 주의할 것은 테스트들 사이에 순서가 없기 때문에(JUnit과 동일) 테스트 데이터를 잘못 조작하면 테스트끼리 의존성 생겨 실패할 수 있습니다. 테스트 마다 각자의 테스트 데이터를 사용하는 시나리오는 다음에 살펴보겠습니다. 이 시나리오는 테스트 데이터를 조작하지는 않고 주로 참조 용으로 테스트 하는 경우에 적당합니다.

@RunWith(WebTestRunner.class)
@WarConfiguration("springsprout")
@DataConfiguration(fileName="integration/sample/testData.xml")
public class SampleWebTest {

    @Before
    public void setUp(){
        System.out.println("===================================");
        System.out.println("===================================");
    }

    @WebTest
    public void test1(){
        System.out.println("test1");
    }

    @WebTest
    public void test2(){
        System.out.println("test2");
        fail("for test");
    }

    @After
    public void tearDown(){
        System.out.println("***********************************");
        System.out.println("***********************************");
    }

    @Test
    public void noTest(){
        System.out.println("this will not be print");
    }

}

이렇게 했을 경우
1. sprignsprout라는 이름의 WAR 파일을 생성하고,
2. 배포하고,
3. integration/sample/testData.xml에 있는 데이터를 DB에 넣고
4. 테스트를 쫙 실행(순서 무작위, JUnit 동작 방식을 따름), 각각의 테스트는 @WebTest를 붙여줌. @Test는 동작하지 않습니다. @Before, @After, @BeforeClass, @AfterClass, @Ignore 모두 적용 됨. 딱 하나. @Test 대신 @WebTest를 사용하면 됨. @Test를 사용해도 되지만, 테스트 구분을 위해.. 차후에 WebTest관련 기능을 추가할 때 유리할 듯..
5. 테스트가 끝나면(중간에 몇 개가 실패하더라도), 테스트 데이터를 삭제하고,
6. WAR를 unploy합니다.

물론 세부적 예외가 언제 발생하느냐에 따라 그 처리가 조금씩 달라집니다. 지금도 계속해서 이부분을 작업하고 있으니 자세한 설명은 나중에~


top


주소록 화면 완성



사용자 삽입 이미지

Gmail을 따라 그리다가 개발이 한도 끝도 없이 길어질까봐 일단 화면을 좀 더 간추리고 단순하게 만들었습니다. 한 화면에서 모든 멤버 보기와 새로운 멤버 추가, 그리고 삭제가 가능한 화면입니다.

이전에 만들어둔 새로운 멤버 추가 화면은 멤버의 정보를 수정하는 화면으로 살짝 바꿨습니다.
사용자 삽입 이미지

화면을 보니 대강 프로그램이 어떻게 진행되어야 할지 선명하게 눈에 들어옵니다.

삭제 시나리오
맨 위에 있는 화면이 제일 처음 이 프로그램의 사용자가 보게 될 화면입니다. 그곳에서 삭제 버튼을 누르면 "정말로 삭제 하시겠습니까?" 라고 물어보는 팝업창(이건 어떻게 만들지;;)이 뜨며 거기서 확인을 클릭하면 해당하는 주소가 지워지고 다시 첫화면을 뿌려줍니다.

새로운 멤버 추가 시나리오
첫 화면의 빈 칸들에 적당한 문자들을 입력한 후 add버튼을 클릭합니다. 이 때 입력된 값들이 적당한 값들인지 확인 하고 email이 중복 됐거나 얼토당토 않은 문자들이 입력 됐을 때는 해당하는 메시지를 출력하고 적당한 값들이 입력 됐다면 저장이 되었음을 알려주는 팝업창을 띄워주고 다시 첫 화면을 뿌려줍니다.

수정하기 시나리오
첫 화면의 오른쪽에 있는 modify 버튼을 클릭하면 두 번째 화면(수정 화면)으로 넘어가고 그 곳에는 첫 번째 화면에서 수정을 원했던 사용자의 정보들이 input box안에 적혀 있습니다.(이건 또 어떻게 하지;;) 그리고 수정할 부분의 input box에 원하는 문자열로 수정한 뒤 Commit 버튼을 클릭하면 "새로운 멤버 추가 시나리오"에서 거쳤던 검증을 거친 뒤에 첫 번째 화면을 다시 뿌려줍니다.

'Spring > 주소록 만들기' 카테고리의 다른 글

Web Application Context 작성  (3) 2006.12.25
Spring MVC 구동을 위한 web.xml 작성  (0) 2006.12.25
이클립스에서 웹 프로젝트 생성하기  (0) 2006.12.25
Spring MVC 공부 중  (10) 2006.12.23
CSS 공부 중  (2) 2006.12.21
주소록 화면 완성  (3) 2006.12.19
중간점검  (0) 2006.12.17
HTML 공부 중 2탄  (2) 2006.12.14
Strict HTML 4.01 지침서  (6) 2006.12.14
HTML 공부 중  (2) 2006.12.13
페이징 기능 구현하기(TDD, Easymock, iBATIS, MySQL)  (2) 2006.12.11
top