자동화된 테스팅은 같은 테스팅 단계를 반복할 때의 시간과 노력을 줄여준다. 이 글에서 jWebUnit을 소개한다. 웹 애플리케이션용 테스트 케이스를 개발할 때 사용할 수 있는 자바 클래스이다. jWebUnit은 오픈 소스 프로젝트로서 BSD 라이센스 하에서 무료로 사용할 수 있다. jWebUnit 라이브러리 다운로드, Eclipse 플랫폼을 설정하여 jWebUnit 테스트 케이스 개발하기, 샘플 테스트 케이스 구현하기 등을 설명하겠다.
jWebUnit은 HttpUnit 기반으로서 웹 애플리케이션의 자동 테스팅을 위한 자바 라이브러리이고 JUnit 단위 테스팅 프레임웍이다.(참고자료) jWebUnit은 웹 애플리케이션 검색에 쓰이는 고급 API를 제공하고 링크를 통한 네비게이션의 정확성, 형식 엔트리와 제출, 테이블 내용, 기타 비즈니스 웹 애플리케이션을 확인하는 주석 세트도 포함되어 있다. jWebUnit은 JAR 파일 형태로 되어 있어 대부분의 IDE에 쉽게 플러그인 되며 다른 필수 라이브러리도 포함하고 있다.
웹 애플리케이션용 자동화 테스팅이란 웹 브라우저를 우회하여 프로그램을 통해 웹 사이트로 작업하는 것이다. 우선, JWebUnit의 구현 블록들 중 하나인 HttpUnit이 이 작업을 어떻게 간소화 시키는지를 설명하겠다. HttpUnit은 프레임, 자바 스크립트, 페이지 리다이렉션 쿠키 등을 모방할 수 있다. JUnit과 사용되면, HttpUnit은 웹 사이트의 기능을 빠르게 확인 할 수 있다.
Listing 1은 HttpUnit으로 작성된 테스트 케이스 예제이다. HttpUnit 홈 페이지상의 "Cookbook" 링크로 클릭을 시도한다.:
Listing 1. HttpUnit 홈 페이지상의 "Cookbook" 링크로 클릭을 시도하는 HttpUnit 코드
1 public class HttpUnitTest {
2 public static void main(String[] args) {
3 try {
4 WebConversation wc = new WebConversation();
5 WebRequest request =
new GetMethodWebRequest("http://httpunit.sourceforge.net/index.html");
6 wc.setProxyServer( "your.proxy.com", 80 );
7 WebResponse response = wc.getResponse(request);
8 WebLink httpunitLink =
response.getFirstMatchingLink(WebLink.MATCH_CONTAINED_TEXT,"Cookbook");
9 response = httpunitLink.click();
10 System.out.println("Test successful !!");
11 } catch (Exception e) {
12 System.err.println("Exception: " + e);
13 }
14 }
15 }
|
Listing 1의 코드는 your.proxy.com(line 6)을 사용하여 인터넷에 연결한다. 인터넷에 직접 연결되면 이 문장을 뺄 수 있다. Line 8의 문장은 Cookbook 텍스트를 포함하고 있는 웹 링크에 대한 페이지를 검색한다. Line 9의 문장은 그 링크에 대해 클릭한다. 링크가 검색되면 사용자는 Test Successful !! 메시지를 볼 수 있다.
Listing 2의 테스트 케이스는 jWebUnit API를 사용하여 Listing 1과 같은 태스크를 수행한다.:
Listing 2. HttpUnit 홈페이지에서 Cookbook 링크를 클릭하는 jWebUnit 코드
1 public class JWebUnitTest extends WebTestCase{
2 public static void main(String[] args){
3 junit.textui.TestRunner.run(new TestSuite(JWebUnitTest.class));
4 }
5 public void setUp(){
6 getTestContext().setBaseUrl("http://httpunit.sourceforge.net");
7 getTestContext().setProxyName("webproxy.watson.ibm.com");
8 getTestContext().setProxyPort(8080);
9 }
10 public void testSearch(){
11 beginAt("/index.html");
12 clickLinkWithText("Cookbook");
13 }
14 }
|
Listing 2의 JUnit 스팩 코드를 무시한다면 테스트 케이스가 깔끔하고 정확하다는 것을 알게 될 것이다. 주목해야 할 부분은 라인 6, 11, 12이다. 라인 6에서, 기본 URL은 HttpUnit 홈 페이지로 설정되어 있다. 라인 11은 /index.html에 있는 사이트로 연결된다. 라인 12는 Cookbook 텍스트가 있는 페이지로의 링크를 클릭한다. 클릭이 작동하면 JUnit은 성공했음을 알린다; 그렇지 않을 경우 예외를 보고한다.
모든 jWebUnit 테스트 케이스의 중심에는 net.sourceforge.jwebunit.WebTestCase 클래스가 있다. 이것은 테스트 케이스를 나타낸다. 모든 테스트 케이스는 이 클래스로부터 확장되어야 한다. (net.sourceforge.jwebunit.WebTestCase 클래스 자체는 junit.framework.TestCase에서 확장된다. 이는 JUnit의 테스트 케이스를 나타낸다.) 표 1은 일반적으로 사용되는 이 클래스의 일부를 설명하고 있다.:
표 1. net.sourceforge.jwebunit.WebTestCase 클래스의 중요 메소드
| 메소드 | 설명 |
| public TestContext getTestContext() | 테스트 케이스의 콘텍스트를 받는다. 이것을 사용하여 로케일, 기본 URL, 쿠키 같은 아이템에 접근할 수 있다. |
| public void beginAt(String relativeURL) | 기본 URL과 관련 있는 URL에서 대화를 시작한다. |
| public void setWorkingForm(String nameOrId) | 지정된 형식으로 인터랙션을 시작한다. 현재 페이지가 단 하나의 폼을 갖고 있다면 이 메소드를 호출 할 필요가 없다. |
| protected void submit() | 형식의 Submit 버튼을 클릭하는 것과 동일한 형식을 제출한다. |
| public void gotoFrame(String frameName) | 네임드 프레임을 활성화한다. |
또 다른 중요한 클래스는 net.sourceforge.jwebunit.TestContext이다. 이는 테스트용 콘텍스트를 구현한다. 이 클래스를 사용하여 쿠키, 세션, 권한 등의 정보로 작업한다. 표 2는 이 클래스의 중요한 메소드들이다.:
표 2. net.sourceforge.jwebunit.TestContext 클래스의 중요 메소드
| 메소드 | 설명 |
| public void addCookie(String name, String value) | 쿠키를 테스트 콘텍스트에 추가한다. 추가된 콘텍스트는 HttpUnitDialog가 시작되면 WebConversation상에서 설정된다. |
| public void setResourceBundleName(String name) | 리소스 번들이 테스트 콘텍스트용으로 사용될 수 있도록 설정한다. WebTester의 키에 의한 예상 값을 검색하는데 사용된다. |
| public void setProxyName(String proxyName) | 테스트 콘텍스트용 프록시 서버 이름을 정한다. |
| public void setBaseUrl(String url) | 텍스트 콘텍스트용 기본 URL을 설정한다. |
Eclipse에서 jWebUnit 다운로드 및 설정하기
jWebUnit은 순수 자바 코드에서 구현되기 때문에, JAR 파일로서 사용할 수 있다.(참고자료) 다운로드 한 후 다음 단계에 따라 Eclipse 플랫폼상에 jWebUnit 라이브러리를 설정한다.:
- 다운로드 파일(jwebunit-1.2.zip)의 압축을 풀어 임시 디렉토리에 저장한다.(C:\temp)
- Eclipse의 jWebUnit에 새로운 자바 프로젝트를 만든다.
- Package Explorer 뷰에서 jWebUnit 프로젝트를 오른쪽 클릭하여 Properties를 선택한다.
- Java Build Path를 클릭한다. 라이브러리 탭에서, Add External JARs를 클릭한다.
- C:\temp\jwebunit-1.2\lib 디렉토리를 검색하고 이 디렉토리의 모든 JAR를 선택한다.
- OK를 클릭한다.
jWebUnit 프로젝트 하의 Eclipse에서 jWebUnit 테스트 케이스 개발을 시작한다.
jWebUnit API가 어떻게 실행되는지 볼 차례이다. 샘플 애플리케이션을 통해 jWebUnit의 진정한 힘을 이해할 수 있도록 하겠다. 이 애플리케이션은 테스트 케이스로서 구글 검색 페이지를 열고 HttpUnit 텍스트를 검색한다. 애플리케이션이 다음 시나리오를 테스트하도록 해야 한다.:
- 구글 홈 페이지(http://www.google.com)를 오픈한다.
- 페이지가
q라는 이름의 형식 엘리먼트를 포함하고 있다는 것을 확인한다. (구글 홈페이지에서q라는 이름이 붙은 텍스트 박스는 사용자 쿼리를 인풋으로 받아들이는 것이다.) 애플리케이션은 이 엘리먼트를 사용하여 검색 기준을 입력한다. HttpUnit Home스트링을 검색 텍스트 박스에 입력하고 형식을 제출한다.- 결과 페이지를 보고 HttpUnit Home 텍스트를 포함하고 있는 링크를 포함하고 있다는 것을 확인한다.
- HttpUnit Home 텍스트가 있는 링크를 클릭한다.
테스트 시나리오가 준비되면 jWebUnit을 사용하여 요구 사항들을 구현하는 자바 애플리케이션을 작성할 수 있다.
첫 번째 단계는 WebTestCase에서 확장된 클래스를 선언하는 것이다. (Listing 3):
Listing 3. testcase 클래스 선언하기
public class GoogleTest extends WebTestCase {
static String searchLink = "";
}
|
앞서 언급했듯이, jWebUnit은 모든 테스트 케이스가 WebTestCase에서 확장되어야 한다. searchLink는 전달된 인자를 저장한다. 이 값을 명령행 매개변수로서 테스트 케이스로 전달한다.
다음 단계는 엔트리 포인트 main() 메소드를 선언하는 것이다. (Listing 4):
Listing 4.
main() 메소드
public static void main(String[] args) {
searchLink = args[0];
junit.textui.TestRunner.run(new TestSuite(GoogleTest.class));
}
|
main()메소드는 junit.textui.TestRunner.run()을 호출하여 JTest 테스트 케이스를 실행한다. GoogleTest 테스트 케이스를 실행해야 하기 때문에 매개변수로서 run() 메소드로 전달했던 테스트 수트는 인자로서 GoogleTest.class를 받는다.
JTest는 setUp() 메소드를 호출한 다음 기본 URL과 프록시를 설정한다. (Listing 5):
Listing 5. Setup
public void setUp() {
getTestContext().setBaseUrl("http://www.google.com");
getTestContext().setProxyName("proxy.host.com");
getTestContext().setProxyPort(80);
}
|
Listing 5는 기본 URL을 구글(http://www.google.com)로 설정한다. 이것은 테스트 케이스가 이 URL과 비슷한 것을 시작할 것을 의미한다. 다음 두 개의 문장은 프록시 호스트와 프록시 포트를 설정하여 인터넷에 연결되도록 한다. 직접 인터넷과 연결된다면 프록시 설정 문장을 삭제할 수 있다.
이제 사이트 검색을 시작하고 검색 기준을 입력한다. Listing 6은 웹 페이지에 액세스하고 모든 시나리오를 테스트 할 코드이다.:
Listing 6. 시나리오 테스트
public void testSearch() {
beginAt("/");
assertFormElementPresent("q");
setFormElement("q", "HttpUnit");
submit("btnG");
assertLinkPresentWithText(searchLink);
clickLinkWithText(searchLink);
}
|
Listing 6의 코드는 기본 URL과 연결되고 /에서 검색을 시작한다. 그런 다음, 이 페이지가 q라는 이름의 형식 엘리먼트를 포함하고 있다는 것을 확인한다. 다음 문장은 텍스트 박스를 HttpUnit 값을 가진 q 라는 이름으로 설정한다. 다음 문장은 btnG라는 형식-제출 버튼을 제출한다.(구글 홈 페이지에서, btnG라는 버튼은 Google Search로 라벨링 된 버튼이다.) 형식은 제출되고 다음 페이지는 검색 결과를 Listing한다. 결과 페이지에서 코드는 HttpUnit Home 텍스트로 링크 된 것이 있는지를 확인한다. 링크가 존재하지 않으면 테스트는 실패한 것이다.(AssertionFailedError) 링크가 존재하면 테스트는 그것을 클릭한다.
이제 샘플 애플리케이션을 작동시킨다.:
- 샘플 애플리케이션, j-webunitsample.jar를 다운로드(Download) 한다.
- j-webunitsample.jar의 압축을 푼다. C:\temp에 압축을 풀면 소스와 클래스 파일들은 C:\temp\com\jweb\test에 setclasspth.bat는 C:\temp에 저장된다.
- setclasspath.bat을 편집한다.:
JAR_BASE를 설정하여 필요한 JAR를 포함하고 있는 디렉토리를 가리키게 한다. 예를 들어, jwebunit-1.2.zip 파일은 C:\temp에JAR_BASE는 C:\temp\jwebunit-1.2\lib으로 한다. - 명령어 프롬프트를 열고 디렉토리를 C:\temp로 변경한다.
setclasspath.bat를 실행한다. 테스트 케이스 실행에 필요한CLASSPATH를 설정한다.java com.jweb.test.GoogleTest "HttpUnit Home"명령어로 애플리케이션을 실행한다.
테스트 케이스를 실행한 후에 테스트-케이스 리포트가 명령어 프롬프트에 프린트 된다. 테스트가 실패하면 리포트는 다음과 같다. (Listing 7):
Listing 7. 실패 리포트
C:\temp>java com.jweb.test.GoogleTest "HttpUnit Hwee"
.F
Time: 5.338
There was 1 failure:
1) testSearch(com.jweb.test.GoogleTest)junit.framework.AssertionFailedError: Link
with text [HttpUnit Hwee] not found in response.
at net.sourceforge.jwebunit.WebTester.assertLinkPresentWithText(WebTester.java:618)
at net.sourceforge.jwebunit.WebTestCase.assertLinkPresentWithText(WebTestCase.java:244)
at com.jweb.test.GoogleTest.testSearch(GoogleTest.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at com.jweb.test.GoogleTest.main(GoogleTest.java:19)
FAILURES!!!
Tests run: 1, Failures: 1, Errors: 0
|
Listing 7에서 보듯, 테스트 케이스는 매개변수로서 HttpUnit Hwee로 실행된다. 이 테스트 케이스는 결과 페이지에 텍스트로의 링크가 없기 때문에 실패한다. (junit.framework.AssertionFailedError)
Listing 8은 매개변수로서 HttpUnit Home을 사용하여 실행된다. 테스트 케이스는 텍스트가 있는 링크를 찾는다. 성공이다.:
Listing 8. 성공적인 테스트 아웃풋
C:\temp>java com.jweb.test.GoogleTest "HttpUnit Home" . Time: 6.991 OK (1 test) |
이 글에서 jWebUnit 프레임웍을 소개했다. 소란스럽지는 않지만 가장 중요한 클래스를 설명했고 이를 사용하여 정확한 테스트 케이스를 만드는 방법을 설명했다. jWebUnit은 이 글에서 소개한 것 외에도 더 많은 기능을 갖고있다. 테스트가 웹 페이지에 나와있는 링크의 수를 셀 수 있도록 한다. 스트링, 테이블, 형식 인풋 엘리먼트가 페이지에 있는지의 여부도 확인할 수 있다. 쿠키가 존재하면 쿠키를 사용할 수 있고 쿠키를 제거할 수도 있다. 테스트는 특정 텍스트로의 링크를 클릭할 수 있다. 웹 애플리케이션을 위한 빠르고 효율적인 테스트 케이스를 구현하려면 jWebUnit이 제격이다.
| 설명 | 이름 | 크기 | 다운로드 방식 |
|---|---|---|---|
| Sample code | j-webunitsample.jar | 2 KB | FTP |
- Code를 클릭하여 Download한다.
- jWebUnit library.
- jWebUnit
- HttpUnit
- " HttpUnit: A Civilized Way to Test Web Applications in WebSphere Studio" (developerWorks, March 2003)
- JUnit
- "StrutsTestCase simplifies the development process" (developerWorks, January 2005)
- developerWorks blogs.
- Java technology zone.
- Developer Bookstore, Java-related titles.