2007年6月25日 星期一

(2005.11月號-142期)_CanooWebTest實作(下)

在上一期的內容中我們簡單的介紹了WebTest,並且使用了Maven協同WebTest進行簡易腳本測試,而本期將更深入的探討其腳本製作上的考量與進行模組化的腳本製作。




序言

經過上一期的的說明,相信讀者對WebTest已經有了進一步的認識,但在眾多的自訂標籤中如何適當的運用來協助進行測試,才是重要的課題。接下來筆者將進行進階版本的測試案例撰寫,並且重覆進行改寫,藉以循序漸進的導引讀者了解WebTest於實務上應用的特性,以利於未來在實際應用上以模組化、彈性化、容易維護的角度進行測試案例的撰寫。


註:本次範例請參考資料結構1,完整程式碼請至RunPC網站下載。


資料結構1

Jpetstore_WebTest

+--webtest 腳本檔資料夾

| +--config 客製化屬性放置路徑

| | +--login.properties

| | +--shopping.properties

| +--modules 測試用模組放置路徑

| | +--checkout.ent

| | +--login.ent

| | +--logout.ent

| | +--set.init.ent

| | +--set.config.ent

| | +--shopping.ent

| +--testsuit1 測試案例1

| | +--login.xml

| | +--newAccount.xml

| | +--webtest.xml

| +--testsuit2 測試案例2

| | +--shopping_dogs.properties

| | +--shopping_fish.properties

| | +--shopping.xml

| | +--webtest.xml

| +--testsuit3 測試案例3

| | +--login_shopping_checkout.xml

| | +--webtest.xml

| +--webtest.xml

+--project.properties

+--project.xml


測試案例一

在上一期的實作中,當webtest.xml腳本檔撰寫完成之後,即可透過maven webtest進行功能測試,這是因為在Webtest Plug-in中預設執行路徑指定在${basedir}/webtest下的*.xml檔的緣故,因此若將撰寫完成的腳本檔置於${basedir}/webtest的資料夾中,無需指定腳本檔名WebTest即可進行所有腳本的測試。


而從另一方面來說,以這種方式將無法指定腳本執行順序,雖然我們可以指定maven.webtest.file=Test*.xml執行特定腳本檔,但顯然彈性應用上還是不夠,因此比較建議的方式為建立一個只包含執行順序內容的腳本檔,並在執行時指定該腳本為功能測試的進入點。撰寫方式參考腳本1,在本期的所有測試案例中都將指定webtest.xml做為腳本執行順序檔,例如腳本1即依順序執行了,新增帳號與登入這二個測試腳本。


就目前所知預設的JPetStore的範例中並未建立帳號相關資訊,在此我們使用WebTest進行建立帳號的測試腳本,參考腳本2可知所有的腳本檔中至少必須包含二個實體檔供XML腳本使用ENTITY的方式進行引入,分別是webtestmodulesset.init.entwebtestmodulesset.config.ent,這二個檔案在上一期中已經介紹過,在此不再贅述。


腳本212<testSpec>標籤是WebTest的測試進入點,這個標籤中必須包含了<config>標籤的網站連結設定與<steps>標籤的測試步驟。在此要注意的是每一個testSpec標籤都擁有各自的Session,不同的testSpec區塊內容都定義者在不同Session內的動作。


腳本215<invoke>標籤則是透過URL的方式進行網頁請求的連結,若invoke的網頁不存在則會發生StepFailedException,對於配置基礎驗證(Basic Authentication)的網站,也可透過usernamepassword屬性設定進行登入,url則代表欲連結網頁的相對路徑。


腳本224<repeat>標籤代表著重覆次數的操作,在本範例中我們進行了10次的帳號建立動作,經由27invoke將網頁導至新增帳號表單,並透過<setinputfield>標籤對指定的欄位設值,在33行中可以發現引用了EL語法#{count}取得目前已重覆次數作為帳號名稱的區隔,這種寫法跟程式for(int i=0 ; i<10 ; i++)中取得i的做法是相同的,預設是透過#{count}取得重覆次數。


腳本241<clickbutton>標籤則是模擬了滑鼠按下Submit按鈕的動作,將表單資料送出。當所需欄位資料輸入完成送出的同時,系統將建立該帳號並自動進行登入。


腳本244<verifyxpath>標籤,在說明該標籤之前,我們知道帳號已經建立並且登入,而如何確定真的登入了,這時就該判斷回應的網頁上是否出現了所需的訊息,例如使用者未登入之前,網頁上出現會有[登入]的連結,已登入時則有[登出]的連結。若這些訊息只是單純的字串時我們可使用<verifytext>來驗證,如<verifytext stepid="驗證是否登入" text="登出" />,但若驗證訊息若不是文字的話,verifytext就無法進行檢查了。在本例中登入與登出的連結皆是以圖片顯示,這時就必需使用XPath協助對HTML結構進行查詢。在本例中<verifyxpath stepid="確認是否已登入" xpath="//img[@src='../images/sign-out.gif']"/>意謂著驗證網頁中是否包含了IMG並且src屬性指向../images/sign-out.gif圖片的物件。讀者若對XPath有興趣可參考http://www.w3.org/TR/xpath官方網站或至http://www.purpletech.com/xpe/index.jsp下載XPath Explorer進行XML Path Language的學習。


