lexy

          支持開源,尊重他人的勞動!

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            17 隨筆 :: 0 文章 :: 9 評論 :: 0 Trackbacks

          使用HttpUnit進(jìn)行集成測試

          作者: 肖菁

          內(nèi)容摘要

          HttpUnit是一個集成測試工具,主要關(guān)注Web應(yīng)用的測試,提供的幫助類讓測試者可以通過Java類和服務(wù)器進(jìn)行交互,并且將服務(wù)器端的響應(yīng)當(dāng)作文本或者DOM對象進(jìn)行處理。HttpUnit還提供了一個模擬Servlet容器,讓你可以不需要發(fā)布Servlet,就可以對Servlet的內(nèi)部代碼進(jìn)行測試。本文中作者將詳細(xì)的介紹如何使用HttpUnit提供的類完成集成測試。

          1  HttpUnit簡介

          HttpUnit是SourceForge下面的一個開源項目,它是基于JUnit的一個測試框架,主要關(guān)注于測試Web應(yīng)用,解決使用JUnit框架無法對遠(yuǎn)程Web內(nèi)容進(jìn)行測試的弊端。當(dāng)前的最新版本是1.5.4。為了讓HtpUnit正常運行,你應(yīng)該安裝JDK1.3.1或者以上版本。

          1.1  工作原理

          HttpUnit通過模擬瀏覽器的行為,處理頁面框架(frames),cookies,頁面跳轉(zhuǎn)(redirects)等。通過HttpUnit提供的功能,你可以和服務(wù)器端進(jìn)行信息交互,將返回的網(wǎng)頁內(nèi)容作為普通文本、XML Dom對象或者是作為鏈接、頁面框架、圖像、表單、表格等的集合進(jìn)行處理,然后使用JUnit框架進(jìn)行測試,還可以導(dǎo)向一個新的頁面,然后進(jìn)行新頁面的處理,這個功能使你可以處理一組在一個操作鏈中的頁面。

          1.2  和其他商業(yè)工具的對比

          商業(yè)工具一般使用記錄、回放的功能來實現(xiàn)測試,但是這里有個缺陷,就是當(dāng)頁面設(shè)計被修改以后,這些被記錄的行為就不能重用了,需要重新錄制才能繼續(xù)測試。

          舉個例子:如果頁面上有個元素最先的設(shè)計是采用單選框,這個時候你開始測試,那么這些工具記錄的就是你的單項選擇動作,但是如果你的設(shè)計發(fā)生了變化,比如說我改成了下拉選擇,或者使用文本框接受用戶輸入,這時候,你以前錄制的測試過程就無效了,必須要重新錄制。

          而HttpUnit因為關(guān)注點是這些控件的內(nèi)容,所以不管你的外在表現(xiàn)形式如何變化,都不影響你已確定測試的可重用性。

          更多的關(guān)于httpunit的信息請訪問httpunit的主頁http://httpunit.sourceforge.net

          2  作者的演示環(huán)境

          系統(tǒng)平臺:Windows 2000 Server

          應(yīng)用服務(wù)器:深圳金蝶的apusic3.0

          開發(fā)工具: eclipse 2.1.2

          3  HttpUnit安裝、環(huán)境配置

          3.1  安裝

          1. 到HttpUnit的主頁http://httpunit.sourceforge.net下載最新的包文件,當(dāng)前的最新版本是1.5.4。

          2. 將下載的Zip包解壓縮到c:/httpunit(后面將使用%httpunit_home%引用該目錄)

          3.2  環(huán)境配置

          作者的演示程序都是在eclipse中開發(fā)、執(zhí)行的,所以環(huán)境配置都是以eclipse為例,如果你使用其他的開發(fā)工具,請根據(jù)這些步驟進(jìn)行環(huán)境配置。

          1. 啟動eclipse,建立一個java工程
          2. 將%httpunit_home%/lib/*.jar; %httpunit_home%/jars/*.jar加入到該java工程的Java build Path變量中

          4  如何使用httpunit處理頁面的內(nèi)容

          WebConversation類是HttpUnit框架中最重要的類,它用于模擬瀏覽器的行為。其他幾個重要的類是:

          WebRequest類,模仿客戶請求,通過它可以向服務(wù)器發(fā)送信息。

          WebResponse類,模擬瀏覽器獲取服務(wù)器端的響應(yīng)信息。

          4.1  獲取指定頁面的內(nèi)容

          4.1.1  直接獲取頁面內(nèi)容

          System.out.println("直接獲取網(wǎng)頁內(nèi)容:");
          //建立一個WebConversation實例
          WebConversation wc = new WebConversation();
          //向指定的URL發(fā)出請求,獲取響應(yīng)
          WebResponse wr = wc.getResponse( "http://localhost:6888/HelloWorld.html" );
          //用getText方法獲取相應(yīng)的全部內(nèi)容
          //用System.out.println將獲取的內(nèi)容打印在控制臺上
          System.out.println( wr.getText() );
          

          4.1.2  通過Get方法訪問頁面并且加入?yún)?shù)

          System.out.println("向服務(wù)器發(fā)送數(shù)據(jù),然后獲取網(wǎng)頁內(nèi)容:");
          //建立一個WebConversation實例
          WebConversation wc = new WebConversation();
          //向指定的URL發(fā)出請求
          WebRequest req = new GetMethodWebRequest( "http://localhost:6888/HelloWorld.jsp" );
          //給請求加上參數(shù)
          req.setParameter("username","姓名");
          //獲取響應(yīng)對象
          WebResponse resp = wc.getResponse( req );
          //用getText方法獲取相應(yīng)的全部內(nèi)容
          //用System.out.println將獲取的內(nèi)容打印在控制臺上
          System.out.println( resp.getText() );
          

          4.1.3 通過Post方法訪問頁面并且加入?yún)?shù)

          System.out.println("使用Post方式向服務(wù)器發(fā)送數(shù)據(jù),然后獲取網(wǎng)頁內(nèi)容:");
          //建立一個WebConversation實例
          WebConversation wc = new WebConversation();
          //向指定的URL發(fā)出請求
          WebRequest req = new PostMethodWebRequest( "http://localhost:6888/HelloWorld.jsp" );
          //給請求加上參數(shù)
          req.setParameter("username","姓名");
          //獲取響應(yīng)對象
          WebResponse resp = wc.getResponse( req );
          //用getText方法獲取相應(yīng)的全部內(nèi)容
          //用System.out.println將獲取的內(nèi)容打印在控制臺上
          System.out.println( resp.getText() );
          

          大家關(guān)注一下上面代碼中打了下劃線的兩處內(nèi)容,應(yīng)該可以看到,使用Get、Post方法訪問頁面的區(qū)別就是使用的請求對象不同。

          4.2  處理頁面中的鏈接

          這里的演示是找到頁面中的某一個鏈接,然后模擬用戶的單機(jī)行為,獲得它指向文件的內(nèi)容。比如在我的頁面HelloWorld.html中有一個鏈接,它顯示的內(nèi)容是TestLink,它指向我另一個頁面TestLink.htm. TestLink.htm里面只顯示TestLink.html幾個字符。

          下面是處理代碼:

          System.out.println("獲取頁面中鏈接指向頁面的內(nèi)容:");
          //建立一個WebConversation實例
          WebConversation wc = new WebConversation();
          //獲取響應(yīng)對象
          WebResponse   resp = wc.getResponse( "http://localhost:6888/HelloWorld.html" );
          //獲得頁面鏈接對象
          WebLink       link = resp.getLinkWith( "TestLink" );
          //模擬用戶單擊事件
          link.click();
          //獲得當(dāng)前的響應(yīng)對象
          WebResponse   nextLink = wc.getCurrentPage();
          //用getText方法獲取相應(yīng)的全部內(nèi)容
          //用System.out.println將獲取的內(nèi)容打印在控制臺上
          System.out.println( nextLink.getText() );
          

          4.3  處理頁面中的表格

          表格是用來控制頁面顯示的常規(guī)對象,在HttpUnit中使用數(shù)組來處理頁面中的多個表格,你可以用resp.getTables()方法獲取頁面所有的表格對象。他們依照出現(xiàn)在頁面中的順序保存在一個數(shù)組里面。

          [注意] Java中數(shù)組下標(biāo)是從0開始的,所以取第一個表格應(yīng)該是resp.getTables()[0],其他以此類推。

          下面的例子演示如何從頁面中取出第一個表格的內(nèi)容并且將他們循環(huán)顯示出來:

          System.out.println("獲取頁面中表格的內(nèi)容:");
          //建立一個WebConversation實例
          WebConversation wc = new WebConversation();
          //獲取響應(yīng)對象
          WebResponse   resp = wc.getResponse( "http://localhost:6888/HelloWorld.html" );
          //獲得對應(yīng)的表格對象
          WebTable webTable = resp.getTables()[0];
          //將表格對象的內(nèi)容傳遞給字符串?dāng)?shù)組
          String[][] datas = webTable.asText();
          //循環(huán)顯示表格內(nèi)容
          int i = 0 ,j = 0;
          int m = datas[0].length;
          int n = datas.length;
          while (i<n){
          j=0;
          while(j<m){
          System.out.println("表格中第"+(i+1)+"行第"+
          (j+1)+"列的內(nèi)容是:"+datas[i][j]);
          ++j;
          }
          ++i;
          }
          

          4.4  處理頁面中的表單

          表單是用來接受用戶輸入,也可以向用戶顯示用戶已輸入信息(如需要用戶修改數(shù)據(jù)時,通常會顯示他以前輸入過的信息),在HttpUnit中使用數(shù)組來處理頁面中的多個表單,你可以用resp.getForms()方法獲取頁面所有的表單對象。他們依照出現(xiàn)在頁面中的順序保存在一個數(shù)組里面。

          [注意] Java中數(shù)組下標(biāo)是從0開始的,所以取第一個表單應(yīng)該是resp.getForms()[0],其他以此類推。

          下面的例子演示如何從頁面中取出第一個表單的內(nèi)容并且將他們循環(huán)顯示出來:

          System.out.println("獲取頁面中表單的內(nèi)容:");
          //建立一個WebConversation實例
          WebConversation wc = new WebConversation();
          //獲取響應(yīng)對象
          WebResponse   resp = wc.getResponse( "http://localhost:6888/HelloWorld.html" );
          //獲得對應(yīng)的表單對象
          WebForm webForm = resp.getForms()[0];
          //獲得表單中所有控件的名字
          String[] pNames = webForm.getParameterNames();
          int i = 0;
          int m = pNames.length;
          //循環(huán)顯示表單中所有控件的內(nèi)容
          while(i<m){
          System.out.println("第"+(i+1)+"個控件的名字是"+pNames[i]+
          ",里面的內(nèi)容是"+webForm.getParameterValue(pNames[i]));
          ++i;
          }
          

          5  如何使用httpunit進(jìn)行測試

          5.1  對頁面內(nèi)容進(jìn)行測試

          httpunit中的這部分測試完全采用了JUnit的測試方法,即直接將你期望的結(jié)果和頁面中的輸出內(nèi)容進(jìn)行比較。不過這里的測試就簡單多了,只是字符串和字符串的比較。

          比如你期望中的頁面顯示是中有一個表格,它是頁面中的第一個表格,而且他的第一行第一列的數(shù)據(jù)應(yīng)該是顯示username,那么你可以使用下面的代碼進(jìn)行自動化測試:

          System.out.println("獲取頁面中表格的內(nèi)容并且進(jìn)行測試:");
          //建立一個WebConversation實例
          WebConversation wc = new WebConversation();
          //獲取響應(yīng)對象
          WebResponse   resp = wc.getResponse( "http://localhost:6888/TableTest.html" );
          //獲得對應(yīng)的表格對象
          WebTable webTable = resp.getTables()[0];
          //將表格對象的內(nèi)容傳遞給字符串?dāng)?shù)組
          String[][] datas = webTable.asText();
          //對表格內(nèi)容進(jìn)行測試
          String expect = "中文";
          Assert.assertEquals(expect,datas[0][0]);
          

          5.2  對Servlet進(jìn)行測試

          除了對頁面內(nèi)容進(jìn)行測試外,有時候(比如開發(fā)復(fù)雜的Servlets的時候),你需要對Servlet本身的代碼塊進(jìn)行測試,這時候你可以選擇HttpUnit,它可以提供一個模擬的Servlet容器,讓你的Servlet代碼不需要發(fā)布到Servlet容器(如tomcat)就可以直接測試。

          5.2.1  原理簡介

          使用httpunit測試Servlet時,請創(chuàng)建一個ServletRunner的實例,他負(fù)責(zé)模擬Servlet容器環(huán)境。如果你只是測試一個Servlet,你可以直接使用registerServlet方法注冊這個Servlet,如果需要配置多個Servlet,你可以編寫自己的web.xml,然后在初始化ServletRunner的時候?qū)⑺奈恢米鳛閰?shù)傳給ServletRunner的構(gòu)造器。

          在測試Servlet時,應(yīng)該記得使用ServletUnitClient類作為客戶端,他和前面用過的WebConversation差不多,都繼承自WebClient,所以他們的調(diào)用方式基本一致。要注意的差別是,在使用ServletUnitClient時,他會忽略URL中的主機(jī)地址信息,而是直接指向他的ServletRunner實現(xiàn)的模擬環(huán)境。

          5.2.2  簡單測試

          本實例只是演示如何簡單的訪問Servlet并且獲取他的輸出信息,例子中的Servlet在接到用戶請求的時候只是返回一串簡單的字符串:Hello World!.

          1. Servlet的代碼如下:

          public class MyServlet extends HttpServlet {
          public void service(HttpServletRequest req, HttpServletResponse resp)
          throws IOException
          {
          PrintWriter out = resp.getWriter();
          //向瀏覽器中寫一個字符串Hello World!
          out.println("
          
              Hello World!");
              out.close();
              }
              }
              

          2. 測試的調(diào)用代碼如下:

          //創(chuàng)建Servlet的運行環(huán)境
              ServletRunner sr = new ServletRunner();
              //向環(huán)境中注冊Servlet
              sr.registerServlet( "myServlet", MyServlet.class.getName() );
              //創(chuàng)建訪問Servlet的客戶端
              ServletUnitClient sc = sr.newClient();
              //發(fā)送請求
              WebRequest request   = new GetMethodWebRequest( "http://localhost/myServlet" );
              //獲得模擬服務(wù)器的信息
              WebResponse response = sc.getResponse( request );
              //將獲得的結(jié)果打印到控制臺上
              System.out.println(response.getText());
              

          5.2.3  測試Servlet的內(nèi)部行為

          對于開發(fā)者來說,僅僅測試請求和返回信息是不夠的,所以HttpUnit提供的ServletRunner模擬器可以讓你對被調(diào)用Servlet內(nèi)部的行為進(jìn)行測試。和簡單測試中不同,這里使用了InvocationContext獲得該Servlet的環(huán)境,然后你可以通過InvocationContext對象針對request、response等對象或者是該Servlet的內(nèi)部行為(非服務(wù)方法)進(jìn)行操作。

          下面的代碼演示了如何使用HttpUnit模擬Servlet容器,并且通過InvocationContext對象,測試Servlet內(nèi)部行為的大部分工作,比如控制request、session、response等。

          //創(chuàng)建Servlet的運行環(huán)境
              ServletRunner sr = new ServletRunner();
              //向環(huán)境中注冊Servlet
              sr.registerServlet( "InternalServlet", InternalServlet.class.getName() );
              //創(chuàng)建訪問Servlet的客戶端
              ServletUnitClient sc = sr.newClient();
              //發(fā)送請求
              WebRequest request   = new GetMethodWebRequest( "http://localhost/InternalServlet" );
              request.setParameter("pwd","pwd");
              //獲得該請求的上下文環(huán)境
              InvocationContext ic = sc.newInvocation( request );
              //調(diào)用Servlet的非服務(wù)方法
              InternalServlet is = (InternalServlet)ic.getServlet();
              is.myMethod();
              //直接通過上下文獲得request對象
              System.out.println("request中獲取的內(nèi)容:"+ic.getRequest().getParameter("pwd"));
              //直接通過上下文獲得response對象,并且向客戶端輸出信息
              ic.getResponse().getWriter().write("haha");
              //直接通過上下文獲得session對象,控制session對象
              //給session賦值
              ic.getRequest().getSession().setAttribute("username","timeson");
              //獲取session的值
              System.out.println("session中的值:"+ic.getRequest().getSession().getAttribute("username"));
              //使用客戶端獲取返回信息,并且打印出來
              WebResponse response = ic.getServletResponse();
              System.out.println(response.getText());
              

          [注意]

          在測試Servlet的之前,你必須通過InvocationContext完成Servlet中的service方法中完成的工作,因為通過newInvocation方法獲取InvocationContext實例的時候該方法并沒有被調(diào)用。

          6  總結(jié)

          本文中,作者詳細(xì)的演示和介紹了如何使用HttpUnit提供的類來進(jìn)行集成測試,主要實現(xiàn)以下操作:

          1. 模擬用戶行為向服務(wù)器發(fā)送請求,傳遞參數(shù)
          2. 模擬用戶接受服務(wù)器的響應(yīng)信息,并且通過輔助類分析這些響應(yīng)信息,結(jié)合JUnit框架進(jìn)行測試
          3. 使用HttpUnit提供的模擬Servler容器,測試開發(fā)中的Servlet的內(nèi)部行為

          參考資料

          1. HttpUnit幫助  http://httpunit.sourceforge.net
          2. JUnit幫助  http://junit.org/index.htm

          關(guān)于作者

          簡介:肖菁目前是湖南省長沙鐵道學(xué)院科創(chuàng)計算機(jī)系統(tǒng)集成有限公司軟件中心軟件工程師,IBM developerworks/BEA dev2dev撰稿人,主要研究J2EE編程技術(shù)、Web Service技術(shù)以及他們在websphere、weblogic、apache平臺上的實現(xiàn),擁有IBM 的 Developing With Websphere Studio證書,個人網(wǎng)站:http://vivianj.go.nease.net/

          posted on 2007-10-30 18:56 lexy 閱讀(306) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 台北县| 锡林浩特市| 涿州市| 图片| 司法| 偏关县| 虹口区| 松溪县| 吴桥县| 博乐市| 尼木县| 中山市| 睢宁县| 高雄市| 莱西市| 衡水市| 红安县| 叶城县| 闸北区| 平昌县| 阳高县| 辰溪县| 岳池县| 安康市| 四子王旗| 莆田市| 百色市| 会东县| 莎车县| 新竹市| 大港区| 桃园县| 乌鲁木齐县| 扎赉特旗| 呼玛县| 河间市| 玛沁县| 安仁县| 赣榆县| 得荣县| 云霄县|