作者:葉楓(http://blog.matrix.org.cn/page/葉楓)
原文:[http://www.matrix.org.cn/resource/article/44/44008_StrutsTestCase.html]http://www.matrix.org.cn/resource/article/44/44008_StrutsTestCase.html[/url]
關(guān)鍵字:Struts StrutsTestCase
一、Struts測(cè)試概述
一個(gè)具有良好系統(tǒng)架構(gòu)的J2EE應(yīng)用程序至少有三層組成,即表現(xiàn)層,商業(yè)層和系統(tǒng)集成層(包括數(shù)據(jù)存取以及和其他系統(tǒng)集成),目前,Struts是應(yīng)用比較廣泛,實(shí)現(xiàn)MVC2模式應(yīng)用于表現(xiàn)層的一種技術(shù). 在這里面,Struts Action主要用來完成一些簡(jiǎn)單的數(shù)據(jù)校驗(yàn),轉(zhuǎn)換,以及流程轉(zhuǎn)發(fā)控制(注意:這里流程不是業(yè)務(wù)規(guī)則). 因此在對(duì)整個(gè)應(yīng)用程序進(jìn)行測(cè)試時(shí),我們同時(shí)也要測(cè)試Struts Action.
但是,測(cè)試Struts Action相對(duì)測(cè)試簡(jiǎn)單的JavaBean是比較困難,因?yàn)镾truts是運(yùn)行在Web服務(wù)器中, 因此要測(cè)試Struts Action就必須發(fā)布應(yīng)用程序然后才能測(cè)試. 我們想象一下,對(duì)于一個(gè)擁有上千個(gè)JSP page和數(shù)百甚至數(shù)千Java Classes的大規(guī)模應(yīng)用程序,要把他們發(fā)布到諸如Weblogic之類的應(yīng)用服務(wù)器再測(cè)試,需要多少的時(shí)間和硬件資源? 所以這種模式的測(cè)試是非常費(fèi)時(shí)費(fèi)力的.
所以,如果有一種辦法能夠不用發(fā)布應(yīng)用程序,不需要Web服務(wù)器就能象測(cè)試普通Java Class一樣測(cè)試Struts Action,那就能極大地加強(qiáng)Struts的可測(cè)試性能,使應(yīng)用程序測(cè)試更為容易,簡(jiǎn)單快速. 現(xiàn)在這個(gè)工具來了,這就是StrutsTestCase.
二、StrutsTestCase 概述
StrutsTestCase 是一個(gè)功能強(qiáng)大且容易使用的Struts Action開源測(cè)試工具,它本身就是在大名鼎鼎的JUnit基礎(chǔ)上發(fā)展起來的。因此通過和JUnit結(jié)合使用能極大加強(qiáng)應(yīng)用程序的測(cè)試并加快應(yīng)用程序的開發(fā).
StrutsTestCase提供了兩者測(cè)試方式,模仿方式和容器測(cè)試方式. 所謂模仿方式就是有StrutsTestCase本身來模擬Web服務(wù)器. 而容器測(cè)試方式則需要Web服務(wù)器. 本文要討論的是前者,原因很簡(jiǎn)單,不需要Web服務(wù)器就能象測(cè)試普通的Java Class一樣測(cè)試Struts Action.
三、準(zhǔn)備StrutsTestCase和Struts Action/ActionForm/Config
StrutsTestCase是一個(gè)開源工具,可以到http://strutstestcase.sourceforge.net下載. 目前最新版本是2.1.3,如果你使用Servlet2.3就下載StrutsTestCase213-2.3.jar,使用Servlet2.4的就下載StrutsTestCase213-2.4.jar.另外StrutsTestCase本身就是從JUnit繼承的,所以你還需要下載JUnit3.8.1.
在本文中,我們用一個(gè)簡(jiǎn)單的例子來做測(cè)試. 假設(shè)我們有一張表Hotline(country varchar2(50),pno varchar2(50)),我們要做的是根據(jù)輸入條件從這張表檢索相應(yīng)的記錄.檢索條件是country.
Value Object:
ActionForm:
Action Class:
Struts Config:
四、初試StrutsTestCase
當(dāng)采用模擬方式時(shí),所有的StrutsTestCase測(cè)試Class都是從MockStrutsTestCase繼承下來的.
下面我們就創(chuàng)建一個(gè)最簡(jiǎn)單的測(cè)試Class.
上面的Class相信用過JUnit的朋友都很熟悉.
好了,一個(gè)簡(jiǎn)單的測(cè)試?yán)泳屯瓿闪?如果你用的是Eclipse就選擇Run-Run...-JUnit-New就可以直接運(yùn)行.不需要發(fā)布你的程序,不需要任何的Web服務(wù)器支持,就可以測(cè)試Struts Action,這就是StrutsTestCase帶來的好處.下面簡(jiǎn)單地介紹一下它是怎么工作的.
在上面的例子中,我們調(diào)用setRequestPathInfo()告訴StrutsTestCase我們要模擬JSP調(diào)用SearchHotline.do這個(gè)Action,并且調(diào)用addRequestParameter()增加了一個(gè)參數(shù)country.最后調(diào)用actionPerform()運(yùn)行.
看到這里,大家發(fā)現(xiàn)一個(gè)問題沒有? 在上面Action的源代碼里我們是通過
也就是ActionForm來取得輸入的參數(shù)值,可我們?cè)趖estSearchHotline()方法里并沒有設(shè)置ActionForm?
那么它是怎么出來的呢? 其實(shí)大家如果熟悉Struts的運(yùn)行流程的話就知道,JSP接受用戶的輸入并發(fā)請(qǐng)求時(shí)都是類似這樣的http://hostname/servletName?param1=value1¶m2=value2. 只是Struts接受到這些參數(shù)后再根據(jù)Struts Config里的Action和ActionForm的映射把他們轉(zhuǎn)為ActionForm后傳給Action的.
在上面的例子,我們只是簡(jiǎn)單地運(yùn)行了Action,那么Action是否正確執(zhí)行以及返回的結(jié)果是不是我們想要的呢?
我們繼續(xù)完善一下testSearchHotline()這個(gè)Method.
public void testSearchHotline() throws Exception{
setRequestPathInfo("/SearchHotline.do");
addRequestParameter("country", "CN");
actionPerform();
verifyNoActionErrors();
verifyForward("hotlineList");
assertNotNull(request.getAttribute("hotlineList"));
List hotlineList = (List) request.getAttribute("hotlineList");
for (Iterator it = hotlineList.iterator();it.hasNext();){
....
}
}
我們?cè)赼ctionPerform()后增加了幾行語(yǔ)句來斷定Struts Action是否正確執(zhí)行.
verifyNoActionErrors() -- 判斷Action里沒有任何的Action;
verifyForward("hotlineList") -- 判斷Action確實(shí)轉(zhuǎn)發(fā)到hotlineList;
assertNotNull(request.getAttribute("hotlineList")) -- 判斷Action確實(shí)返回了hotlineList并且不為空
到這里,我們已經(jīng)基本上討論完了StrutsTestCase的核心部分. 從頭到尾,我們沒有發(fā)布應(yīng)用程序,也不需要Web服務(wù)器,對(duì)我們來講,Struts Action就象普通的Java Class一樣容易調(diào)試測(cè)試.這就是StrutsTestCase給我們帶來的方便.
五、深入StrutsTestCase
除了以上我們用到的幾個(gè)斷定和校驗(yàn)方法外,StrutsTestCase還提供了其他幾個(gè)方法便于我們測(cè)試Struts Action. 下面我一一講述,具體的大家可以參考文檔.
verifyActionErrors/Messages -- 校驗(yàn)ActionActionServlet controller 是否發(fā)送了ActionError或ActionMessage. 參數(shù)為ActionError/Message Key
verifyNoActionErrors/Messages --校驗(yàn)ActionActionServlet controller 沒有發(fā)送ActionError或ActionMessage
VerifyForward -- 校驗(yàn)Action是否正確轉(zhuǎn)發(fā)到指定的ActionForward.
VerifyForwardPath -- 校驗(yàn)Action是否正確轉(zhuǎn)發(fā)到指定的URL
verifyInputForward -- 校驗(yàn)Action是否轉(zhuǎn)發(fā)到Action Mapping里的input屬性
verifyTilesForward/verifyInputTilesForward--和以上類似,應(yīng)用程序使用到tiles時(shí)用的
六、關(guān)于Web.xml和Struts-Config.xml
缺省情況下,StrutsTestCase認(rèn)為你的Web.xml和struts-config.xml的路徑分別是:/WEB-INF/web.xml和/WEB-INF/struts-config.xml
1. 假如你的web.xml/struts-config.xml的路徑是
d:/app/web/WEB-INF/web.xml(struts-config.xml)的話,就需要把d:/app/web加到classpath.
2. 假如你的struts config是strust-config-module.xml,
那么必須調(diào)用setConfigFile()設(shè)置你的struts config文件
七、結(jié)束語(yǔ)
J2EE應(yīng)用程序的測(cè)試在開發(fā)過程中占有相當(dāng)重要的位置,利用StrutsTestCase能極大方便你測(cè)試基于Struts的應(yīng)用程序.
關(guān)于作者:
葉楓:熱愛Java和Oracle. 在軟件開發(fā)有近10年, 目前在國(guó)外一家美國(guó)大公司擔(dān)任SA, 負(fù)責(zé)技術(shù)研究。作者Blog:http://blog.matrix.org.cn/page/葉楓
原文:[http://www.matrix.org.cn/resource/article/44/44008_StrutsTestCase.html]http://www.matrix.org.cn/resource/article/44/44008_StrutsTestCase.html[/url]
關(guān)鍵字:Struts StrutsTestCase
一、Struts測(cè)試概述
一個(gè)具有良好系統(tǒng)架構(gòu)的J2EE應(yīng)用程序至少有三層組成,即表現(xiàn)層,商業(yè)層和系統(tǒng)集成層(包括數(shù)據(jù)存取以及和其他系統(tǒng)集成),目前,Struts是應(yīng)用比較廣泛,實(shí)現(xiàn)MVC2模式應(yīng)用于表現(xiàn)層的一種技術(shù). 在這里面,Struts Action主要用來完成一些簡(jiǎn)單的數(shù)據(jù)校驗(yàn),轉(zhuǎn)換,以及流程轉(zhuǎn)發(fā)控制(注意:這里流程不是業(yè)務(wù)規(guī)則). 因此在對(duì)整個(gè)應(yīng)用程序進(jìn)行測(cè)試時(shí),我們同時(shí)也要測(cè)試Struts Action.
但是,測(cè)試Struts Action相對(duì)測(cè)試簡(jiǎn)單的JavaBean是比較困難,因?yàn)镾truts是運(yùn)行在Web服務(wù)器中, 因此要測(cè)試Struts Action就必須發(fā)布應(yīng)用程序然后才能測(cè)試. 我們想象一下,對(duì)于一個(gè)擁有上千個(gè)JSP page和數(shù)百甚至數(shù)千Java Classes的大規(guī)模應(yīng)用程序,要把他們發(fā)布到諸如Weblogic之類的應(yīng)用服務(wù)器再測(cè)試,需要多少的時(shí)間和硬件資源? 所以這種模式的測(cè)試是非常費(fèi)時(shí)費(fèi)力的.
所以,如果有一種辦法能夠不用發(fā)布應(yīng)用程序,不需要Web服務(wù)器就能象測(cè)試普通Java Class一樣測(cè)試Struts Action,那就能極大地加強(qiáng)Struts的可測(cè)試性能,使應(yīng)用程序測(cè)試更為容易,簡(jiǎn)單快速. 現(xiàn)在這個(gè)工具來了,這就是StrutsTestCase.
二、StrutsTestCase 概述
StrutsTestCase 是一個(gè)功能強(qiáng)大且容易使用的Struts Action開源測(cè)試工具,它本身就是在大名鼎鼎的JUnit基礎(chǔ)上發(fā)展起來的。因此通過和JUnit結(jié)合使用能極大加強(qiáng)應(yīng)用程序的測(cè)試并加快應(yīng)用程序的開發(fā).
StrutsTestCase提供了兩者測(cè)試方式,模仿方式和容器測(cè)試方式. 所謂模仿方式就是有StrutsTestCase本身來模擬Web服務(wù)器. 而容器測(cè)試方式則需要Web服務(wù)器. 本文要討論的是前者,原因很簡(jiǎn)單,不需要Web服務(wù)器就能象測(cè)試普通的Java Class一樣測(cè)試Struts Action.
三、準(zhǔn)備StrutsTestCase和Struts Action/ActionForm/Config
StrutsTestCase是一個(gè)開源工具,可以到http://strutstestcase.sourceforge.net下載. 目前最新版本是2.1.3,如果你使用Servlet2.3就下載StrutsTestCase213-2.3.jar,使用Servlet2.4的就下載StrutsTestCase213-2.4.jar.另外StrutsTestCase本身就是從JUnit繼承的,所以你還需要下載JUnit3.8.1.
在本文中,我們用一個(gè)簡(jiǎn)單的例子來做測(cè)試. 假設(shè)我們有一張表Hotline(country varchar2(50),pno varchar2(50)),我們要做的是根據(jù)輸入條件從這張表檢索相應(yīng)的記錄.檢索條件是country.
Value Object:
package sample;
public class HotlineDTO implements Serializable{
private String country = "";
private String pno = "";
/**
* Method HotlineActionForm
*
*
*/
public HotlineDTO () {
super();
}
public void setCountry(String country) {
this.country = country;
}
public void setPno(String pno) {
this.pno = pno;
}
public String getCountry() {
return (this.country);
}
public String getPno() {
return (this.pno);
}
}
ActionForm:
package sample;
import org.apache.struts.action.ActionForm;
public class HotlineActionForm extends ActionForm{
private String country = "";
private String pno = "";
/**
* Method HotlineActionForm
*
*
*/
public HotlineActionForm() {
super();
}
public void setCountry(String country) {
this.country = country;
}
public void setPno(String pno) {
this.pno = pno;
}
public String getCountry() {
return (this.country);
}
public String getPno() {
return (this.pno);
}
}
Action Class:
public class SearchHotlineAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception {
String target = "";
try{
//調(diào)用HotlineDAO檢索hotline
String country=((HotlineActionForm)form).getCountry();
List hotlineList = HotlineDAO.getHotlineList(country);
if(hotlineList!=null && hotlineList.size()>0){
request.setAttribute("hotlineList",hotlineList);
target = "hotlineList";
}else{
target = "notfound";
}
}catch(Exception ex){
....
}
}
Struts Config:
<struts-config>
<form-beans>
<form-bean name="hotlineActionForm" type="sample.HotlineActionForm" />
.......
</form-beans>
<action-mappings>
<action path="/SearchHotline"
name="hotlineActionForm"
type="sample.SearchHotlineAction "
scope="request"
validate="false">
<forward name="hotlineList" path="/hotlineList.jsp"/>
<forward name="notfound" path="/searchHotline.jsp"/>
</action>
.....
<action-mappings>
........
<struts-config>
四、初試StrutsTestCase
當(dāng)采用模擬方式時(shí),所有的StrutsTestCase測(cè)試Class都是從MockStrutsTestCase繼承下來的.
下面我們就創(chuàng)建一個(gè)最簡(jiǎn)單的測(cè)試Class.
public class SearchHotlineAction extends MockStrutsTestCase {
public void setUp()throws Exception{
}
public void tearDown()throws Exception{
}
public void testSearchHotline() throws Exception{
setRequestPathInfo("/SearchHotline.do");
addRequestParameter("country", "CN");
actionPerform();
}
}
上面的Class相信用過JUnit的朋友都很熟悉.
好了,一個(gè)簡(jiǎn)單的測(cè)試?yán)泳屯瓿闪?如果你用的是Eclipse就選擇Run-Run...-JUnit-New就可以直接運(yùn)行.不需要發(fā)布你的程序,不需要任何的Web服務(wù)器支持,就可以測(cè)試Struts Action,這就是StrutsTestCase帶來的好處.下面簡(jiǎn)單地介紹一下它是怎么工作的.
在上面的例子中,我們調(diào)用setRequestPathInfo()告訴StrutsTestCase我們要模擬JSP調(diào)用SearchHotline.do這個(gè)Action,并且調(diào)用addRequestParameter()增加了一個(gè)參數(shù)country.最后調(diào)用actionPerform()運(yùn)行.
看到這里,大家發(fā)現(xiàn)一個(gè)問題沒有? 在上面Action的源代碼里我們是通過
String country=((HotlineActionForm)form).getCountry();
也就是ActionForm來取得輸入的參數(shù)值,可我們?cè)趖estSearchHotline()方法里并沒有設(shè)置ActionForm?
那么它是怎么出來的呢? 其實(shí)大家如果熟悉Struts的運(yùn)行流程的話就知道,JSP接受用戶的輸入并發(fā)請(qǐng)求時(shí)都是類似這樣的http://hostname/servletName?param1=value1¶m2=value2. 只是Struts接受到這些參數(shù)后再根據(jù)Struts Config里的Action和ActionForm的映射把他們轉(zhuǎn)為ActionForm后傳給Action的.
在上面的例子,我們只是簡(jiǎn)單地運(yùn)行了Action,那么Action是否正確執(zhí)行以及返回的結(jié)果是不是我們想要的呢?
我們繼續(xù)完善一下testSearchHotline()這個(gè)Method.
public void testSearchHotline() throws Exception{
setRequestPathInfo("/SearchHotline.do");
addRequestParameter("country", "CN");
actionPerform();
verifyNoActionErrors();
verifyForward("hotlineList");
assertNotNull(request.getAttribute("hotlineList"));
List hotlineList = (List) request.getAttribute("hotlineList");
for (Iterator it = hotlineList.iterator();it.hasNext();){
....
}
}
我們?cè)赼ctionPerform()后增加了幾行語(yǔ)句來斷定Struts Action是否正確執(zhí)行.
verifyNoActionErrors() -- 判斷Action里沒有任何的Action;
verifyForward("hotlineList") -- 判斷Action確實(shí)轉(zhuǎn)發(fā)到hotlineList;
assertNotNull(request.getAttribute("hotlineList")) -- 判斷Action確實(shí)返回了hotlineList并且不為空
到這里,我們已經(jīng)基本上討論完了StrutsTestCase的核心部分. 從頭到尾,我們沒有發(fā)布應(yīng)用程序,也不需要Web服務(wù)器,對(duì)我們來講,Struts Action就象普通的Java Class一樣容易調(diào)試測(cè)試.這就是StrutsTestCase給我們帶來的方便.
五、深入StrutsTestCase
除了以上我們用到的幾個(gè)斷定和校驗(yàn)方法外,StrutsTestCase還提供了其他幾個(gè)方法便于我們測(cè)試Struts Action. 下面我一一講述,具體的大家可以參考文檔.
verifyActionErrors/Messages -- 校驗(yàn)ActionActionServlet controller 是否發(fā)送了ActionError或ActionMessage. 參數(shù)為ActionError/Message Key
verifyNoActionErrors/Messages --校驗(yàn)ActionActionServlet controller 沒有發(fā)送ActionError或ActionMessage
VerifyForward -- 校驗(yàn)Action是否正確轉(zhuǎn)發(fā)到指定的ActionForward.
VerifyForwardPath -- 校驗(yàn)Action是否正確轉(zhuǎn)發(fā)到指定的URL
verifyInputForward -- 校驗(yàn)Action是否轉(zhuǎn)發(fā)到Action Mapping里的input屬性
verifyTilesForward/verifyInputTilesForward--和以上類似,應(yīng)用程序使用到tiles時(shí)用的
六、關(guān)于Web.xml和Struts-Config.xml
缺省情況下,StrutsTestCase認(rèn)為你的Web.xml和struts-config.xml的路徑分別是:/WEB-INF/web.xml和/WEB-INF/struts-config.xml
1. 假如你的web.xml/struts-config.xml的路徑是
d:/app/web/WEB-INF/web.xml(struts-config.xml)的話,就需要把d:/app/web加到classpath.
2. 假如你的struts config是strust-config-module.xml,
那么必須調(diào)用setConfigFile()設(shè)置你的struts config文件
七、結(jié)束語(yǔ)
J2EE應(yīng)用程序的測(cè)試在開發(fā)過程中占有相當(dāng)重要的位置,利用StrutsTestCase能極大方便你測(cè)試基于Struts的應(yīng)用程序.
關(guān)于作者:
葉楓:熱愛Java和Oracle. 在軟件開發(fā)有近10年, 目前在國(guó)外一家美國(guó)大公司擔(dān)任SA, 負(fù)責(zé)技術(shù)研究。作者Blog:http://blog.matrix.org.cn/page/葉楓