到目前為止我們已經說明了測試案例一所需標籤的使用,而測試流程的建立則必須由測試人員進行實際的系統操作並評估於何處加入檢查點,以了解系統是否如預期的回應。測試人員可一邊進行系統操作,一邊進行腳本建立,建立腳本所需的資訊如連結網址、填入欄位名稱、點選按鈕屬性等都是由使用者端的網頁得來的,有時無可避免測試人員必須檢視HTML原始碼以了解更多的訊息,但畢竟都比白箱測試來得簡單多了。


測試案例一撰寫完成後於Console下執行maven webtest -Dmaven.webtest.file=testsuit1/webtest.xml進行測試與報表的建立。


腳本1 testsuit1webtest.xml

<?xml version="1.0" encoding="Big5"?>

<project name="WebTest" basedir="." default="all">

<target name="all" >

<ant antfile="newAccount.xml" dir="."/>

<ant antfile="login.xml" dir="."/>

</target>

</project>


腳本2 testsuit1newAccount.xml

01 <?xml version="1.0" encoding="Big5"?>

02 <!DOCTYPE project [

03 <!ENTITY init SYSTEM "../modules/set.init.ent">

04 <!ENTITY config SYSTEM "../modules/set.config.ent">

05 ]>

06 <project name="newAccount" basedir="." default="all">

07 &init;

08 <target name="all" >

09 <antcall target="newAccountTest"/>

10 </target>

11 <target name="newAccountTest" >

12 <testSpec name="newAccountTest" >

13 &config;

14 <steps>

15 <invoke

16 stepid="連結「JPetstore首頁」網址"

17 url="shop/index.do"/>

18 <invoke

19 stepid="連結「登錄」網頁"

20 url="shop/signonForm.do"/>

21 <invoke

22 stepid="連結「新增帳號」網頁"

23 url="shop/newAccount.do"/>

24 <repeat

25 stepid="新增指定人數帳號"

26 count="10">

27 <invoke

28 stepid="連結「新增帳號」網頁"

29 url="shop/newAccount.do"/>

30 <setinputfield

31 stepid="輸入User ID"

32 name="account.username"

33 value="TestID#{count}" />

34 <setinputfield

35 stepid="輸入New password"

36 name="account.password"

37 value="0000" />

38

39 ...中間省略...

40

41 <clickbutton

42 stepid="[Submit]送出"

43 name="submit"/>

44 <verifyxpath

45 stepid="確認是否已登入"

46 xpath="//img[@src='../images/sign-out.gif']"/>

47 <invoke

48 stepid="進行登出"

49 url="shop/signoff.do"/>

50 </repeat>

51 </steps>

52 </testSpec>

53 </target>

54 </project>


測試案例二

測試案例二中,我們將進行購物車的操作,在尚未進行腳本撰寫之前先行於系統上進行寵物商品的導覽,確定要購買的分類(Category)、產品(Product)、項目(Item),並製作如測試參數1與測試參數2的屬性檔。


接著撰寫腳本4並在testsuit2webtest.xml中置入測試參數檔進行腳本的執行,在腳本3中我們可以發現本次的測試進行了二次測試腳本的執行,並分別以shopping_fish.propertiesshopping_dogs.properties進行測試參數的設定。腳本422<clicklink>標籤模擬按下Link的動作,並在該檔中進行了${category.id}${product.id}${item.id} 取得ANTProperty,因此在每一次進行shopping.xml腳本載入的同時會依據給予的properties檔的不同,設予不同的測試參數,在此相同的測試腳本就能重覆的利用。


但這樣的寫法在實際的執行上卻發生了問題,我們進行了二次購物車的動作並購買了商品, 照理來說應該在購物車上顯示二項商品才是,不過在這裏無論進行了多少次的購物動作,購買的商品都只有最後一項,前面購買的商品都會被忽略。


請參考腳本412行,筆者在前面曾經提過每一個testSpec標籤都擁有各自的Session,不同的testSpec區塊內容都定義者在不同Session內的動作,這就表示了在webtest.xml中進行的二次腳本,是屬於二次的購買動作,並不屬於一次的操作情節。


因此讀者在實作的同時必須注意,腳本檔中可以撰寫多個不同的testSpec,但每一個testSpec都是獨立的測試情節,所有的操作是不可分割的。另外使用ANTProperty並不適合作為測試參數使用,因為在ANTProperty一旦設定了值,就無法再次變更,這種特性作為動態參數的傳遞並不恰當。


若要執行測試案例二,可於Console下達maven webtest -Dmaven.webtest.file=testsuit2/webtest.xml指令,筆者將在測試案例三進行改寫。


腳本3 testsuit2webtest.xml

<?xml version="1.0" encoding="Big5"?>

<project name="WebTest" basedir="." default="all">

<target name="all" >

<ant antfile="shopping.xml" dir=".">

<property file="shopping_fish.properties"/>

</ant>

<ant antfile="shopping.xml" dir=".">

<property file="shopping_dogs.properties"/>

</ant>

</target>

</project>


腳本4 testsuit2shopping.xml

01<?xml version="1.0" encoding="Big5"?>

02<!DOCTYPE project [

03<!ENTITY init SYSTEM "../modules/set.init.ent">

04<!ENTITY config SYSTEM "../modules/set.config.ent">

05]>

