Introduction
對於寫過test case 的 programmer 來說,JUnit 應該是不陌生,JUnit 是被大家公認用來執行java測試最好的framework,但是對於像Struts這種以MVC為宗旨的framework,我們又該如何去執行測試呢?StrutsTestCase for JUnit[1] 就是一個用來達成我們目的的solution。從字面上就可以了解,StrutsTestCase其實就是將JUnit延伸到Struts framework可以使用的library。所以,大致上對於測試的方式是大同小異的,不過對於StrutsTestCase[1]來說,還是有一些不一樣之處。
下圖一是官方網站的簡介,此網站對於StrutsTestCase[1]有很詳細的說明。
圖一 官方網站的說明
圖一中的紅圈處就可以下載該library。點選後就會進入SourceForge.net的網站,如下圖二。
圖二 SourceForge.net的下載點
接個點選Download字樣,進入如下圖三的畫面。
圖三 SourceForge.net的下載點(2)
畫面中請下載您所需要的版本,通常是選擇下載最新版本為主,圖中最後一個載點是在檔名後方加上 -src代表是原始碼的版本,若您有需要訂做自己適用的StrutsTestCase,您也可以下載原始碼版本。
下載完的壓縮檔案解開後的資料夾中會包含一個strutstest-x.jar(其中x會依照您所下載的版本不同而有所改變)。若是一般的 Java Application 要使用,請設定 classpath 位置;若是需要在 Web Server 上面的 Web Application 使用,請放置該 Web Application 的 WEB-INF / lib 之下。
Example
首先假設您有一個action如下:
public class LoginAction extends Action {
public ActionForward excute(...) {
String username = ((LoginForm)form).getUsername();
String password = ((LoginForm)form).getPassword();
String role = “user”;
if (username.equals(“adm”) && password.equals(“test”)) {
role = “adm”;
}
request.getSession().setAttribute(“role”,role);
request.getSession().setAttribute(“username”,username);
}
}
上述程式碼中,我們假設您已經有一個LoginForm class。上述的action您在struts-config.xml中設定如下:
<action path=”/login” type=”LoginAction” />
接下來您就可以根據您的action來開發strutstestcases測試,開發strutstestcase步驟如下:
(1) 您必須建立新的class,我們命名為LoginActionTest並且extends MockStrutsTestCase:
public class LoginActionTest extends MockStrutsTestCase {
}
(2) 如果您是在 eclipse 環境下執行測試,請您務必加入以下的程式碼:
public class LoginActionTest extends MockStrutsTestCase {
public void setUp() {
super.setUp();
setContextDirectory(new File(“WebContent”)); //註一
this.setConfigFile(“/WEB-INF/struts-config.xml”);
}
}
註一:其中WebContent要根據您在eclipse中建立的資料夾而定,依照我所設定的資料夾如下圖四,所以我們採用WebContent:
圖四 Eclipse專案的目錄結構
(3) 接著我們就要開始來正式的撰寫我們的test case,所有的test case method都必須以test開頭,例如:testLogin。
public class LoginActionTest extends MockStrutsTestCase {
public void setUp() {
super.setUp();
setContextDirectory(new File(“WebContent”));
this.setConfigFile(“/WEB-INF/struts-config.xml”);
}
public void testLogin() {}
}
(4) 有了test case method,我們就要開始撰寫內容了。首先,我們要先告知strutstestcase我們要測試的路徑,也就是瀏覽器如何存取該action的方法,不過,我們只需要設定在struts-config.xml中的路徑即可,無須增加IP位址,因為MockStrutsTestCase是屬於Mock Test測試(也就是非in-container測試,所謂的container就是由tomcat這類的server來啟動,所以in-container就是會啟動tomcat server來進行測試,Mock Test就是另一種不用啟動tomcat server的離線測試),先前我們已經將LoginAction class在struts-config.xml中設定的路徑為/login,所以我們可以透過MockStrutsTestCase所提供的setRequestPathInfo() method來設定action的存取位置。
public class LoginActionTest extends MockStrutsTestCase {
public void setUp() {
super.setUp();
setContextDirectory(new File(“WebContent”));
this.setConfigFile(“/WEB-INF/struts-config.xml”);
}
public void testLogin() {
super.setRequestPathInfo(“/login”);
}
}
NOTE: 呼叫superclass的methods時,可以使用super關鍵字,本人建議所有呼叫superclass的methods時,都加上super關鍵字,以方便未來觀看程式碼時就可以一目了然,另外,若是呼叫同一個method時,請您也加上this來方便日後的維護。這並沒有硬性的規定,所以的關鍵字都不加上去,程式碼依舊可以執行,這只是習慣性的問題而已。
(5) 再來就是告知該action我們要傳入的資料,此資料就是模擬使用者會傳入哪些資料給action。切記,雖然我們的action是接收一個ActionForm物件,不過在MockStrutsTestCase中是用類似URL GET method(../login.do?username=adm&…)的方式給予。我們並不能給予ActionForm物件。所以我們要呼叫MockStrutsTestCase的addRequestParameter() method,並將我們要給予的參數名稱與參數值。
public class LoginActionTest extends MockStrutsTestCase {
public void setUp() {
super.setUp();
setContextDirectory(new File(“WebContent”));
this.setConfigFile(“/WEB-INF/struts-config.xml”);
}
public void testLogin() {
super.setRequestPathInfo(“/login”);
super.addRequestParameter(“username”,”adm”);
super.addRequestParameter(“password”,”test”);
}
}
(6) 設定好路徑與參數後,我們就要告知MockStrutsTestCase,該測試可以啟動了,所以我們就呼叫他的actionPerform() method來正式的執行該action。
public class LoginActionTest extends MockStrutsTestCase {
public void setUp() {
super.setUp();
setContextDirectory(new File(“WebContent”));
this.setConfigFile(“/WEB-INF/struts-config.xml”);
}
public void testLogin() {
super.setRequestPathInfo(“/login”);
super.addRequestParameter(“username”,”adm”);
super.addRequestParameter(“password”,”test”);
super.actionPerform();
}
}
(7) Action執行完後,我們就可以針對action執行後的結果作測試,因為我們的action是將結果儲存在session中,所以我們就要從session中取出結果,並且呼叫JUnit的測試method來檢驗結果。
public class LoginActionTest extends MockStrutsTestCase {
public void setUp() {
super.setUp();
setContextDirectory(new File(“WebContent”));
this.setConfigFile(“/WEB-INF/struts-config.xml”);
}
public void testLogin() {
super.setRequestPathInfo(“/login”);
super.addRequestParameter(“username”,”adm”);
super.addRequestParameter(“password”,”test”);
super.actionPerform();
String role = super.getSession().getAttribute(“role”);
super.assertEquals(role,”adm”);
}
}
NOTE:若action是將結果儲存在request中,您就要改呼叫super.getRequest() method來進行測試。
References
[1] StrutsTestCase官方網站 http://strutstestcase.sourceforge.net/