在 測試 JSP 中, 你對add.jsp獨立進行測試,假設現在整個應用程式已部署,你要針對add.jsp在實際與應用程式其它元件結合後,是否功能正常,你也許會打開瀏覽 器連接add.jsp,然後按下表單按鈕,看看是否回到add.jsp並有錯誤訊息,你也許輸入表單中其中一個欄位,看看回到add.jsp後,該表單欄 位值是否回填,你也許正確填寫每個欄位,發送看看是否新增資料成功。
由於你是測試實際應用程式部署之後,功能是否正常,你是在執行功能測試(Functional test),且由於你是針對應用程式的介面進行測試,而非元件實際的撰寫內容,所以你是在執行黑箱測試(Block box test)。
你不用親自打開瀏覽器,一一手動進行測試,你可以使用 HtmlUnit,它可以用來模擬瀏覽器,某些程度上,你可以將HtmlUnit看作是一個沒有畫面的瀏覽器,你可以使用程式撰寫瀏覽器上的操作過程,接下來就可以自動執行操作。例如:
package test.cc.openhome;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.After;
import org.junit.Test;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
public class AddJSPTest {
private WebClient webClient;
private HtmlPage page;
@Before
public void setUp() throws Exception {
// WebClient 代表一個瀏覽器
webClient = new WebClient();
// 指定 URL 取得 HTML 結果
page = webClient.getPage(
"http://localhost:8080/BookmarkOnline/add.jsp");
}
@After
public void tearDown() throws Exception {
// 關閉所有瀏覽視窗
webClient.closeAllWindows();
}
@Test
public void testNoError() throws Exception {
// 測試初次造訪頁面
// 以標準 DOM API 取得頁面元素進行斷言
assertEquals(0, page.getElementsByTagName("h1").size());
}
@Test
public void testError() throws Exception {
// 取得表單元素
HtmlForm form = page.getForms().get(0);
// 取得發送按鈕
HtmlSubmitInput button = form.getInputByValue("送出");
// 發送表單,取得回應頁面
HtmlPage page2 = button.click();
// 以標準 DOM API 取得頁面元素進行斷言
assertEquals("新增書籤失敗",
page2.getElementsByTagName("h1")
.item(0).getFirstChild().getNodeValue());
}
@Test
public void testParameters() throws Exception {
// 測試欄位回填功能
String title = "測試";
HtmlForm form = page.getForms().get(0);
// 取得輸入欄位
HtmlTextInput textField = form.getInputByName("title");
// 在欄位填值
textField.setValueAttribute(title);
HtmlSubmitInput button = form.getInputByValue("送出");
HtmlPage page2 = button.click();
assertEquals(title,
page2.getElementsByName("title")
.get(0).getAttribute("value"));
}
@Test
public void testSubmitSuccess() throws Exception {
HtmlForm form = page.getForms().get(0);
form.getInputByName("url").setValueAttribute("http://test");
form.getInputByName("title").setValueAttribute("測試");
form.getSelectByName("category").getOption(1).setSelected(true);
HtmlSubmitInput button = form.getInputByValue("送出");
// 假設發送成功的回應頁面標題為"新增書籤功成功"
HtmlPage page2 = button.click();
assertEquals("新增書籤成功", page2.getTitleText());
}
}
上面的例子說明了幾個模擬瀏覽器操作的方式,你也可以模擬Firefox或Internet Explorer特定版本。例如:
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3);
在撰寫文件的此時,可模擬的瀏覽器有:
- Firefox 2:BrowserVersion.FIREFOX_2(不建議使用)
- Firefox 3:BrowserVersion.FIREFOX_3
- Firefox 3.6:BrowserVersion.FIREFOX_3_6
- Internet Explorer 6:BrowserVersion.INTERNET_EXPLORER_6
- Internet Explorer 7:BrowserVersion.INTERNET_EXPLORER_7
- Internet Explorer 8:BrowserVersion.INTERNET_EXPLORER_8
在Cactus 1.8之後,HtmlUnit可與Cactus結合,只要在Classpath中包括HtmlUnit的相關程式庫,在Cactus的endXXX()方法中,就可以使用com.gargoylesoftware.htmlunit.WebResponse來取代org.apache.cactus.WebResponse(Cactus 1.2後到1.7可以換用 HttpUnit 的com.meterware.httpunit.WebResponse)。
HtmlUnit的使用十分直覺,關於頁面元素的取得,或相關動作的模擬(例如滑鼠點選、鍵盤鍵入等),都可以使用DOM標準API。如果連外需要透過代理伺服器,則可以如下:
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3,
"http://proxyserver", port);
// 設定連接代理伺服器時的名稱、密碼
DefaultCredentialsProvider credentialsProvider =
(DefaultCredentialsProvider) webClient.getCredentialsProvider();
credentialsProvider.addProxyCredentials("username", "password");