06<project name="shopping" basedir="." default="all">

07 &init;

08 <target name="all" >

09 <antcall target="shopping" />

10 </target>

11 <target name="shopping" >

12 <testSpec name="shopping" >

13 &config;

14 <steps>

15 <invoke

16 stepid="連結「JPetstore首頁」網址"

17 url="shop/index.do"/>

18 <invoke

19 stepid="瀏覽選購,連結「${category.id}」網頁"

20 url="shop/viewCategory.do?categoryId=${category.id}"

21 />

22 <clicklink stepid="點選Product"

23 label="${product.id}"

24 />

25 <clicklink stepid="點選Item"

26 label="${item.id}"

27 />

28 <invoke

29 stepid="點選[${item.id}]加入購物車"

30 url="shop/addItemToCart.do?workingItemId=${item.id}"

31 />

32 </steps>

33 </testSpec>

34 </target>

35</project>


測試參數1 testsuit2shopping_dogs.properties

category.id=DOGS

product.id=K9-DL-01

item.id= EST-10


測試參數2 testsuit2shopping_fish.properties

category.id=FISH

product.id=FI-FW-02

item.id=EST-21


測試案例三

參考腳本6,在測試案例三中,我們將購物流程抽離獨立成單一的實體檔modulesshopping.ent,在腳本5進行實體檔引入的動作並透過configshopping.properties進行參數的設值,參考測試參數3


腳本525~30<storeDynamicProperty>標籤,有別於ANTProperty的設定,使用該標籤的參數,可以在腳本檔中重覆定義值而達到動態設定參數進行測試的目的,當使用storeDynamicProperty設定參數後取得動態參數值則必須使用#{ }EL語法,請注意與ANT內定的${ }語法的不同。


除了購物動作之外,在本例中也將登入(login)、登出(logout)、付款(checkout)的動作抽離出成單一實體模組,以供未來進行新增測試案例時重覆使用,因此我們在腳本5中完成了一個完整的Scenario。請參考腳本789與圖1


測試案例三撰寫完成後於Console下執行maven webtest -Dmaven.webtest.file=testsuit1/webtest.xml即可完成整個Scenario的測試。


腳本5 testsuit3login_shopping_checkout.xml

01<?xml version="1.0" encoding="Big5"?>

02<!DOCTYPE project [

03<!ENTITY init SYSTEM "../modules/set.init.ent">

04<!ENTITY config SYSTEM "../modules/set.config.ent">

05<!ENTITY login SYSTEM "../modules/login.ent">

06<!ENTITY shopping SYSTEM "../modules/shopping.ent">

07<!ENTITY checkout SYSTEM "../modules/checkout.ent">

08<!ENTITY logout SYSTEM "../modules/logout.ent">

09]>

10<project name="login_shopping_checkout"

11 basedir="." default="all">

12 <property file="../config/login.properties"/>

13 <property file="../config/shopping.properties"/>

14 &init;

15 <target name="all" >

16 <antcall target="login_shopping_checkout" />

17 </target>

18 <target name="login_shopping_checkout" >

19 <testSpec

20 name="測試情節:1登入2購物3付款4登出" >

21 &config;

22 <steps>

23 &login;

24 <group stepid="進行購物">

25 <storeDynamicProperty

26 name="category.id" value="${category01.id}"/>

27 <storeDynamicProperty

28 name="product.id" value="${product01.id}"/>

29 <storeDynamicProperty

30 name="item.id" value="${item01.id}"/>

31 &shopping;

32 <storeDynamicProperty

33 name="category.id" value="${category02.id}"/>

34 <storeDynamicProperty

35 name="product.id" value="${product02.id}"/>

36 <storeDynamicProperty

37 name="item.id" value="${item02.id}"/>

38 &shopping;

39 ...中間省略...

40 </group>

41 &checkout;

42 &logout;

43 </steps>

44 </testSpec>

45 </target>

46</project>



腳本6 modulesshopping.ent

<?xml version="1.0" encoding="Big5"?>

<invoke

stepid="連結「JPetstore首頁」網址"

url="shop/index.do"/>

<invoke

stepid="進行瀏覽並選購,連結「#{category.id}」網頁"

url="shop/viewCategory.do?categoryId=#{category.id}"

/>

<clicklink stepid="點選Product"

label="#{product.id}"

/>

<clicklink stepid="點選Item"

label="#{item.id}"

/>

<invoke

stepid="點選[#{item.id}]加入購物車"

url="shop/addItemToCart.do?workingItemId=#{item.id}"

/>


測試參數3 configshopping.properties

category01.id=FISH

product01.id=FI-FW-02

item01.id=EST-21


category02.id=DOGS

product02.id=K9-DL-01

item02.id=EST-10


category03.id=CATS

product03.id=FL-DSH-01

item03.id=EST-14


category04.id=REPTILES

product04.id=RP-SN-01

item04.id=EST-12


腳本7 moduleslogin.ent

<?xml version="1.0" encoding="Big5"?>

<group stepid="使用者登入">

<invoke

stepid="連結「JPetstore首頁」網址"

url="shop/index.do"/>

<invoke

stepid="連結「登錄」網頁"

url="shop/signonForm.do"/>

<setinputfield

stepid="輸入Username"

name="username"

value="${username}" />

<setinputfield

stepid="輸入Password"

name="password"

value="${password}" />

<clickbutton

stepid="[Submit]送出"

name="update"/>

<verifyxpath

stepid="確認是否已登入"

xpath="//img[@src='../images/sign-out.gif']"/>

</group>


腳本8 moduleslogout.ent

<?xml version="1.0" encoding="Big5"?>

<group stepid="登出">

<invoke

stepid="進行登出"

url="shop/signoff.do"/>

<verifyxpath

stepid="確認是否已登出"

xpath="//img[@src='../images/sign-in.gif']"/>

</group>


腳本9 modulescheckout.ent

<?xml version="1.0" encoding="Big5"?>

<group stepid="付款">

<invoke

stepid="連結「付款」網址"

url="shop/checkout.do"/>

<invoke

stepid="查看[Checkout Summary]並按下[Continue]"

url="shop/newOrder.do"/>

<invoke

stepid="進行付款"

url="shop/newOrder.do?_finish=true"/>

<verifytext stepid="確認是否出現訂購完成訊息"

text="Thank you, your order has been submitted" />

</group>


1 測試案例順序圖。




結語

在這二期的文章中,筆者所介紹的都是以自動化測試為主的工具。讀者心中可能會有所疑惑:


1.自動化測試是否真的能夠為軟體開發帶來實質的效益嗎?

2.自動化測試是否能完全取代人工測試?

3.目前的商業測試工具多數都有「錄製/播放」的功能,對於需要撰寫腳本檔的測試工具並沒有實務上的用途。


第一點的答案是肯定的關於「軟體測試自動化」已經被許多的軟體測試專家驗證是可行的,並且反覆的運用在許多軟體開發過程中。大多數參與軟體測試的專家也同意自動化測試不只是值得的同時也是必要的。但在建構自動化測試的之前,必須備有一套「正規」的人工測試流程。並且從商業功能規格或設計文件中擷取必要的測試案例與建立可獨立的測試環境。再者必須了解到不是所有的測試都適合或值得自動化。例如將過度複雜的測試自動化可能會花費更多的成本。請謹記,將自動化的重點放在主要的測試個案上。只有會重複執行的測試才需要自動化。對於只做一次的測試能免則免。


自動化測試最實際的應用與目的是自動化回歸測試。也就是說,我們必須要保存所有測試個案的結果,而且這些測試個案是可以重複執行於每次應用軟體被變更後,以確保應用軟體的變更沒有產生任何因為不小心所造成的影響。


而對於第二點來說自動化測試並不會取代人工測試或是縮減測試人員的數量。自動化測試工具就只是工具,幫助測試人員可以將軟體測試工作做得更好。自動化測試工具可以幫測試人員執行那些無聊,但是又必須一直重複執行的測試個案。讓測試人員有更多時間去設計更好、更能有效找到問題的測試個案。自動化測試主要意義在於利用策略、工具以及產出等,減少人工介入非技術性 ( unskilled )、重複性 ( repetitive )、冗長 ( redundant ) 的測試動作。


最後須要帶給各位的觀念是雖然多數的商業測試工具都有「錄製/播放」測試案例的功能,但以「錄製/播放」的方式實施自動化儘量能免則免,原因在於基本上透過錄製建立的腳本,裡面的資料都可能是硬編碼,而當應用軟體資料變動、軟體功能變動,意味這些硬編碼的資料可能也需要修改,甚至必須重新錄製腳本。並且維護這些錄製的腳本,成本是非常高的,對於軟體開發與測試來說不可不謹慎。




Read More......

2007年6月23日 星期六

補-2007/06/19記事(力特舊同事聚會與看電影)



似乎已經一年多沒見過他們了,力特的舊同事們。

下面餐廳是中午聚餐的地點
餐廳店名:夢見地中海
地址:台北市大安區師大路837
電話:02-23630336
網址:http://www.map.com.tw/landmarkads/medisea/aboutUs.htm
http://106.travel-web.com.tw/Show/Style3/News/c1_News.asp?SItemId=0271030&ProgramNo=A100045000001&SubjectNo=31372&Page=1

有點不太好意思,當天的餐點其實滿不錯的,不過因為早餐吃太多所以點的義大利麵並沒有吃完。
(因為19號那天聚會完就要返鄉,家中冰箱要休息四天,所以把冰箱中食物清到肚肚中,導致沒胃口)
原本是五人的聚餐(我、交換髒東西的好友、一對應該會論及婚嫁的男女朋友、一位素未某面的女姓朋友)。
不過一個人臨時有事,所以就是我們這四位曾經是力特同事又是以前天天在一起的室友們的聚會了。

這麼一來先前買的預售電影票,不就有一張開天窗了!
只好趕緊打電話問問幾個朋友是否能挪出時間加入我們的行列,一起去看「史瑞克3」。
呵呵!意料中的事,其他朋友們都有自己的活動。
後來我們的Selina說他板橋有個朋友,應該可以找他來,不過已經快開場時才想到,應該已經是來不及了!

電影我們是到西門町的國賓影城,在容納1234個座位的劇場中,坐傳說中的皇帝位(19排的2、4、6、8、10),聽說音響設備不錯。
現場一感覺,的確是如此,滿有震撼力的,不過這麼好的設備拿來看卡通到是滿可惜的。
看大場面的影片應該不錯,希望下一檔的「變形金鋼」會有機會來這裏看。

Read More......

補-2007/06/22記事(慶生)

對於其他的上班族而言,今天還是上班的日子。
而明天(星期六)因應19日的彈性放假,多數人還是得上班。
不過對我來說,我給自己放了19~22四天的假。
因為是自由工作者的關系吧,沒了穩定的日子,多了風險,卻也多了自由。
返鄉不用跟人家擠,訂那種提前二個星期訂還訂不到的火車票。
上網隨便Click就一張了。回北部也只要當場買就有位子。
這大概是我目前這種生活型態最大的好處了吧!

雖然沒什麼特別的事,我還是在22日返回北部。
繼續我一定程度上的自由、研究與工作。

但重要的是,22號是我一位熟識許久的正妹型朋友生日。
會安排這幾天回中部,主要目的也是希望為這位朋友慶生。
不過我似乎沒趕到正式的慶生活動,聽說她的生日在21號就提前辦了。
玩得好像還滿High的(也好啦!我不適合參加那樣的場合)。

中午到了台中,原先找的公車路線派不上用場,完全等不到要搭的公車。
(覺得台中的公車規劃以前就不發達,沒想到現在也是如此)
放棄後改搭計程車,到達目的地後,聯絡朋友,呵呵!新狀況出現!!
因昨晚朋友玩太High,睡在朋友家了。折騰了半小時才會面。
雖然當天的狀況滿多的,不過滿開心的,難得久沒見面的朋友還能保持穩定的情誼。
算難能可貴的了。不過可惜的是,今天的這攤飯局還是讓他們請了客。

所以最後我想說,喂!佳倩、孟如!下次該讓我請了吧!
再不然我可不敢再去找你們了!還有,佳倩,Happy Birthday囉!

Read More......

2007年6月19日 星期二

料理新鮮人(第二集-絕不認輸!)



咱們家的Bambi還會不會回來呢?
已經有多少人在現在這個時刻離開店裡
為什麼讓自已過的這麼痛苦
不如去找一家輕鬆點的小店工作

感受不到自己存在的必要性是多麼的痛苦
什麼忙都幫不上的感覺是最難熬的
可是
他究竟會不會逃避痛苦呢?
敢勇於面對也是一種才能
這個店裡工作的每一位員工,都撐了下來
那麼你會怎麼選擇呢?Bambi!





為什麼要讓阿伴去東京呢?
你早就知道他會受委屈的吧!

男人啊!
男人不會一出生就是男子漢
要靠自己的力量成長
不管廚師或是別的什麼行業
無論做什麼,都要經歷同樣的感受
不甘心、遇到任何事都不逃避、不想被人比下去

經過這些思想的洗禮,男人將能承受一切事物
變的頂天立地

我滿喜歡上面的二段話,其實很多事不言而諭了吧!
是個男人就該經歷些過程,如果以前的我遇到困難就逃避的話
現在的我應該還是個半調子的開發人員而已。

但我們也得承認!在許多的磨難中,也有些試著想逃避,或真的逃避的情況發生。
有時我們必須抉擇,如果目標是明確的、方向是對的、你就是想成為什麼樣的人,那就真的千萬不要逃避接踵而來的磨綀。
如果你還在找方向,還沒有明確的想成就什麼樣的理想,你可以對困境選擇逃避,但也可以從困境中理出你真正想走的路。
危機就是轉機,不是嗎?

原本沒打算看這一部日劇的,一直以為這部應該跟「美食偵探2」相似的內容。
如果真的跟「美食偵探2」相似的內容話,那就只能用悶一字來形容了。

不過看了我們SaSha的介紹 後,才發現,錯誤的先入為主觀念真的很糟。
我誤會了這部日劇了,看來未來的幾週,我應該會看完這部劇吧!











Read More......

2007年6月17日 星期日

[轉載] 如何更改Oracle XE for Windows的HTTP port number?

這是一篇轉載的文章,原文內容請參考:
http://www.cwt.idv.tw/~andy/pLog/index.php?op=ViewArticle&articleId=33&blogId=1



Oracle XE (eXpresss Edition) 是一套免費的資料庫管理系統。它的功能和 performance 當然無法和正式的 Oracle 10g Database 相比。但是,當作小型的網頁後端資料庫,已是綽綽有餘。Oracle XE 目前已有 for Windows 和 for Linux 兩個平台的版本,而 for Linux 的版本,又分成給 Redhat/Fedora Core 和 SuSE 用的 RPM 版,以及給 Debian 和 Ubuntu 用的 DEB 版。我只用過 for Windows 版和 RPM 版,雖然安裝好了之後,由於操作界面採用 Web 形式,所以完全相同。但是在安裝的過程中,卻有一點點的差異。RPM 版在安裝完畢後,會出現以下這條訊息,告訴你還有一些東西要設定,其中就包括 HTTP port number。

You must run '/etc/init.d/oracle-xe configure' as the root user to
configure the database.

一旦你如以下輸入,我們可以看到第一個問題就是詢問 HTTP port number,當然還有像 SYSTEM/SYS 的密碼設定,還有是否要開機時自動啟動等等:

$ /etc/init.d/oracle-xe configure

Oracle Database 10g Express Edition Configuration
-------------------------------------------------
This will configure on-boot properties of Oracle Database 10g Express
Edition. The following questions will determine whether the database should
be starting upon system boot, the ports it will use, and the passwords that
will be used for database accounts. Press to accept the defaults.
Ctrl-C will abort. Specify the HTTP port that will be used for Oracle Application Express [8080]:XXXX
Specify a port that will be used for the database listener [1521]:
Specify a password to be used for database accounts. Note that the same
password will be used for SYS and SYSTEM. Oracle recommends the use of
different passwords for each database account. This can be done after
initial configuration:
Confirm the password:
Do you want Oracle Database 10g Express Edition to be started on boot (y/n) [y]:
Starting Oracle Net Listener...Done
Configuring Database...Done
Starting Oracle Database 10g Express Edition Instance...Done
Installation Completed Successfully.
To access the Database Home Page go to "http://127.0.0.1:8051/apex"

為 什麼要更動這個 port number?主要的原因是,有很多 HTTP 應用在主機上的 port 80 已經被 web server 使用掉後,第一個想到就是改用 port 8080。這包括 Apache Tomcat,還有很多 Java Servlet Container 都是這樣預設的。所以,除非你的機器已是 production server,不容許安裝一堆奇奇怪怪的東西,否則在 develop system 上 port 8080 已被占用的可能性極高,尤其是 Java server side 應用的開發者。

接下來,我們要離開 Linux ,來開始我們的 Windows 上的工作。既然無法在安裝時就設定,那麼只好手動來更改了。主要要更動的地方有三個。要更改第一個步驟是到 開始功能表 中,找到 Oracle Database 10g Express Edition / 執行 SQL 命令行,打開 SQL*Plus。然後在 SQL*Plus 下如以下輸入,xxxx 代表要輸入的 port number,比如 8888:

SQL*Plus: Release 10.2.0.1.0 - Production Copyright (c) 1982, 2005, Oracle. All rights reserved. SQL> connect system as sysdba;

輸入密碼:

已連線.

SQL> exec dbms_xdb.sethttpport(xxxx);

已順利完成 PL/SQL 程序.

SQL>exit

下達 exit 指令後,就會跳出 SQL*Plus 環境了。接著第二個步驟,先找到你安裝 Oracle XE 的安裝目錄。 預設值是 C:oraclexe。如果你安裝時是接受預設值,那麼打開 檔案總管,找到這個目錄下的 C:oraclexeapporacleproduct10.2.0server 這個目錄,打開來。你會發現在這個目錄下有六個網際網路捷徑:

下 達 指令後,就會跳出 環境了。接著第二個步驟,先找到你安裝 Oracle XE 的安裝目錄。 預設值是 。如果你安裝時是接受預設值,那麼打開 ,找到這個目錄下的 這個目錄,打開來。你會發現在這個目錄下有六個網際網路捷徑:我們要修改的是 Database_homepage 及 Online_help 這兩個網際網路捷徑。當你把滑鼠游標到其中一個時,按下右鍵,打開捷徑選單,選擇 內容。打開 內容對話方塊時;以 Database_homepage 這個網際網路捷徑為例;在 網頁文件 頁籤中,URL 輸入方塊目前是 http://127.0.0.1:8080/apex,請將它改成 http://127.0.0.1:xxxx/apex。這裡的 xxxx 就是剛才你更改的 HTTP port number,比如是 8888。然後按下確定鈕。

同樣的方法修改 Online_help 網際網路捷徑,這樣就大功告成了。這樣你就可以直接使用 開始功能表 中的 Oracle Database 10g Express Edition / 移到資料庫首頁 就可以跳到你的資料庫管理界面了。




Read More......

(2005.10月號-141期)_CanooWebTest實作(上)02

續上一篇文章…






腳本檔1 Jpetstore_WebTestwebtestwebtest.xml

<?xml version="1.0" encoding="Big5"?>

<!DOCTYPE project [

<!ENTITY init SYSTEM "modules/set.init.ent">

<!ENTITY config SYSTEM "modules/set.config.ent">

]>

<project name="WebTest" basedir="." default="all">

&init;

<target name="all" >

<antcall target="home"/>

</target>

<target name="home" >

<testSpec name="進入首頁" >

&config;

<steps>

<invoke

stepid="連結「JPetstore首頁」網址"

url="shop/index.do"/>

</steps>

</testSpec>

</target>

</project>


2 執行腳本檔結果。


3 測試結果報表

4 測試網頁快照

下一步的考量

在本期的內容中筆者透過Maven Plug-in將原本使用ANT建置與執行的WebTest移植到了Maven上,建置者完全無需擔心WebTest需相依什麼jar檔、原先ANT中的build.xml需要多複雜的設定,單獨透過Maven就可進行無縫的整合,並且與ANT一樣,不一定只有Java的專案才會使用Maven,從Maven整合的WebTest來看,就跟JMeter一樣只要是Web Base的系統就能進行測試,並產生數據報表,不知讀者是否注意到,本篇文章中完全沒有談到Java Code

另外,筆者在本期的內容中只作了簡單的功能測試介紹並實作了個再簡單不過的WebTest腳本,至於WebTest更進階的功能、腳本製作上的考量與進行模組化的腳本製作等。將在下一期中與各位討論。(待續)

相關資源

1. http://webtest.canoo.com Canoo WebTest官方網站

2. http://maven-plugins.sourceforge.net/maven-webtest-plugin/

Maven Canoo WebTest Plug-in 官方網站

3.完整的JPetStore功能測試請至RunPC網站下載


Read More......

(2005.10月號-141期)_CanooWebTest實作(上)01

當程式中的元件一步一步接近完成的狀態,開發人員可將這些元件整合成為系統的部份功能,這些功能將會是系統規範Use Case中的一部份,功能測試的目的就在於對這些組件進行驗證並回饋結果。




序言

功能測試是根據軟體的功能設計規格,於系統上進行測試,以證實每個現存的功能是否符合要求,功能測試與單元測試的不同處在於功能測試是從使用者的角度來編寫的。這些測試保證系統能夠按照使用者所期望的那樣去運行,並且注重使用者所感興趣的系統功能。

功能測試屬於黑箱測試的一種,黑箱測試則意味著測試要在軟體的介面處進行。也就是說,這種方法是把測試物件看做一個黑箱子,測試人員完全不考慮程式內部的邏輯結構和內部特性,只依據程式的需求分析規格說明,檢查程式的功能是否符合它的功能說明。

但由於其天生的複雜性,Web應用程式的功能測試常是繁雜且令人生畏的工作,因為其中有太多的使用者行為,若將這些行為複製似乎是很困難的。在這裏所會面臨的是開發人員必須撰寫程式碼來進行各種不同的行為排列組合的驗證。

Java語言進行開發的領域中,進行功能測試,主要都是基於HttpUnit為基礎作延伸,而HttpUnit協助開發人員對於HTTP RequestResponse的程式進行功能單元測試或是功能測試,基本上HttpUnit本身並不是測試工具,而是協助開發人員進行HTTP請求,然後對回應的結果作驗證,並搭配 JUnit來進行測試。

雖然HttpUnit提供了基礎上的支援,從這個基礎當中開發人員可以建構複雜的測試邏輯。但以這種方式進行功能測試卻是有些不切實際的,筆者之前提過功能測試是從使用者的角度來編寫的,在極端軟體製程中也強調功能測試是為並且大部分由客戶所撰寫的,以便從客戶獲得系統狀態的回饋。若進行功能測試的人員還必須了解程式語言並以硬編碼的方式進行測試的話,似乎就有違黑箱測試的意義了。

理想上,功能測試的應用應該以HttpUnit為基礎進行封裝,依據功能測試的需求提供測試介面,例如以XML腳本的方式作為與系統溝通的請求與回應介面,為HttpUnit測試建立XML腳本。腳本定義哪一個網頁以哪一種順序被執行,及對執行結果要如何進行驗證。每當有新的功能完成,便撰寫一個新的腳本。如此一來,測試人員只需了解簡單的腳本規範即可進行複雜的功能測試了。

在本期中筆者將介紹基於上述概念協助開發人員進行功能測試的套件Canoo WebTest

Canoo WebTest簡介

WebTest是由Canoo公司開發並且基礎於HttpUnit之上的開放原始碼測試工具,有興趣的讀者可至http://webtest.canoo.com/manual/WebTestHome.html的官方網站查看最新版本與下載原始碼,到目前為止最新版本為基於HttpUnit 1.6版本開發的為WebTest 1.6版。

1 官方網站提供的下載檔案

檔名

說明

build.zip

完整的建置版本,包含了執行WebTest時所需的jar檔。

doc.zip

完整的說明文件與WebTest自身測試範本。

src.zip

使用ANT建置的原始碼。

selftest.war

WebTest自身測試用範例war檔,可佈署於Servlet Container中進行測試。

當讀者下載相關檔案之後,可依照doc.zip中的文件說明使用ANT進行WebTest的建置與自動化測試,在本期內容中筆者並不打算照官方文件依樣畫葫蘆來做重覆性的說明,在此我將以Maven進行WebTest的整合,協助讀者進行測試並且更加熟悉Maven的使用。

註:關於Maven環境建置,請參考八月份RunPC文章,建置企業專案使用Maven


使用Maven Canoo WebTest Plug-in

MavenApache的專案管理、構建、部署工具,Maven的基本概念就是專案物件模型 (Project Object ModelPOM) 描述專案的各個方面,並且對於Maven不足的功能也能夠使用Plug-in的方式進行擴充。

Maven Canoo WebTest Plug-in是位於Sourceforge.net所提供的Plug-in套件,讀者可自行在http://maven-plugins.sourceforge.net/maven-webtest-plugin網址下載或透過MavenGoal進行下載並安裝,在Console下執行maven plugin:download -DgroupId=maven-plugins -DartifactId=maven-webtest-plugin -Dversion=1.0即可完成Maven Canoo WebTest Plug-in的安裝,參考圖1

接著我們必須建置MavenPOM相關設定並給予WebTest所需的參數。讀者可自行透過MavenGoal執行genapp後再修改成符合WebTest的設定或跟隨筆者自行建立POM以便於更了解Maven

在本次的內容中將繼續以前二期的範例程式JPetStore作為我們的範例,建立如資料結構1的結構, 並撰寫設定1到設定4Maven設定檔project.xmlproject.propertiesWebTest設定檔set.init.entset.config.ent

關於project.xml的結構於之前文章中已有說明,並且在此次的範例中無java程式碼,無需相依其他的jar檔因此在<dependencies><build>標籤中不需任何設定。

project.properties檔中則必須依照WebTest的需求進行設定,參考表2,其他相關Properties請參考http://maven-plugins.sourceforge.net/maven-webtest-plugin/properties.html 的說明。

set.init.ent檔中眼尖的讀者應該可以發現< taskdef >這不是ANT的定義客製化標籤嗎?沒錯,事實上WebTest的測試腳本是基於ANT自定標籤技術的實現,在此只須依參考設定3撰寫,在等會的實作中將會以XML實體檔的方式作引入。

set.config.ent檔與set.init.ent相同,都是在下一步的實作中作引入的設定,不同的是< config >標籤除了與先前的project.properties設定對應之外還可以加入Http header的相關參數,這在針對header進行特別處理的網頁測試上相當有用,如設定4註解處。

2 WebTest Plug-in 須設定的Properties

屬性

說明

maven.webtest.config.host

進行webtest的測試主機位址,預設為localhost

maven.webtest.config.port

進行webtest的測試主機通訊埠,預設為80port

maven.webtest.config.protocol

進行webtest的通訊協定,例如httphttps,預設為http

maven.webtest.config.basepath

進行webtestcontext路徑,在本例中使用jpetstore

maven.webtest.src

webtest測試腳本檔放置路徑,預設為${basedir}/webtest,在本例中使用預設路徑,因此在project.properties檔中將其註解。


1 Maven Canoo WebTest Plug-in安裝。

資料結構1

Jpetstore_WebTest

+--webtest 放置webtest腳本檔資料夾

| +--modules 測試用模組放置資料夾

| +--set.init.ent webtest初始化設定

| +--set.config.ent webtest測試網站設定

+--project.properties 專案屬性檔

+--project.xml Project Object Model,POM

設定1 project.xml

<?xml version="1.0" encoding="UTF-8"?>

<project>

<pomVersion>3</pomVersion>

<groupId>jpetstore</groupId>

<id>jpetstore</id>

<name>JPetStore Application</name>

<currentVersion>1.0</currentVersion>

<dependencies></dependencies>

<build></build>

</project>

設定2 project.properties

# -------------------------------------------------------------------

# for Canoo WebTest plugin.

# -------------------------------------------------------------------

# Source directory of Canoo Webtest scripts

#maven.webtest.src=${basedir}/src/webtest

# Settings for Canoo Webtest Configuration

maven.webtest.config.host=localhost

maven.webtest.config.port=8080

maven.webtest.config.protocol=http

maven.webtest.config.basepath=jpetstore

設定3 set.init.ent

<taskdef file="${webtest.home}/webtestTaskdefs.properties">

<classpath>

<fileset dir="${webtest.home}">

<include name="lib/*.jar"/>

<include name="lib/base/*.jar"/>

</fileset>

<pathelement path="${webtest.home}/lib"/>

</classpath>

</taskdef>

設定4 set.config.ent

<config

host="${host}"

port="${port}"

protocol="${protocol}"

basepath="${basepath}"

summary="${summary}"

saveresponse="${saveresponse}"

resultpath="${resultpath}"

resultfile="${resultfile}"

haltonfailure="${haltonfailure}"

haltonerror="${haltonerror}"

showhtmlparseroutput="${showhtmlparseroutput}"

autorefresh="${autorefresh}"

>

<!--

<header name="user-agent" value="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; MyIE2)"/>

<header name="accept-encoding" value="gzip, deflate"/>

<header name="accept-language" value="zh-tw,en-us;q=0.7,zh-cn;q=0.3"/>

<header name="connection" value="Keep-Alive"/>

<header name="locale" value="zh_TW"/>

-->

</config>

當完成設定後,可以開始寫第一個腳本檔了,參考腳本檔1,從該檔中不難發現,這不就是ANTXML格式嗎!這就更加印證了WebTest的測試腳本是基於ANT自定標籤技術的實現,並且更能熟悉Maven的好處,Maven可透過Plug-in進行不同技術的整合,包括ANT

在腳本檔1webtest.xml中將set.init.ent與set.config.ent透過XML使用ENTITY的方式進行引入,並在<project>標籤一開始就執行了&init;,將set.init.ent的自定標籤庫導入,使得在之後的<target>標籤中能使用WebTest的自定標籤進行功能測試腳本實作。在<target name="home">標籤中包含了<testSpec>WebTest 標籤,testSpec中引入了&config;進行set.config.ent檔的設定,參考設定2可知,網頁起始路徑將會是http://localhost:8080/jpetstore/ <invoke >標籤中得知,這個簡易的腳本將測試http://localhost:8080/jpetstore/ shop/index.do 是否可正常的連結。

完成第腳本檔1之後啟動JPetStore的HSQLDB資料庫與Tomcat並且在Console下執行maven webtest,若設定無誤Maven執行結果將如圖2所示。當WebTest測試完成後將會在[Jpetstore_WebTesttargetdocsmaven-webtest-report.html]建立如圖3的測試報告檔,並且報告檔中將可得知其測試結果總表(Result Summary)、伺服端回應時間數據圖(Server Roundtrip Timing Profile)、測試情節概要(Test Scenario Overview)等測試結果訊息供測試人員參考。不但如此在每一個<invoke >標籤執行後的Resulting page上皆記錄了網頁快照可供連結進行確認是否正確執行。

Read More......