<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    qileilove

    blog已經(jīng)轉(zhuǎn)移至github,大家請訪問 http://qaseven.github.io/

    LoadRunner 11簡單使用

      開始菜單--》HP LoadRunner-->applications--->virtual user Generator
      1>新建--》類別 (選擇協(xié)議):常用的web項目用Web(HTTP/HTML),后臺運行的服務(wù),選擇java下的java vuser,編寫java代碼;
      2>對于web,需要設(shè)置訪問的URL地址,錄制到的操作:init  action  end,默認是action,
      2.1確定后會彈出瀏覽器并打開剛設(shè)置的URL,而且彈出了錄制工具條,此時已經(jīng)進入了錄制過程;
      2.2錄制完一個操作(比如錄制輸入用戶名、密碼后的登錄操作),可以在那個錄制的工具條上新建一個新的;
      2.3如果要停止錄制,先關(guān)閉瀏覽器,然后點擊錄制工具條上的停止按鈕,此時腳本文件就有了代碼;
      2.4修改腳本,比如錄制的登錄過程,可能需要登錄多個用戶,那就找到腳本里設(shè)置登錄用戶名(可以查剛才錄制時登錄的用戶名)的地方,
      選中該用戶名,右鍵--》替換為參數(shù)--》設(shè)置參數(shù)名稱--》點擊屬性按鈕-->創(chuàng)建表--》添加行--》輸入被測試系統(tǒng)已有的測試用戶名;
      對話框下面的“更新值的時間”,有三個選擇,請根據(jù)具體測試情景選擇,然后“關(guān)閉”--》“確定”;
      2.5此時剛才的用戶名會變成參數(shù)形式,如果有多個地方需要用這個參數(shù)替換,則找到這些地方選中,右鍵---》“使用現(xiàn)有參數(shù)”,找到要替換的參數(shù);
      2.6點擊工具欄的“運行”按鈕,會彈出一個結(jié)果概要的窗口,顯示腳本運行是否通過或者報錯;
      2.7給腳本設(shè)置具體的場景:
      VUGen  工具---》創(chuàng)建controller場景---》設(shè)置load Generator(loadrunner所在IP)彈出controller界面:最下方分出 “設(shè)計”和“運行”兩種選項卡;
      運行前的配置操作在“設(shè)計”選項卡操作,常用的如下:
      1》場景組里可以設(shè)置多個組,組里的Load Generator可以是當(dāng)前l(fā)oadrunner或另外一個loadrunner 客戶端(可以只安裝load Generator),相當(dāng)于是負載,安裝了controller的lr可以作為中心,配置它的客戶端方式為:
      controller-->場景-->Load Generator-->添加(別的loadrunner 客戶端)--》連接;
      2》場景計劃面板,如果計劃方式選擇的是場景,那么下面的“全局計劃”的設(shè)置是對所有組的,如果計劃方式是組,那么下面是針對各組的設(shè)置計劃;
      3》“全局計劃”面板,可以選中某一個,如“啟動Vuser”雙擊,設(shè)置并發(fā)user數(shù),是同時運行還是隔多長時間運行一次;
      2.8設(shè)置完后,點最下方的“運行”選項卡,點右上方的“開始場景”運行,運行結(jié)束后該按鈕由置灰變可點;
      2.9右邊的“場景狀態(tài)”會顯示運行情況,具體的分析報告可點菜單“工具”--》“analysis”彈出具體的分析面板,右邊的概要報告會顯示大概的指標;
      3.0如果左邊的會話瀏覽器里顯示的圖不夠,可以點右鍵--》添加新項--->添加新圖;
      3、如果新建后選擇的類別是 java vuser
      3.1配置運行java腳本需要的java環(huán)境:Vuser->運行時設(shè)置-->java環(huán)境設(shè)置-->java VM 勾選“使用指定JDK”,并把jdk(lr11建議用32位的jdk)的bin上一層路徑復(fù)制到JDK后,點確定;
      3.2導(dǎo)入java環(huán)境的jar包:Vuser->運行時設(shè)置-->java環(huán)境設(shè)置-->Classpath,點添加jar的按鈕,選擇指定的jdk下的lib下的dt.jar和tools.jar導(dǎo)入;
      3.3導(dǎo)入編寫的java腳本需要依賴的jar:Vuser->運行時設(shè)置-->java環(huán)境設(shè)置-->Classpath,點添加jar的按鈕,將編寫腳本依賴的工程里的Jar包導(dǎo)入,點確定;
      3.4此時可以編寫java腳本,記住import類,和eclipse的寫法一致就能找到類;
      3.5運行腳本,看能否運行通過;
      某些配置的具體操作方式:
      1、VUGen  工具--》錄制選項--》HTTP屬性 --》高級     (設(shè)置字符集)
      2、腳本設(shè)置:
      2.1、VUGen  工具--》錄制選項--》常規(guī)--》錄制    (默認web使用html)
      3、運行時的設(shè)置:
      VUGen  VUSER-->運行時設(shè)置--》運行邏輯  (設(shè)置運行的迭代次數(shù))
      VUGen  VUSER-->運行時設(shè)置--》常規(guī)--》思考時間--》忽略思考時間  (將錄制操作過程中的停頓忽略)
      4、如果需要操作到達某個點時需要等待其他用戶都到達這個點再同時向下執(zhí)行,在整理代碼時,可以在這個點上執(zhí)行“插入--》集合”;
      5、當(dāng)需要請求的用戶來自不同IP時,需要設(shè)置Controller的“場景”--》“啟用IP欺騙器”;

    posted @ 2014-04-16 11:21 順其自然EVO 閱讀(2220) | 評論 (0)編輯 收藏

    LoadRunner 11簡單使用

      開始菜單--》HP LoadRunner-->applications--->virtual user Generator
      1>新建--》類別 (選擇協(xié)議):常用的web項目用Web(HTTP/HTML),后臺運行的服務(wù),選擇java下的java vuser,編寫java代碼;
      2>對于web,需要設(shè)置訪問的URL地址,錄制到的操作:init  action  end,默認是action,
      2.1確定后會彈出瀏覽器并打開剛設(shè)置的URL,而且彈出了錄制工具條,此時已經(jīng)進入了錄制過程;
      2.2錄制完一個操作(比如錄制輸入用戶名、密碼后的登錄操作),可以在那個錄制的工具條上新建一個新的;
      2.3如果要停止錄制,先關(guān)閉瀏覽器,然后點擊錄制工具條上的停止按鈕,此時腳本文件就有了代碼;
      2.4修改腳本,比如錄制的登錄過程,可能需要登錄多個用戶,那就找到腳本里設(shè)置登錄用戶名(可以查剛才錄制時登錄的用戶名)的地方,
      選中該用戶名,右鍵--》替換為參數(shù)--》設(shè)置參數(shù)名稱--》點擊屬性按鈕-->創(chuàng)建表--》添加行--》輸入被測試系統(tǒng)已有的測試用戶名;
      對話框下面的“更新值的時間”,有三個選擇,請根據(jù)具體測試情景選擇,然后“關(guān)閉”--》“確定”;
      2.5此時剛才的用戶名會變成參數(shù)形式,如果有多個地方需要用這個參數(shù)替換,則找到這些地方選中,右鍵---》“使用現(xiàn)有參數(shù)”,找到要替換的參數(shù);
      2.6點擊工具欄的“運行”按鈕,會彈出一個結(jié)果概要的窗口,顯示腳本運行是否通過或者報錯;
      2.7給腳本設(shè)置具體的場景:
      VUGen  工具---》創(chuàng)建controller場景---》設(shè)置load Generator(loadrunner所在IP)彈出controller界面:最下方分出 “設(shè)計”和“運行”兩種選項卡;
      運行前的配置操作在“設(shè)計”選項卡操作,常用的如下:
      1》場景組里可以設(shè)置多個組,組里的Load Generator可以是當(dāng)前l(fā)oadrunner或另外一個loadrunner 客戶端(可以只安裝load Generator),相當(dāng)于是負載,安裝了controller的lr可以作為中心,配置它的客戶端方式為:
      controller-->場景-->Load Generator-->添加(別的loadrunner 客戶端)--》連接;
      2》場景計劃面板,如果計劃方式選擇的是場景,那么下面的“全局計劃”的設(shè)置是對所有組的,如果計劃方式是組,那么下面是針對各組的設(shè)置計劃;
      3》“全局計劃”面板,可以選中某一個,如“啟動Vuser”雙擊,設(shè)置并發(fā)user數(shù),是同時運行還是隔多長時間運行一次;
      2.8設(shè)置完后,點最下方的“運行”選項卡,點右上方的“開始場景”運行,運行結(jié)束后該按鈕由置灰變可點;
      2.9右邊的“場景狀態(tài)”會顯示運行情況,具體的分析報告可點菜單“工具”--》“analysis”彈出具體的分析面板,右邊的概要報告會顯示大概的指標;
      3.0如果左邊的會話瀏覽器里顯示的圖不夠,可以點右鍵--》添加新項--->添加新圖;
      3、如果新建后選擇的類別是 java vuser
      3.1配置運行java腳本需要的java環(huán)境:Vuser->運行時設(shè)置-->java環(huán)境設(shè)置-->java VM 勾選“使用指定JDK”,并把jdk(lr11建議用32位的jdk)的bin上一層路徑復(fù)制到JDK后,點確定;
      3.2導(dǎo)入java環(huán)境的jar包:Vuser->運行時設(shè)置-->java環(huán)境設(shè)置-->Classpath,點添加jar的按鈕,選擇指定的jdk下的lib下的dt.jar和tools.jar導(dǎo)入;
      3.3導(dǎo)入編寫的java腳本需要依賴的jar:Vuser->運行時設(shè)置-->java環(huán)境設(shè)置-->Classpath,點添加jar的按鈕,將編寫腳本依賴的工程里的Jar包導(dǎo)入,點確定;
      3.4此時可以編寫java腳本,記住import類,和eclipse的寫法一致就能找到類;
      3.5運行腳本,看能否運行通過;
      某些配置的具體操作方式:
      1、VUGen  工具--》錄制選項--》HTTP屬性 --》高級     (設(shè)置字符集)
      2、腳本設(shè)置:
      2.1、VUGen  工具--》錄制選項--》常規(guī)--》錄制    (默認web使用html)
      3、運行時的設(shè)置:
      VUGen  VUSER-->運行時設(shè)置--》運行邏輯  (設(shè)置運行的迭代次數(shù))
      VUGen  VUSER-->運行時設(shè)置--》常規(guī)--》思考時間--》忽略思考時間  (將錄制操作過程中的停頓忽略)
      4、如果需要操作到達某個點時需要等待其他用戶都到達這個點再同時向下執(zhí)行,在整理代碼時,可以在這個點上執(zhí)行“插入--》集合”;
      5、當(dāng)需要請求的用戶來自不同IP時,需要設(shè)置Controller的“場景”--》“啟用IP欺騙器”;

    posted @ 2014-04-16 11:21 順其自然EVO 閱讀(195) | 評論 (0)編輯 收藏

    分層設(shè)計與分層測試

     分層是復(fù)雜軟件系統(tǒng)常見的設(shè)計思路。比如互聯(lián)網(wǎng)的七層/五層模型,Android系統(tǒng)的APP/FWK/JNI/Kernel等,都是通過分層、解耦,達到簡化問題,易于維護,便于擴展的效果。
      傳統(tǒng)的黑盒測試主要關(guān)注客戶需求,白盒測試比較靈活,但實際應(yīng)用中以驗證編碼實現(xiàn)為主,兩者都忽略了設(shè)計這個開發(fā)過程中承上啟下的環(huán)節(jié)。分層測試的核心思想是:針對有明確分層設(shè)計的軟件系統(tǒng),采用白盒測試的技術(shù),在層與層之間驗證接口的正確性。分層測試以調(diào)用接口驅(qū)動被測系統(tǒng),盡量不依賴于打樁(具體原因后面會提到)。去年下半年開始我們在Android測試中嘗試分層測試,取得了很好的效果。
      1、精準。我們都知道,離問題產(chǎn)生的地方越近,就越容易觸發(fā)問題。如果問題發(fā)生在底層,以白盒測試的方法,很難精確打擊,特別是一些復(fù)雜場景或異常流程,可能無法構(gòu)造。而分層測試的切入點就是層與層之間的接口,從機制上更接近出問題的地方,因此也更容易命中目標。
      2、低成本。這個優(yōu)勢源于可測試性。舉例來說:我們要測試Android系統(tǒng)下?lián)芴柕男阅埽诤性趺礈y呢?測試人員需要打開秒表,同時進行撥號的操作,并觀測電話是否撥通。操作麻煩不說,誤差也很大。如果用分層測試的方式,只要提供撥號和檢查是否撥通兩個對外開放的接口,通過用例腳本調(diào)用,并記錄兩者的時間,就可以方便準確地得到耗時。更進一步,我們還可以在不同層次的接口調(diào)用時均記錄下時間,在腳本中直接對各個環(huán)節(jié)的耗時進行分析,從而自動分析流程的瓶頸,找到影響性能的關(guān)鍵環(huán)節(jié)。
      再回過頭來看前面提到的盡量避免打樁的建議,也是考慮到成本。打樁是白盒測試最困難的部分,特別是涉及到復(fù)雜的數(shù)據(jù)類型或者系統(tǒng)內(nèi)部狀態(tài)。因此很多開發(fā)同事不愿意使用UT。分層測試重驅(qū)動弱打樁,測試腳本主要還是運行在真實的測試環(huán)境中,這樣就避免了打樁上的投入,也更接近開發(fā)的調(diào)試手段。
      3、高效。這里是指用例執(zhí)行速度快。首先自動化測試的速度就明顯優(yōu)于手工測試,基于API調(diào)用的自動化又比UI自動化要快,分層測試的高效就建立在API調(diào)用高效的基礎(chǔ)上。從我們收集的數(shù)據(jù)來看,相同的用例,手工執(zhí)行的耗時平均在5-8分鐘,UI自動化一般也需要1-2分鐘,而分層測試通常10-20秒就完成了,效率提升達10倍。
      4、易定位。易定位其實是和精準對應(yīng)的。在用例設(shè)計的時候就考慮到用例所針對的代碼,一旦出現(xiàn)問題,自然就容易定位了。
      5、穩(wěn)定。客戶需求是易變的,內(nèi)部實現(xiàn)也是易變的,但是層與層之間的接口是不同開發(fā)人員之間的約定,通常會盡量保持穩(wěn)定。這里也有一組數(shù)據(jù):從Android 4.2到Android 4.4,我們設(shè)計的JNI層用例變更不到10%,而針對APP界面開發(fā)的用例,變更率高達40%。
      6、盡早測試。盡早測試是敏捷所提倡的,目的是把問題攔截在前端,降低問題修復(fù)成本。由于分層測試不依賴于完整系統(tǒng),可以通過直接調(diào)用底層接口進行測試,就不需要等到整個系統(tǒng)開發(fā)完成。其實分層測試的思想和自底向上的系統(tǒng)開發(fā)模式也是不謀而合的。
      介紹了這么多分層測試的優(yōu)勢,那么它是萬能的銀彈嗎?首先,分層測試不是端到端的測試,接口之上的部分無法覆蓋,因此無法替代驗收測試。另外,分層測試依賴于被測系統(tǒng)良好的分層設(shè)計,如果被測系統(tǒng)的結(jié)構(gòu)不清晰,耦合嚴重,分層測試就不合適了。

    posted @ 2014-04-16 11:01 順其自然EVO 閱讀(591) | 評論 (0)編輯 收藏

    談 Dojo 應(yīng)用的 UI 自動化測試

    本文首先列舉了 Dojo 應(yīng)用 UI 自動化測試所面臨的挑戰(zhàn),進而引出設(shè)計 Dojo 應(yīng)用 UI 自動化測試的框架時應(yīng)考慮的一些原則。對于正從事 Web UI 自動化測試工作的讀者(即便所測試的應(yīng)用不是 Dojo 應(yīng)用)或者對這方面感興趣的讀者,本文都有一定的參考價值。
      隨著富 Internet 應(yīng)用(RIA)的不斷興起,各種 JavaScript 開發(fā)工具包的功能也在不斷增強,Dojo 正是其中的佼佼者。Dojo 提供了一套完整的開發(fā)解決方案,包括核心的 JavaScript 庫、簡單易用的小部件(Widget)等。當(dāng)越來越多的企業(yè) Web 應(yīng)用選擇 Dojo 作為前端技術(shù)框架的時候,作為測試人員,我們便需要考慮如何有效地進行自動化測試開發(fā)與實施。Dojo 是一個 Web 前端技術(shù)框架,所以這里所說的自動化測試,具體是指 Web UI 自動化測試,更進一步說是 Web 2.0 UI 自動化測試。
      考慮到 Web UI 的特性以及 Web UI 自動化測試的投入產(chǎn)出比(ROI),關(guān)于是否應(yīng)該進行 Web UI 自動化測試,測試領(lǐng)域存在不同的觀點。我個人認為還是有必要的。不過這不是本文要討論的重點。決定 Web UI 自動化測試成敗(或者說收效)的因素有很多,技術(shù)框架的選取和設(shè)計是其中之一,個人認為也是比較重要的一個因素。本文將從 Dojo 應(yīng)用 UI 自動化測試面臨的諸多挑戰(zhàn)談起,進而討論針對 Dojo 應(yīng)用 UI 自動化測試的框架適用的設(shè)計原則。
      雖然本文探討的主題是 Dojo 應(yīng)用的 UI 自動化測試,但不少內(nèi)容也適合其他的 Web 2.0 應(yīng)用。希望讀者朋友或多或少都能從中獲益。
      Dojo 是什么?
      Dojo 是一個 JavaScript 實現(xiàn)的開源 DHTML 工具包。它是在幾個項目捐助基礎(chǔ)上建立起來的(nWidgets,f(m),Burstlib) 。 Dojo 的最初目標是解決開發(fā) DHTML 應(yīng)用程序遇到的一些長期存在的歷史問題,現(xiàn)在,Dojo 已經(jīng)成為了開發(fā) RIA 應(yīng)用程序的利器:
      Dojo 讓您更容易地為 Web 頁面添加動態(tài)能力,您也可以在其它支持 JavaScript 的環(huán)境中使用 Dojo ;
      利用 Dojo 提供的組件,您可以提升 Web 應(yīng)用程序的可用性和交互能力;
      Dojo 很大程度上屏蔽了瀏覽器之間的差異性,因此,您可以不用擔(dān)心 Web 頁面是否在某些瀏覽器中可用;
      通過 Dojo 提供的工具,您還可以為代碼編寫命令行式的單元測試代碼。
      Dojo 的打包工具可以幫助您優(yōu)化 JavaScript 代碼,并且只生成部署應(yīng)用程序所需的最小 Dojo 包集合。
      Dojo 應(yīng)用 UI 自動化測試面臨的挑戰(zhàn)
      Dojo 應(yīng)用 UI 自動化測試面臨的挑戰(zhàn)可以歸為兩類:開發(fā)階段的挑戰(zhàn)和維護階段的挑戰(zhàn)。
      開發(fā)階段的挑戰(zhàn):
      異步請求的處理
      元素定位
      Dojo 復(fù)雜性
      產(chǎn)品復(fù)雜性
      維護階段的挑戰(zhàn):
      頻繁的 UI 更改
      Dojo 升級
      下面,我們具體講解每一種挑戰(zhàn)。為了后文講解設(shè)計原則時能方便的對應(yīng)到這些挑戰(zhàn),我們用英文字母標記每個挑戰(zhàn)。
      A. 異步請求的處理
      在傳統(tǒng)的 Web 應(yīng)用中,用戶每點擊頁面上的超鏈,瀏覽器就會向服務(wù)器發(fā)出一個請求,等待服務(wù)器做出響應(yīng),然后返回一個完整新網(wǎng)頁,但在大多數(shù)情況下用戶不得不忍受頁面閃爍和長時間的等待。為了解決傳統(tǒng)的 Web 應(yīng)用中出現(xiàn)的問題,出現(xiàn)了 Ajax。通過使用 Ajax 頁面和應(yīng)用向服務(wù)器請求它們真正需要的東西,也就是頁面中需要修改的部分,服務(wù)器就提供哪部分,這使得通信量更少,更新更少,用戶等待頁面刷新更短,用戶更加滿意。
      但是,Ajax 的到來對 Web UI 自動化測試卻未必是好消息。Web UI 自動化測試框架的執(zhí)行方式類似于一個“隊列”:用戶定義了一系列的頁面操作和驗證,之后 Web UI 自動測試框架把它們按順序一一執(zhí)行。在傳統(tǒng) Web 應(yīng)用中,由于每次向服務(wù)器端發(fā)起請求都會導(dǎo)致頁面跳轉(zhuǎn),Web UI 自動化測試框架能很容易地判斷出合適該執(zhí)行下一個動作。 但是,Ajax 的行為是異步的,也就是說,用戶的操作跟服務(wù)器端的處理現(xiàn)可以是并行的,不存在嚴格的順序。起初,這給 Web UI 自動化測試框架的開發(fā)者帶來了困擾,而且很長一段時間里這個問題都沒有被很好的解決。
      起初,Web UI 自動化測試開發(fā)人員主要有兩種解決方案:硬編碼等待時間和基于條件的等待。
      硬編碼等待時間: 這種方式是指在代碼中指定一個靜態(tài)等待時間,比如指定等待 30 秒后執(zhí)行下一個操作。通常,這種數(shù)值的設(shè)置來源于經(jīng)驗。可以想象,如果這個等待時間比實際等待時間小,自動化腳本執(zhí)行就會失敗。而且,不幸的是,這樣情況的確經(jīng)常發(fā)生。隨著測試環(huán)境的變化,實際需要的等待時間事實上是一個變量。以下幾個因素都有可能導(dǎo)致它發(fā)生變化:
      測試服務(wù)器在遠程還是本地:毫無以為,由于網(wǎng)絡(luò)的影響,服務(wù)器如果在遠程,等待時間就會增加。
      使用的瀏覽器: 瀏覽器 JavaScript 引擎的執(zhí)行速度對等待時間也有影響。根據(jù)經(jīng)驗, Firefox 和 Chrome 都比 IE 要快。因此,如果用的是 IE,等待時間也會增加。 測試運行時的網(wǎng)絡(luò)環(huán)境:如果測試時的網(wǎng)速較慢,等待時間會增加。
      測試服務(wù)器的負載:測試服務(wù)器可能是獨占也可能是共享的。如果自動化測試執(zhí)行時的服務(wù)器負載較大,也會導(dǎo)致等待時間增加。
      對于上述硬編碼等待時間的問題,Web UI 自動化測試開發(fā)人員一般有如下對策。
      盡量將等待時間設(shè)置的大一些。這樣做存在一些問題。一來未必能保證在任何情況下該值都足夠大;二來它意味著無論服務(wù)器在本地還是遠程瀏覽器是快是慢,執(zhí)行時間都一樣,這對于服務(wù)器在本地以及瀏覽器比較快的測試環(huán)境是很大的時間成本浪費。
      設(shè)置放大因子。這種方法是在編碼的時候給等待時間乘上一個因子。這個因子或者是硬編碼的,比如定義在一個參數(shù)文件中。當(dāng)測試環(huán)境比較好的時候,設(shè)置小一點;測試環(huán)境比較差的時候,設(shè)置大一點。 高級一些的,可以動態(tài)地設(shè)置這個因子。比如,可以把某一個操作的執(zhí)行時間作為計算該因子數(shù)值的參照。這個方法使情況得到了部分改善,但是仍然不能保持其執(zhí)行的穩(wěn)定性。
      基于條件的等待: 由于硬編碼等待時間方式的不穩(wěn)定性,Web UI 自動化測試框架開始支持“基于條件的等待”。這種方式是采用“輪詢”的機制判斷是否可以開始執(zhí)行一個操作。假設(shè),當(dāng)前要執(zhí)行的操作是一個按鈕點擊動作。這個按鈕默認是被禁用的,當(dāng)頁面從服務(wù)器端加載了數(shù)據(jù)之后這個按鈕才被啟用。因此,如果要保證這個操作成功,就需要“輪詢”這個按鈕的狀態(tài) – 直到發(fā)現(xiàn)它被啟用了,才執(zhí)行點擊操作。 如果由于存在 bug 按鈕一直不啟用怎么辦?所以,基于條件的等待的方法需要設(shè)置“超時時間”。如果超過這個時間按鈕還沒有啟用,就認為這個測試用例失敗了。所以,大家發(fā)現(xiàn)了,這個超時時間的設(shè)置其實還是個“硬編碼等待時間”,所以某種程度上,這種方式仍存在硬編碼等待時間方式的弊端。這種方式的另外一弊端是它帶來了額外的編碼成本,并且自動化測試代碼中可能充斥了許多條件判斷代碼,而它們本身不完成我們的“業(yè)務(wù)”目標,僅是輔助代碼。
      B. 元素定位
      一般的 Web UI 自動化測試編碼無非包含這樣幾個步驟:定位及獲取元素,執(zhí)行操作以及驗證結(jié)果。而且,通常 Web UI 自動化測試開發(fā)人員在元素定位和獲取這個步驟上花費相當(dāng)多的時間。大多數(shù) Web UI 自動化測試開發(fā)人員希望所需獲得的元素能有一個靜態(tài) id 屬性。根據(jù)規(guī)范,id 屬性的值在 DOM 樹中必須是唯一的,因此通過 id 屬性就可以很簡單并且準確地定位元素。但是,這樣的需求常常不是產(chǎn)品的需求,而只是為了滿足 Web UI 自動化測試代碼開發(fā)的簡便。所以,對于產(chǎn)品開發(fā)人員來說,給每個需要在 Web UI 自動化測試中使用到的元素增加靜態(tài) id 屬性不是高優(yōu)先級的工作。而且,從技術(shù)角度上講,有些 Dojo 應(yīng)用中的元素也無法設(shè)置靜態(tài) id 屬性。
      對于 Dojo 應(yīng)用,情況又復(fù)雜了一些。圖 1 展示的是一個 Dojo 按鈕小部件在 Firebug 中呈現(xiàn)的 DOM 結(jié)構(gòu)。最外層的 SPAN 元素上有一個 widgetid 屬性,內(nèi)部的 SPAN 元素上定義了 id 屬性,共同點是它們都是由一個前綴和一個動態(tài)的數(shù)字構(gòu)成的。這個數(shù)字是由運行時該 Dojo 小部件在整個 DOM 樹上的位置決定的,索引從 0 開始。因此可知,圖 1 中的按鈕小部件是整個 DOM 樹上的第二個按鈕。Widgetid 是每個 Dojo 小部件都有的屬性,如沒有特別指定的話,它就是如圖中所示的動態(tài)結(jié)構(gòu)。
      所以,如何通過這種動態(tài)格式的 id 和 widgetid 定位獲取頁面中的元素成為另一個 Dojo 應(yīng)用 UI 自動化測試開發(fā)的挑戰(zhàn)。
      
    圖 1. Dojo 按鈕小部件
      C. Dojo 復(fù)雜性
      讀者不要誤會,這里說的“Dojo 復(fù)雜性”不是說 Dojo 使用起來很復(fù)雜,而是說 Dojo 應(yīng)用最后生成的頁面 DOM 結(jié)構(gòu)比較復(fù)雜。如圖 1 所示,原本用一個 INPUT 元素實現(xiàn)的按鈕,現(xiàn)在嵌套了四層 SPAN 元素。 所以,Dojo 小部件已不再是一個簡單的 HTML 元素,而是由諸多 HTML 元素組合而成的。Dojo 按鈕小部件只是一個簡單的例子,對于像表格、日歷之類的 Dojo 小部件,它們的結(jié)構(gòu)更加復(fù)雜。針對某個 Dojo 小部件的操作也不再像操作普通的 HMTL 元素那樣簡單(調(diào)用某個 JavaScript 方法就可以實現(xiàn)),而是要具體定位響應(yīng)事件(比如點擊事件)的 Dojo 小部件的內(nèi)部對應(yīng)元素,然后觸發(fā)具體的事件。
      多數(shù)的 Web UI 自動化測試框架只能處理基本的 HTML 元素。這是合理的,因為框架開發(fā)者不知道最終的自動化測試開發(fā)者使用什么樣的前段框架,因而只能提供最基本的“小磚塊”。如果具體應(yīng)用的自動化測試開發(fā)者有任何需求,可以在其之上進行二次開發(fā)。
      對于 Dojo 應(yīng)用的 UI 自動化測試開發(fā)者來說,可以選擇直接定位和操作 Dojo 小部件內(nèi)部元素的方法。但是,這樣做的弊端很明顯 – 缺乏重用性。 因此,應(yīng)該將 Dojo 小部件作為最小操作單元。如何將 Dojo 小部件模塊化成為了又一個挑戰(zhàn)。
      D. 產(chǎn)品復(fù)雜性
      產(chǎn)品復(fù)雜性包含兩層意思。
      一是指產(chǎn)品本身頁面層次多,界面元素多以及功能邏輯復(fù)雜。Web UI 自動化測試開發(fā)過程中,編寫定位元素的代碼通常占據(jù)很大一部分時間,編寫這部分代碼的工作量直接受頁面元素多少的影響。功能復(fù)雜度一般不太會直線性增加編碼工作量,但是有可能會增加調(diào)試的工作量。
      二是指產(chǎn)品頁面 DOM 結(jié)構(gòu)復(fù)雜。Web 2.0 應(yīng)用的開發(fā)模式與傳統(tǒng) Web 應(yīng)用的開發(fā)模式有很大的不同。傳統(tǒng) Web 應(yīng)用開發(fā)基本上是一個頁面對應(yīng)一個物理的程序文件(比如,.jsp 文件)。而 Web 2.0 應(yīng)用的開發(fā)通常是整個應(yīng)用只有少數(shù)幾個物理的程序文件,頁面的跳轉(zhuǎn)和呈現(xiàn)通過 JavaScript 更新 DOM 樹結(jié)構(gòu)完成。所以,在瀏覽器中的跳轉(zhuǎn)頁面實際上往往只是 DOM 樹結(jié)構(gòu)被更新了。這樣,就有可能帶來這樣一個問題:DOM 樹上同時存在多個頁面的 DOM 子節(jié)點。如果其他頁面有與當(dāng)前要定位的元素類似的元素,就很容易出現(xiàn)“錯誤定位”。
      如何能在產(chǎn)品變得越來越復(fù)雜的同時,盡可能的減少開發(fā)工作量,也是一個 Dojo 應(yīng)用 UI 自動化測試開發(fā)者要解決的問題。
      E. 頻繁的 UI 更改
      頻繁的 UI 更改在“敏捷開發(fā)”大行其道之后成為了又一個讓 Web UI 自動化測試開發(fā)者頭痛的問題。迭代中的產(chǎn)品 UI 經(jīng)常隨著客戶的反饋不斷地修改,于是自動化測試代碼需要跟著更新。由此帶來的 Web UI 自動化測試腳本巨大的維護工作量也成為了很多人反對進行 Web UI 自動化測試的重要原因之一。
      難道,因此就放棄 Web UI 自動化測試嗎?我認為,作為 Web UI 自動化測試開發(fā)者需要考慮的應(yīng)該是:在這樣的現(xiàn)實之下,如何能夠最小化頻繁的 UI 更改帶來的代碼維護工作量。從經(jīng)驗來看,并非 Web UI 上的任何一點點更改都會導(dǎo)致自動化測試代碼的修改。這個問題的解決極大程度上依賴于測試框架適應(yīng) DOM 結(jié)構(gòu)變化的能力以及元素定位時所使用的方法。
      F. Dojo 升級
      Dojo 升級有可能會引發(fā) Dojo 小部件 DOM 結(jié)構(gòu)的變化,繼而帶來自動化測試代碼的維護工作量增加。盡管根據(jù)經(jīng)驗,這一點的影響不是很顯著,因為目前一些常見的 Dojo 小部件(比如按鈕輸入框之類)都已經(jīng)十分成熟,但是還是需要考慮。如果一個小部件的 DOM 結(jié)構(gòu)發(fā)生了變化,如何能夠最小化對自動化測試代碼的影響?這是 Dojo 應(yīng)用 UI 自動化測試開發(fā)者要考慮的問題。
     Dojo 應(yīng)用 UI 自動化測試框架挑選(設(shè)計)原則
      講解完了所有的挑戰(zhàn),讓我們來看看當(dāng)我們要設(shè)計或者選取一個 Dojo 應(yīng)用 UI 自動化測試框架時需要考慮的因素和原則。
      概括起來,主要有以下八大原則。括號內(nèi)是該原則所對應(yīng)解決的挑戰(zhàn)。
      隱式等待(A)
      位置關(guān)系操作(B,E)
      封裝 Dojo 小部件 (C,D,F(xiàn))
      IBM 框架 (E)
      代碼生成(D)
      測試數(shù)據(jù)的管理(D)
      錄制與編碼 (D)
      接下來,我們一一來講解每一條原則。為了幫助讀者理解,講解過程中會引用內(nèi)部自行開發(fā)的 Dojo 應(yīng)用 UI 自動化測試框架 Water Bear 的部分內(nèi)容。
      隱式等待
      挑戰(zhàn) A 提到了異步請求處理的問題也描述了幾種解決方案,但都不甚理想。最理想的情況是自動化測試框架能夠自己處理異步請求的問題,并且不需要開發(fā)者編寫任何代碼。這就是所謂的“隱式等待”機制。
      目前,不少 Web UI 自動化測試框架都具備“隱式等待”功能,比如 Sahi 和 Selenium。Water Bear 使用的是 Sahi。當(dāng)然,Sahi 同時也提供了對“硬編碼等待時間”和“基于條件的等待”的 API 支持(因為,有些情況下還是不得不使用“硬編碼等待時間”或“基于條件的等待”)。根據(jù)經(jīng)驗,超過 90%的情形是 Sahi 的“隱式等待”功能可以覆蓋的,但是像“進度條”這樣的功能就不得不用“基于條件的等待”。在進度條達到 100%之前,前端代碼不斷地向后臺發(fā)起 Ajax 請求輪詢進度狀態(tài)。這種情形,Sahi 無法智能地得知哪一個 Ajax 請求的返回是“最后一個”,因此,就無法決定何時可以執(zhí)行下一個動作。
      清單 1. “進度條”代碼示例
      BrowserCondition cond = new BrowserCondition(getBrowser()) {
      public boolean test() throws ExecutionException {
      return getBrowser().isVisible(getBrowser().div("100%").in(es));
      }
      };
      getBrowser().waitFor(cond, waitTime);
      清單 1 展示了 Water Bear 中部分實現(xiàn)進度條功能的代碼,也就是 Sahi“基于條件的等待”的代碼。在 test 方法返回“真”之前(也就是代碼發(fā)現(xiàn)文本“100%”出現(xiàn)了),waitFor 方法一直處于輪詢狀態(tài)。waitTime 是一個超時時間。如果這個時間達到了,即便 test 方法仍然返回“假”,waitFor 還是返回。通常,這時已經(jīng)可以認定 Web UI 的功能執(zhí)行出現(xiàn)了問題。
      只所以把“隱式等待”放在第一個來講,是因為 Web UI 自動化測試框架是否具備該功能對于 Dojo 應(yīng)用 UI 自動化測試實施成敗是至關(guān)重要的。
      位置關(guān)系操作
      Dojo 應(yīng)用 UI 自動化測試框架應(yīng)當(dāng)具備根據(jù)給定對象定位其他對象的功能。這種相對的位置關(guān)系通常包括:在里面、在附近、在左面(右面)以及在上面(下面)等等。目前,Sahi 支持所有這些位置關(guān)系查找,另外還支持“在上面或者下面”以及“在左面或者右面”。這當(dāng)中,“在里面”使用的最為頻繁。
      為什么要使用位置關(guān)系操作?有以下幾個原因:
      準確定位頁面對象。在挑戰(zhàn) D 中,我們提到了在一個 DOM 樹中有可能存在與要查找的對象屬性與 DOM 結(jié)構(gòu)完全相同的對象。尤其對于“確定”或者“取消”按鈕,這種情況很常見。這時,必須要通過限定父對象來縮小查找范圍。一般來講,只要限制到當(dāng)前頁面的邊界元素能夠阻止跨頁面 DOM 節(jié)點查找就夠了(因為,當(dāng)前頁面有哪些對象一目了然,但是其他頁面的 DOM 節(jié)點是由運行時的操作控制的,無法預(yù)料)。
      封裝 Dojo 小部件。這一點會在下面具體講解。
      提供更豐富的查找方式,如根據(jù)“標簽”查找 Dojo 小部件。通常,文本框的左側(cè)會有一個文本,比如“名稱:”。如果,該文本框沒有任何其他合適的靜態(tài)屬性用來定位,就可以通過“在附近”查找的方法,先定位“名稱:”所在的元素,再找到這個文本框。
      當(dāng) DOM 樹結(jié)構(gòu)未發(fā)生“功能性”變化時,避免自動化測試代碼改動。所謂“功能性”變化是指頁面上增加、替換或者移除了控件,比如按鈕或者輸入框等。當(dāng)發(fā)生這些變化時,自動化測試代碼不得不修改。但,如果發(fā)生的僅僅是 DOM 樹結(jié)構(gòu)上的變化,比如增加了不可見的 DIV 或者 SPAN 元素,只要位置關(guān)系操作使用得當(dāng),自動化測試代碼可以做到不需要修改。
      我們來看一個例子。圖 2 左邊是所測應(yīng)用現(xiàn)在的狀態(tài):一個 Dojo 按鈕小部件被一個 DIV 元素包圍。在代碼中,我們用按鈕的文本“OK”并限制在圖示的 DIV 中來定位它。之后,DOM 樹結(jié)構(gòu)發(fā)生了變化,變成了圖 2 右邊的樣子,在原有的 DIV 元素和按鈕之間增加了兩層 DIV 元素。此時,代碼不需要更改,因為這個“OK”按鈕仍然在之前的 DIV 元素里。但是,如果用 XPath 定位元素,這種情況就很有可能要修改了。
      
    圖 2. 位置關(guān)系操作示例
      封裝 Dojo 小部件
      在挑戰(zhàn) C 中,提到了 Dojo 小部件 DOM 結(jié)構(gòu)的復(fù)雜性。最好的方式是封裝 Dojo 小部件,將每個 Dojo 小部件作為一個整體操作。
      Water Bear 使用的編程語言是 Java。它將頁面中的 Dojo 小部件映射成一個 Java 類,以此封裝所有該 Dojo 小部件的行為。由于 Sahi 支持“在里面”的位置關(guān)系操作,使得封裝更加容易 – 只需要定位到 Dojo 小部件的最外層 HTMl 元素(一般是 DIV),其他的元素定位都限制在該元素之內(nèi)。從而,即便頁面上同時有兩個同類型的 Dojo 小部件,也不會出現(xiàn)跨部件的錯誤操作。
      圖 3 展示了 Water Bear 中定義的與 Dojo 小部件對應(yīng)的一些類。最上層父類 WebElement.java 代表一般的 HTML 元素,它封裝了基本 HTML 元素的方法。DojoWidget.java 是所有 Dojo 小部件類的抽象。它定義了所有 Dojo 小部件類的通用方法,比如 getWidgetId()等。所有 Dojo 小部件類均繼承自 DojoWidget.java 并定義自己的方法,比如 ComboBox.java 需要定義 selectByText 方法。
      
    圖 3. Water Bear 中與 Dojo 小部件對應(yīng)的類
      那么,頁面上 Dojo 小部件如何和這些類對應(yīng)關(guān)聯(lián)起來呢?Water Bear 中通過.wdef 文件把兩者關(guān)聯(lián)起來。

    清單 2. .wdef 文件示例
      org.waterbear.core.widgets.dijit.Textbox=div|textbox|labelnear|dijit_form_ValidationTextBox,\
      evo_form_ObjectNameTextBox,dijit_form_NumberTextBox,dijit_form_TextBox,aspen_config_directory_DNTextBox
      org.waterbear.core.widgets.dijit.Checkbox=div|checkbox|labelnear|dijit_form_CheckBox
      org.waterbear.core.widgets.dijit.Select=table|table|labelnear|dijit_form_Select
      org.waterbear.core.widgets.dijit.Button=span|span|labelinside|dijit_form_Button
      org.waterbear.core.widgets.dijit.ComboBox=div|textbox|labelnear|dijit_form_ComboBox
      清單 2 展示了.wdef 文件的部分內(nèi)容。它是一純文本文件,每一行定義了一組映射關(guān)系。等號左邊是 Dojo 小部件映射的 Java 類名,等號右邊是頁面上 Dojo 小部件的屬性描述。其中,起關(guān)鍵作用的是是最后一個屬性,它是 widgetid 的前綴部分。一個 Dojo 小部件類可以關(guān)聯(lián)到多種頁面 Dojo 小部件,因為有些 Dojo 小部件雖然被擴展了,但是對 Web UI 自動化測試來說擴展的功能不會被涉及到,于是可以用同一個類表示。
      IBM 框架
      IBM 框架以前被稱作為 ITCL 框架,由質(zhì)量軟件工程(Quality Software Engineering) 和 IBM 中有經(jīng)驗的自動化團隊合作開發(fā)而成的。這個框架由三層架構(gòu)組成,架構(gòu)的實現(xiàn)貫穿了應(yīng)用對象、任務(wù)和測試用例包(IBM 包)。
      潛在于應(yīng)用對象、任務(wù)和測試用例包之下的基本原理是:
      層次化的體系架構(gòu)
      將“做什么”與“如何做”分離開來
      代碼重用
      一致和清晰的組織結(jié)構(gòu)
      快速增強的能力
      迅速的調(diào)試
      有效地組織文件
      啟用協(xié)作
      學(xué)習(xí)他人
      下面是對應(yīng)用對象、任務(wù)和測試用例的解釋說明:
      應(yīng)用對象:儲存有關(guān)你的應(yīng)用程序中的 GUI 元素信息。同時在這里也可以編寫你的 Getter 方法,這些 Getter 方法可以返回對象,使調(diào)用者能夠?qū)@些 GUI 元素進行查詢和操作。一般情況下,這些方法在 Task 層中進行調(diào)用。
      任務(wù):在這里你將編寫可重用的方法,這些方法在你的應(yīng)用程序中執(zhí)行通用功能。同時在這里,你將編寫可以處理和查詢復(fù)雜的特定應(yīng)用程序控件的方法。在任務(wù)中的方法可以被測試用例調(diào)用。
      測試用例:導(dǎo)航一個應(yīng)用程序,驗證其狀態(tài),并記錄其結(jié)果的方法。
      這個理念應(yīng)用到 Java 編程就是用不同“包”組織應(yīng)用對象、任務(wù)和測試用例的類。無論具體的底層 Web UI 自動化測試框架是什么,用 IBM 框架的理念來架構(gòu)上層測試用例的類都是有幫助的。 采用 IBM 框架能夠有效地應(yīng)對挑戰(zhàn) E,因為高重用性能夠?qū)⒋a改動控制在局部范圍,并且一處改動即可糾正所有引用的代碼。除了采用 IBM 框架,實際上如何合理地規(guī)劃任務(wù)方法的粒度也很關(guān)鍵。但,這與具體應(yīng)用就十分相關(guān)了。
      代碼生成
      一般來說,編寫用來獲取界面元素的代碼(也就是應(yīng)用對象層的代碼)在整個開發(fā)工作量中占據(jù)很大的比例。通常,它需要開發(fā)者先借助一些能夠顯示 DOM 樹結(jié)構(gòu)的工具(比如 Firebug)觀察元素的屬性,然后決定用什么屬性來定位元素比較合適。 另外,一些代碼又是比較“機械”或者模式化的,例如給界面元素賦值的操作。這樣的代碼應(yīng)盡可能的通過一些自動化的方式生成,就可大大節(jié)省開發(fā)的時間。
      在 Water Bear 中,針對以上的兩個問題,分別開發(fā)了兩種代碼生成工具。
      一個工具叫 AppObjs CodeGen,它可以自動遍歷當(dāng)前的 DOM 樹,從而生成應(yīng)用對象層的代碼。它用 Sahi 腳本實現(xiàn),將結(jié)果輸出在它的日志窗口中(如圖 4)。 開發(fā)者將代碼復(fù)制到自己的類文件中即可。盡管這些代碼仍可能需要一些手工修改,比如重命名以增強方法的可讀性,但較之完全用手工編碼已節(jié)省很多時間。
      
    圖 4. AppObjs CodeGen 生成結(jié)果
      第二個工具叫 Skeleton CodeGen。 它的輸入是應(yīng)用對象層的類,輸出是任務(wù)和測試用例層的部分代碼。對于符合特定模式的以及界面有很多 UI 控件的 Dojo 應(yīng)用,這個工具比較有效。生成代碼仍需要二次修改,因為有些邏輯無法自動生成。
      測試數(shù)據(jù)的管理
      最好能夠?qū)y試數(shù)據(jù)和測試用例代碼分離,這樣同樣一份測試用例代碼可以搭配 N 種不同的測試數(shù)據(jù)運行。另外,這種分離也可以輕松地做到為不同的測試環(huán)境定義不同的測試數(shù)據(jù) – 有時候,一些測試數(shù)據(jù)是有環(huán)境依賴的。
      Water Bear 利用開源軟件 XStream 來實現(xiàn)測試數(shù)據(jù)與測試用例代碼的分離。首先,測試數(shù)據(jù)被定義在一個 HashMap 中。測試用例在第一次運行時會將 HashMap 通過 XStream 自動序列化成一個.xml 文件。當(dāng)自動化腳本再次運行時,如果.xml 文件已經(jīng)存在,它就直接讀取已有文件并借助 XStream 把文件內(nèi)容反序列化成 HashMap。在之后的運行中,只要 HashMap 的數(shù)據(jù)結(jié)構(gòu)沒有變化,就無需重新生成.xml 文件。數(shù)據(jù)文件的存放目錄可以通過配置文件指定,因此對于不同的環(huán)境只要修改配置文件指向不同的路徑即可。
      錄制與編碼
      提高開發(fā)效率的另一個途徑是提供錄制功能。但是錄制功能通常有如下一些問題:
      錄制生成的代碼通常是“過程化”的。“過程化”的代碼很難重用。即便是針對同一個頁面功能模塊錄制的不同的測試用例代碼也是孤立的。如果頁面功能發(fā)生變化,所有測試用例需要重新錄制。因此,表面上看錄制功能似乎大大減少了開發(fā)時間,但是當(dāng)頁面發(fā)生變化的時候,它或許未必如我們想象的那么好。
      錄制的代碼可讀性通常比較差。一般來說,錄制之后仍需要重命名變量以提高代碼可讀性。
      所以,理想中的錄制功能生成的代碼應(yīng)該是模塊化的,也就是按照應(yīng)用對象、任務(wù)和測試用例這三個層次生成。這樣的代碼即便于二次修改,也便于與已有代碼集成。從使用的角度看,所有的測試用例代碼完全用錄制功能生成不太現(xiàn)實,較好的方式是只用錄制功能輔助開發(fā)應(yīng)用對象層和任務(wù)層代碼。 當(dāng) UI 發(fā)生非功能性變化時,只需要重新錄制受影響的任務(wù)方法并更新應(yīng)用對象層。理論上,測試用例層不需要修改(除非測試用例的邏輯不得不修改)。
      Water Bear 目前僅支持“過程化”錄制功能。圖 5 展示的就是 Water Bear Recorder 生成的代碼。開發(fā)者把生成的代碼復(fù)制黏貼到自己的測試類中即可在 Water Bear 中直接運行。
      
    圖 5. Water Bear Recorder
      結(jié)束語
      本文首先列舉了 Dojo 應(yīng)用 UI 自動化測試面臨的諸多挑戰(zhàn),之后從這些挑戰(zhàn)入手,結(jié)合個人的開發(fā)經(jīng)驗以及一個內(nèi)部使用的 Dojo 應(yīng)用 UI 自動化測試框架,提出了八個在選取和設(shè)計 Dojo 應(yīng)用 UI 自動化測試框架時需要考慮的原則。當(dāng)然,每一點的重要性不盡相同。比如“隱式等待”是必須的,而錄制功能卻沒有那么重要。但是,若是這些原則都能符合,將大大提高 Dojo 應(yīng)用 UI 自動化測試實施成功的可能性。

    posted @ 2014-04-16 10:51 順其自然EVO 閱讀(222) | 評論 (0)編輯 收藏

    Linux下Tomcat重新啟動

     在Linux系統(tǒng)下,重啟Tomcat使用命令操作的!
      首先,進入Tomcat下的bin目錄
      cd /usr/local/tomcat/bin
      使用Tomcat關(guān)閉命令
      ./shutdown.sh
      查看Tomcat是否以關(guān)閉
      ps -ef|grep java
      如果顯示以下相似信息,說明Tomcat還沒有關(guān)閉
    root      1971     1  0 Apr19 ?        00:00:04 /opt/jdk1.6.0_37/bin/java -Djava.util.logging.config.file=/opt/tomcat8080/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/opt/tomcat8080/endorsed -classpath /opt/tomcat8080/bin/bootstrap.jar -Dcatalina.base=/opt/tomcat8080 -Dcatalina.home=/opt/tomcat8080 -Djava.io.tmpdir=/opt/tomcat8080/temp org.apache.catalina.startup.Bootstrap start
    root      6016  5899  0 09:14 pts/1    00:00:00 grep java
      *如果你想直接干掉Tomcat,你可以使用kill命令,直接殺死Tomcat進程
      kill -9 1971
      然后繼續(xù)查看Tomcat是否關(guān)閉
      ps -ef|grep java
      如果出現(xiàn)以下信息,則表示Tomcat已經(jīng)關(guān)閉
      root      6019    5899  0 09:15 pts/1    00:00:00 grep java
      最后,啟動Tomcat
      ./startup.sh
      注意:使用root用戶登錄Linux系統(tǒng);正確進入Tomcat目錄;在確定Tomcat關(guān)閉之后再啟動Tomcat,否則會報端口被占用異常。
      附圖:

    posted @ 2014-04-15 11:05 順其自然EVO 閱讀(142) | 評論 (0)編輯 收藏

    MySql配置優(yōu)化

      在做軟件開發(fā)時,如果選用MySQL數(shù)據(jù)庫的系統(tǒng),當(dāng)需要存儲數(shù)據(jù)量大或數(shù)據(jù)操作很頻繁時,MySQL對于性能的影響很大,也是關(guān)鍵的核心部分。MySQL的設(shè)置是否合理優(yōu)化,直接影響到軟件運行的速度和承載量。同時,MySQL也是優(yōu)化難度最大的一個部分,不但需要理解一些MySQL專業(yè)知識,同時還需要長時間的觀察統(tǒng)計并且根據(jù)經(jīng)驗進行判斷,然后設(shè)置合理的參數(shù)。下面我們研究一下MySQL(my.cnf/my.ini)的配置文件,通過在(my.cnf/my.ini)中添加/修改參數(shù)項來對Mysql進行優(yōu)化。
      linux環(huán)境MySql配置優(yōu)化
      1、配置文件
      MySQL服務(wù)器的許多參數(shù)會影響服務(wù)器的性能表現(xiàn),而且我們可以把這些參數(shù)保存到配置文件,使得每次MySQL服務(wù)器啟動時這些參數(shù)都自動發(fā)揮作用。這個配置文件就是my.cnf。
      MySQL服務(wù)器提供了my.cnf文件的幾個示例,它們可以在/usr/local/mysql/share/mysql/目錄下找到,名字分別為 my-small.cnf、my-medium.cnf、my-large.cnf以及my-huge.cnf。文件名字中關(guān)于規(guī)模的說明描述了該配置文件適用的系統(tǒng)類型。例如,如果運行MySQL服務(wù)器的系統(tǒng)內(nèi)存不多,而且MySQL只是偶爾使用,那么使用my-small.cnf配置文件最為理想,這個配置文件告訴mysqld daemon使用最少的系統(tǒng)資源。反之,如果MySQL服務(wù)器用于支持一個大規(guī)模的在線網(wǎng)站,系統(tǒng)擁有4G以上的內(nèi)存,那么使用mysql-huge.cnf 最為合適。
      要使用上述示例配置文件,我們應(yīng)該先復(fù)制一個最適合要求的配置文件,并把它命名為my.cnf。這個復(fù)制得到的配置文件可以按照如下三種方式使用:
      全局:把這個my.cnf文件復(fù)制到服務(wù)器的/etc目錄,此時文件中所定義的參數(shù)將全局有效,即對該服務(wù)器上運行的所有MySQL數(shù)據(jù)庫服務(wù)器都有效。
      局部:把這個my.cnf文件復(fù)制到[MYSQL-INSTALL-DIR]/var/將使該文件只對指定的服務(wù)器有效,其中[MYSQL-INSTALL-DIR]表示安裝MySQL的目錄。
      用戶:最后,我們還可以把該文件的作用范圍局限到指定的用戶,這只需把my.cnf文件復(fù)制到用戶的根目錄即可。
      那么,如何設(shè)置my.cnf文件中的參數(shù)呢?或者進一步說,哪些參數(shù)是我們可以設(shè)置的呢?所有這些參數(shù)都對MySQL服務(wù)器有著全局性的影響,但同時每一個參數(shù)都和MySQL的特定部分關(guān)系較為密切。例如,max_connections參數(shù)屬于mysqld一類。那么,如何才能得知這一點呢?這只需執(zhí)行如下命令:
      %>/usr/local/mysql/libexec/mysqld –help
      該命令將顯示出和mysqld有關(guān)的各種選項和參數(shù)。要尋找這些參數(shù)非常方便,因為這些參數(shù)都在“Possible variables for option –set-variable (-O) are”這行內(nèi)容的后面。找到這些參數(shù)之后,我們就可以在my.cnf文件中按照如下方式設(shè)置所有這些參數(shù):
      例如:
      set-variable = max_connections=1000
      這行代碼的效果是:同時連接MySQL服務(wù)器的最大連接數(shù)量限制為1000。
      2、參數(shù)優(yōu)化
      2.1 back_log
      back_log = 500要求 MySQL 能有的連接數(shù)量。當(dāng)主要MySQL線程在一個很短時間內(nèi)得到非常多的連接請求,這就起作用,然后主線程花些時間(盡管很短)檢查連接并且啟動一個新線程。
      back_log值指出在MySQL暫時停止回答新請求之前的短時間內(nèi)多少個請求可以被存在堆棧中。只有如果期望在一個短時間內(nèi)有很多連接,你需要增加它,換句話說,這值對到來的TCP/IP連接的偵聽隊列的大小。你的操作系統(tǒng)在這個隊列大小上有它自己的限制。試圖設(shè)定back_log高于你的操作系統(tǒng)的限制將是無效的。當(dāng)你觀察你的主機進程列表,發(fā)現(xiàn)大量 264084 | unauthenticated user | xxx.xxx.xxx.xxx | NULL | Connect | NULL | login | NULL 的待連接進程時,就要加大 back_log 的值了。默認數(shù)值是50,如果訪問量大可以它改為500。
      2.2 key_buffer_size
      Key_read_requests :從緩存讀取索引的請求次數(shù);
      Key_reads :從磁盤讀取索引的請求次數(shù);
      key_buffer_size指定用于索引的緩沖區(qū)大小。如果Key_reads太大,則應(yīng)該把key_buffer_size變大。增加它可得到更好處理的索引(對所有讀和多重寫),如果對表的順序掃描請求非常頻繁,并且你認為頻繁掃描進行得太慢,可以通過增加該變量值以及內(nèi)存緩沖區(qū)大小提高其性能。對于內(nèi)存在4GB左右的服務(wù)器該參數(shù)可設(shè)置為384M或512M。通過檢查狀態(tài)值Key_read_requests和 Key_reads,可以知道key_buffer_size設(shè)置是否合理。比例key_reads / key_read_requests應(yīng)該盡可能的低,至少是1:100,1:1000更好(上述狀態(tài)值可以使用SHOW STATUS LIKE ‘key_read%'獲得)。注意:該參數(shù)值設(shè)置的過大反而導(dǎo)致是服務(wù)器整體效率降低。

     2.3 max_allowed_packet
      設(shè)置最大包,限制server接受的數(shù)據(jù)包大小,避免超長SQL的執(zhí)行有問題 默認值為16M,當(dāng)MySQL客戶端或mysqld服務(wù)器收到大于max_allowed_packet字節(jié)的信息包時,將發(fā)出“信息包過大”錯誤,并關(guān)閉連接。對于某些客戶端,如果通信信息包過大,在執(zhí)行查詢期間,可能會遇到“丟失與MySQL服務(wù)器的連接”錯誤。
      增加該變量的值十分安全,這是因為僅當(dāng)需要時才會分配額外內(nèi)存。例如,僅當(dāng)你發(fā)出長查詢或mysqld必須返回大的結(jié)果行時mysqld才會分配更多內(nèi)存。該變量之所以取較小默認值是一種預(yù)防措施,以捕獲客戶端和服務(wù)器之間的錯誤信息包,并確保不會因偶然使用大的信息包而導(dǎo)致內(nèi)存溢出。
      2.4 table_cache
      table_cache = 512指定表高速緩存的大小, 如果opened_tables太大,應(yīng)該把table_cache變大。每當(dāng)MySQL訪問一個表時,如果在表緩沖區(qū)中還有空間,該表就被打開并放入其中,這樣可以更快地訪問表內(nèi)容。通過檢查峰值時間的狀態(tài)值Open_tables和Opened_tables,可以決定是否需要增加table_cache的值。如果你發(fā)現(xiàn) open_tables等于table_cache,并且opened_tables在不斷增長,那么你就需要增加table_cache的值了(上述狀態(tài)值可以使用SHOW STATUS LIKE ‘Open%tables'獲得)。注意,不能盲目地把table_cache設(shè)置成很大的值。如果設(shè)置得太高,可能會造成文件描述符不足,從而造成性能不穩(wěn)定或者連接失敗。
      2.5 sort_buffer_size
      屬重點優(yōu)化參數(shù)
      sort_buffer_size = 4M查詢排序時所能使用的緩沖區(qū)大小。注意:該參數(shù)對應(yīng)的分配內(nèi)存是每連接獨占,如果有100個連接,那么實際分配的總共排序緩沖區(qū)大小為100 × 4 = 400MB。所以,對于內(nèi)存在4GB左右的服務(wù)器推薦設(shè)置為4-8M。
      2.6 read_buffer_size
      read_buffer_size = 4M讀查詢操作所能使用的緩沖區(qū)大小。和sort_buffer_size一樣,該參數(shù)對應(yīng)的分配內(nèi)存也是每連接獨享。MySql讀入緩沖區(qū)大小。對表進行順序掃描的請求將分配一個讀入緩沖區(qū),MySql會為它分配一段內(nèi)存緩沖區(qū)。read_buffer_size變量控制這一緩沖區(qū)的大小。如果對表的順序掃描請求非常頻繁,并且你認為頻繁掃描進行得太慢,可以通過增加該變量值以及內(nèi)存緩沖區(qū)大小提高其性能。
      2.7 join_buffer_size
      join_buffer_size = 8M聯(lián)合查詢操作所能使用的緩沖區(qū)大小,和sort_buffer_size一樣,該參數(shù)對應(yīng)的分配內(nèi)存也是每連接獨享。
      2.8 thread_cache_size
      thread_cache_size = 64服務(wù)器線程緩存這個值表示可以重新利用保存在緩存中線程的數(shù)量,如果Threads_created太大,就要增加thread_cache_size的值。當(dāng)斷開連接時如果緩存中還有空間,那么客戶端的線程將被放到緩存中,如果線程重新被請求,那么請求將從緩存中讀取,如果緩存中是空的或者是新的請求,那么這個線程將被重新創(chuàng)建,如果有很多新的線程,增加這個值可以改善系統(tǒng)性能.通過比較 Connections 和 Threads_created 狀態(tài)的變量,可以看到這個變量的作用
      2.9 max_connections
      max_connections = 300指定MySQL允許的最大連接進程數(shù)。如果在訪問論壇時經(jīng)常出現(xiàn)Too Many Connections的錯誤提示,則需要增大該參數(shù)值。
      2.10 max_connect_errors
      max_connect_errors = 10000000對于同一主機,如果有超出該參數(shù)值個數(shù)的中斷錯誤連接,則該主機將被禁止連接。如需對該主機進行解禁,執(zhí)行:FLUSH HOST;。
      2.11 wait_timeout
      wait_timeout = 10指定一個請求的最大連接時間,對于4GB左右內(nèi)存的服務(wù)器可以設(shè)置為5-10。
      2.12 thread_concurrency
      屬重點優(yōu)化參數(shù)
      thread_concurrency = 8設(shè)置thread_concurrency的值的正確與否, 對mysql的性能影響很大, 在多個cpu(或多核)的情況下,錯誤設(shè)置了thread_concurrency的值, 會導(dǎo)致mysql不能充分利用多cpu(或多核), 出現(xiàn)同一時刻只能一個cpu(或核)在工作的情況。thread_concurrency應(yīng)設(shè)為CPU核數(shù)的2倍. 比如有一個雙核的CPU, 那么thread_concurrency的應(yīng)該為4; 2個雙核的cpu, thread_concurrency的值應(yīng)為8。
      2.13 tmp_table_size
      如果Created_tmp_disk_tables太大, 就要增加tmp_table_size的值,用基于內(nèi)存的臨時表代替基于磁盤的。tmp_table_size 的默認大小是 32M。如果一張臨時表超出該大小,MySQL產(chǎn)生一個 The table tbl_name is full 形式的錯誤,如果你做很多高級 GROUP BY 查詢,可以增加 tmp_table_size 值。
      2.14 read_rnd_buffer_size
      MySql的隨機讀(查詢操作)緩沖區(qū)大小。當(dāng)按任意順序讀取行時(例如,按照排序順序),將分配一個隨機讀緩存區(qū)。進行排序查詢時,MySql會首先掃描一遍該緩沖,以避免磁盤搜索,提高查詢速度,如果需要排序大量數(shù)據(jù),可適當(dāng)調(diào)高該值。但MySql會為每個客戶連接發(fā)放該緩沖空間,所以應(yīng)盡量適當(dāng)設(shè)置該值,以避免內(nèi)存開銷過大。
      2.15 query_cache_size屬重點優(yōu)化參數(shù)
      這個參數(shù)也是一個重要的優(yōu)化參數(shù)。但隨著發(fā)展,這個參數(shù)也爆露出來一些問題。機器的內(nèi)存越來越大,人們也都習(xí)慣性的把以前有用的參數(shù)分配的值越來越大。這個參數(shù)加大后也引發(fā)了一系列問題。我們首先分析一下 query_cache_size的工作原理:一個SELECT查詢在DB中工作后,DB會把該語句緩存下來,當(dāng)同樣的一個SQL再次來到DB里調(diào)用時,DB在該表沒發(fā)生變化的情況下把結(jié)果從緩存中返回給Client。這里有一個關(guān)建點,就是DB在利用Query_cache工作時,要求該語句涉及的表在這段時間內(nèi)沒有發(fā)生變更。那如果該表在發(fā)生變更時,Query_cache里的數(shù)據(jù)又怎么處理呢?首先要把Query_cache和該表相關(guān)的語句全部置為失效,然后在寫入更新。那么如果Query_cache非常大,該表的查詢結(jié)構(gòu)又比較多,查詢語句失效也慢,一個更新或是Insert就會很慢,這樣看到的就是Update或是Insert怎么這么慢了。所以在數(shù)據(jù)庫寫入量或是更新量也比較大的系統(tǒng),該參數(shù)不適合分配過大。而且在高并發(fā),寫入量大的系統(tǒng),建系把該功能禁掉。

    posted @ 2014-04-15 11:04 順其自然EVO 閱讀(308) | 評論 (0)編輯 收藏

    Java類加載器加載類順序

     數(shù)組就是相同數(shù)據(jù)類型的元素按一定順序排列的集合,就是把有限個類型相同的變量用一個名字命名,然后用編號區(qū)分他們的變量的集合,這個名字成為數(shù)組名,編號成為下標。組成數(shù)組的各個變量成為數(shù)組的分量,也稱為數(shù)組的元素,有時也稱為下標變量。數(shù)組是在程序設(shè)計中,為了處理方便, 把具有相同類型的若干變量按有序的形式組織起來的一種形式。這些按序排列的同類數(shù)據(jù)元素的集合稱為數(shù)組。 ——這是百度對數(shù)組的定義
      首先,數(shù)組的定義:
      元素類型[] 數(shù)組名 = new 元素類型[] {元素1,元素2,........}        例如int[] arr = new int[5]
    public static void main(String[] args) {
    //定義一個可以存放3個數(shù)組的容器,注意,數(shù)組的腳標從0開始
    int[] arr = new int[3];
    //位數(shù)組賦值
    arr[0] = 1;
    arr[1] = 2;
    arr[2] = 3;
    System.out.println(arr[0]);
    }
    也可以這樣寫
    public static void main(String[] args) {
    int arr[] = {1,2,3};
    System.out.println(arr[0]);
    }
      后者直接體現(xiàn)了數(shù)組的值和個數(shù)。數(shù)據(jù)明確的情況下可以前面中,不明確時用后者。
      public static void main(String[] args) {
      int arr[] = {1,2,3};
      arr = null;
      System.out.println(arr[1]);
      }
      用數(shù)組的常見錯誤:
    public static void main(String[] args) {
    int arr[] = {1,2,3};
    System.out.println(arr[3]);
    }
    //ArrayIndexOutOfBoundsException:數(shù)組越界;訪問數(shù)組時,訪問到數(shù)組中不存在的腳標。
    public static void main(String[] args) {
    int arr[] = {1,2,3};
    arr = null;
    System.out.println(arr[1]);
    }
    //NullPointerException:空指針;當(dāng)引用沒有任何指向值為null的情況,該引用還在用于操作實體。
      數(shù)組的操作
      獲取數(shù)組中德數(shù)據(jù),通常會用到遍歷
      用for循環(huán)遍歷數(shù)組
    public static void main(String[] args) {
    int arr[] = { 1, 2, 3, 9, 5, 8, 6, 32, 52, 100 };
    //arr.length方法獲取數(shù)組的長度
    for (int i = 0; i < arr.length; i++) {
    System.err.println(arr[i]);
    }
    }
      java ClassLoader的學(xué)習(xí)
      java是一門解釋執(zhí)行的語言,由開發(fā)人員編寫好的java源文件先編譯成字節(jié)碼文件.class形式,然后由java虛擬機(JVM)解釋執(zhí)行,.class字節(jié)碼文件本身是平臺無關(guān)的,但是jvm卻不是,為了實現(xiàn)所謂的一次編譯,到處執(zhí)行,sun提供了各個平臺的JVM實現(xiàn)--也就是說jvm不是跨平臺的,編譯好的字節(jié)碼文件被放在不同的操作系統(tǒng)平臺上的jvm所解釋執(zhí)行,這個章節(jié)主要解釋一下JVM裝載類的機制
      1.ClassLoader是什么?
      一個類如果要被JVM所調(diào)度執(zhí)行,必須先把這個類加載到JVM內(nèi)存里,java.lang下有個很重要的類ClassLoader,這個類主要就是用來把指定名稱(指定路徑下)的類加載到JVM中
      2.ClassLoader的分類
      主要分4類,見下圖橙色部分
      JVM類加載器:這個模式會加載JAVA_HOME/lib下的jar包
      擴展類加載器:會加載JAVA_HOME/lib/ext下的jar包
      系統(tǒng)類加載器:這個會去加載指定了classpath參數(shù)指定的jar文件
      用戶自定義類加載器:sun提供的ClassLoader是可以被繼承的,允許用戶自己實現(xiàn)類加載器
      類加載器的加載順序如圖所示:

    posted @ 2014-04-15 11:02 順其自然EVO 閱讀(344) | 評論 (0)編輯 收藏

    LoadRunner FAQ

    web_concurrent_start和web_concurrent_end
      web_concurrent_start
      語法:
      int web_concurrent_start ( [char * ConcurrentGroupName,]NULL );
      參數(shù):
      ConcurrentGroupName:可選的,并發(fā)組的標識符。
      NULL:參數(shù)列表結(jié)束的標記符。
      返回值:
      整型,返回LR_PASS (0)表示成功,返回LR_FAIL(1)表示失敗。
      web_concurrent_end
      語法:
      int web_concurrent_end ( reserved );
      參數(shù):
      reserved:保留的供擴展的字段。
      返回值
      整型。返回LR_PASS (0)表示成功,返回LR_FAIL(1)表示失敗。
      說明
      web_concurrent_start函數(shù)是并發(fā)組開始的標記。web_concurrent_end,并發(fā)組結(jié)束的標記。在并發(fā)組中的函數(shù)不是立即執(zhí)行的。在并發(fā)組開始時,所有的函數(shù)首先被記錄下來,當(dāng)并發(fā)組結(jié)束時,所有的函數(shù)并發(fā)執(zhí)行。腳本執(zhí)行時,碰到 web_concurrent_end函數(shù)時,開始并發(fā)執(zhí)行所有記錄的函數(shù)。
      在并發(fā)組中,可以包含的函數(shù)有:web_url、web_submit_data、web_custom_request、web_create_html_param、web_create_html_param_ex、web_reg_save_param、web_add_header。
      URL-based 方式將每條客戶端發(fā)出的請求錄制成一條語句,對LoadRunner來說,在該模式下,一條語句只建立一個到服務(wù)器的連接,LoadRunner提供了web_concurrent_start和web_concurrent_end函數(shù)模擬HTML-based的工作方式
      LoadRunner變量
      Loadrunner變量分為局部變量和全局變量。
      1. 如何定義變量
      在Loadrunner腳本中變量必須在開頭聲明。比如說,在vuser_init、Action、vuser_end定義變量,必須現(xiàn)在最頂端生命,后面才能使用。如果不這樣,編譯器是通不過的。
      2. 局部變量
      就像C語言一樣,變量有作用域范圍,局部變量包含在函數(shù)或者vuser_init、Action、vuser_end內(nèi)部,對于其他范圍之外就不起作用了。
      3. 全局變量
      若要跨越vuser_init、Action、vuser_end定義變量,則需要定義全局變量。在Loadrunner的腳本錄制時,會生成一個globals.h文件,在這里定義的變量相當(dāng)于Loadrunner腳本的全局變量,可以在vuser_init、Action、vuser_end中被使用。例子:
    #ifndef _GLOBALS_H
    #define _GLOBALS_H
    //-------------------------------------------------------------------
    // Include Files
    #include "lrun.h"
    #include "web_api.h"
    #include "lrw_custom_body.h"
    //定義全局變量char * str="This is a test";
    //-------------------------------------------------------------------
    // Global Variables#endif // _GLOBALS_H
     LR中參數(shù)的定義和賦值
      1.參數(shù)的賦值和取值
      lr_save_string("hello world","param");
      lr_eval_string("{param}");
      2.變量到參數(shù)
    int x;
    char *y;
    y="hello";
    x=10;
    lr_save_int(x,"param");
    lr_save_string(y,"param1");
    lr_eval_string("{param}");
    lr_eval_string("{param1}");
      3.變量讀參數(shù)
    char x[100];
    x="{param}";
    lr_save_string("hello world","param");
    lr_eval_string(x);
      LR中文件下載模擬
    Action()
    {
    //定義一個整型變量保存獲得文件的大小
    int flen;
    //保存文件句柄
    long filedes;
    //保存文件路徑及文件名
    char file[256]="/0";
    //定義一個隨機數(shù)
    char * strNumber;
    //Returns the string argument after evaluating embedded parameters.
    strNumber=lr_eval_string("{RandomNum}");
    //將路徑保存到file變量中
    strcat(file,"D://Excel//");
    //將獲得的隨機數(shù)拼接在file變量之后
    strcat(file,strNumber);
    //將下載的文件后綴名.rar拼接在file變量之后
    strcat(file,".rar");
    //到此為止一個LoadRunner已經(jīng)獲得了一個完整的文件名
    //設(shè)置參數(shù)的最大長度,注意該值必須大于文件的大小
    web_set_max_html_param_len("20000");
    //使用關(guān)聯(lián)函數(shù)獲取下載文件的內(nèi)容,在這里不定義左右邊界,獲得服務(wù)器響應(yīng)的所有內(nèi)容
    web_reg_save_param("fcontent",
    "LB=",
    "RB=",
    "SEARCH=BODY",
    LAST);
    lr_start_transaction("下載幫助文件");
    //發(fā)送下載幫助文件的請求
    web_url("DownLoadServlet",
    "URL=https://testserver3/servlet/DownLoadServlet?filename=help",
    "Resource=1",
    "RecContentType=application/x-msdownload",
    "Referer=",
    "Snapshot=t41.inf",
    LAST);
    //獲取響應(yīng)中的文件長度
    flen = web_get_int_property(HTTP_INFO_DOWNLOAD_SIZE);
    if(flen > 0)
    {
    //以寫方式打開文件
    if((filedes = fopen(file, "wb")) == NULL)
    {
    lr_output_message("打開文件失敗!");
    return -1;
    }
    //寫入文件內(nèi)容
    fwrite(lr_eval_string("{fcontent}"), flen, 1, filedes);
    //關(guān)閉文件
    fclose(filedes);
    }
    lr_end_transaction("下載幫助文件",LR_AUTO);
    return 0;
    }
      如何進行數(shù)據(jù)的關(guān)聯(lián)
      VuGen提供二種方式幫助您找出需要做關(guān)聯(lián)(correlation)的值:
      1. 自動關(guān)聯(lián)
      2. 手動關(guān)聯(lián)
      自動關(guān)聯(lián)
      VuGen內(nèi)建自動關(guān)聯(lián)引擎(auto-correlationengine),可以自動找出需要關(guān)聯(lián)的值,并且自動使用關(guān)聯(lián)函數(shù)建立關(guān)聯(lián)。有兩種方式:
      RuleCorrelation
      可以在【RecordingOptions】>【InternetProtocol】>【Correlation】中啟用關(guān)聯(lián)規(guī)則,則當(dāng)錄制這些應(yīng)用系統(tǒng)的腳本時,VuGen會在腳本中自動建立關(guān)聯(lián)。

    您也可以在【RecordingOptions】>【InternetProtocol】>【Correlation】檢視每個關(guān)聯(lián)規(guī)則的定義。
      請依照以下步驟使用RuleCorrelation:
      1. 啟用auto-correlation
      1) 點選VuGen的【Tools】>【RecordingOptions】,開啟【RecordingOptions】對話窗口,選取【InternetProtocol】>【Correlation】,勾選【Enablecorrelation during recording】,以啟用自動關(guān)聯(lián)。
      2) 假如錄制的應(yīng)用系統(tǒng)屬于內(nèi)建關(guān)聯(lián)規(guī)則的系統(tǒng),如AribaBuyer、BlueMartini、BroadVision、InterStage、mySAP、NetDynamics、Oracle、PeopleSoft、Siebel、SilverJRunner等,請勾選相對應(yīng)的應(yīng)用系統(tǒng)。
      3) 或者也可以針對錄制的應(yīng)用系統(tǒng)加入新的關(guān)聯(lián)規(guī)則,此即為使用者自訂的關(guān)聯(lián)規(guī)則。
      2. 錄制腳本
      開始錄制腳本,在錄制過程中,當(dāng)VuGen偵測到符合關(guān)聯(lián)規(guī)則的數(shù)據(jù)時,會依照設(shè)定建立關(guān)聯(lián),您會在腳本中看到類似以下的腳本,此為BroadVision應(yīng)用系統(tǒng)建立關(guān)聯(lián)的例子,在腳本批注部分可以看到關(guān)聯(lián)前的數(shù)據(jù)為何。
      3. 執(zhí)行腳本驗證關(guān)聯(lián)是OK的。
      CorrelationStudio
      當(dāng)錄制的應(yīng)用系統(tǒng)不屬于VuGen預(yù)設(shè)支持的應(yīng)用系統(tǒng)時,RuleCorrelation可能既無法發(fā)揮作用,這時可以利用CorrelationStudio來做關(guān)聯(lián)。
      CorrelationStudio會嘗試找出錄制時與執(zhí)行時,服務(wù)器響應(yīng)內(nèi)容的差異部分,藉以找出需要關(guān)聯(lián)的數(shù)據(jù),并建立關(guān)聯(lián)。
      使用CorrelationStudio的步驟如下:
      1. 錄制腳本并執(zhí)行
      2. 執(zhí)行完畢后,VuGen會跳出下面的【ScanAction for Correlation】窗口,詢問您是否要掃描腳本并建立關(guān)聯(lián),按下【Yes】按鈕。
      3. 掃描完后,可以在腳本下方的【CorrelationResults】中看到掃描的結(jié)果。
      4. 檢查一下掃瞄的結(jié)果后,選擇要做關(guān)聯(lián)的數(shù)據(jù),然后按下【Correlate】按鈕,一筆一筆做,或是按下【CorrelateAll】讓VuGen一次就對所有的數(shù)據(jù)建立關(guān)聯(lián)。
      注意:由于CorrelationStudio會找出所有有變動的數(shù)據(jù),但是并不是所有的數(shù)據(jù)都需要做關(guān)聯(lián),所以不建議您直接用【CorrelateAll】。
      5. 一般來說,您必須一直重復(fù)步驟1~4直到所有需要做關(guān)聯(lián)的數(shù)據(jù)都找出來為止。因為有時前面的關(guān)聯(lián)還沒做好之前,將無法執(zhí)行到后面需要做關(guān)聯(lián)的部份。
      手動關(guān)聯(lián)
      手動關(guān)聯(lián)的執(zhí)行過程大致如下:
      1. 使用相同的業(yè)務(wù)流程與數(shù)據(jù),錄制二份腳本
      2. 使用Diff工具比較一下生成的Action.c,找出需要關(guān)聯(lián)的數(shù)據(jù)
      3. 使用web_reg_save_param函數(shù)手動建立關(guān)聯(lián)
      4. 將腳本中有用到關(guān)聯(lián)的數(shù)據(jù),以參數(shù)取代
      注意動態(tài)數(shù)據(jù)不能放在vuser_init.c文件中。不是所有的差異處都要關(guān)聯(lián)的,WEB_URL()等方法的參數(shù)列表的先后順序是沒關(guān)系的,思考時間當(dāng)然也可以不同。
      LR的檢查點設(shè)置
      常用檢查點函數(shù)如下:
      1)web_find()函數(shù)用于從 HTML 頁中搜索指定的文本字符串;
      2)web_reg_find()函數(shù)注冊一個請求,以在下一個操作函數(shù)(如 web_url)檢索到的HTML網(wǎng)頁上搜索指定的文本字符串;
      3)web_image_check()函數(shù)用于從HTML頁面中查找指定的圖片;
      4)web_global_verfication()屬于注冊函數(shù),注冊一個在web頁面中搜索文本字符串的請求,與web_reg_find只在下一個Action函數(shù)中執(zhí)行搜索不同的是它在之后所有的Action類函數(shù)中執(zhí)行搜索指定的文本字符串;
      下面分別介紹以上函數(shù)的用法:
      1、web_find()函數(shù)參數(shù)舉例:
      web_find("web_find","RighOf=a","LeftOf=b","What=name",LAST);
      參數(shù)解釋:"web_find"定義該查找函數(shù)的名稱;“LeftOf”和“RighOf=”用來定義查找字符的左右邊界;“What=”定義查找內(nèi)容;
      例如上述參數(shù)舉例中的意思就是在頁面中查找左邊界為b,右邊界為a,內(nèi)容為name的信息;
      使用該函數(shù)注意事項:該函數(shù)是在查找頁面中的內(nèi)容,所以要放在要查找的內(nèi)容的后面;該函數(shù)只能在基于HTML模式錄制的腳本中進行查找
      注意事項:使用該函數(shù)時,要在Vuser->Run-Tme Settings中更改下設(shè)置
      勾選Enable Image and text check
      系統(tǒng)默認是不勾選該選項的。
      2、web_reg_find()函數(shù)參數(shù)舉例:
      web_reg_find("Search=Body","SaveCount=ddd","Test=aaa",LAST);
      參數(shù)解釋: Search用來定義查找范圍,SaveCount定義查找計數(shù)變量名稱,該參數(shù)可以記錄在緩存中查找內(nèi)容出現(xiàn)的次數(shù),可以使用該值,來判斷要查找的內(nèi)容是否被找到;
      例如上述參數(shù)舉例中的意思就是Body中查找內(nèi)容為aaa的信息,并將出現(xiàn)次數(shù)記錄在變量ddd中;
      【代碼一:web_reg_find("Text=PaymentDetails",LAST);
      代碼思路:1.“Payment Details” 為你要檢查的文本;
      2. 腳本執(zhí)行到此處,若在頁面上找到了這幾個字符串,那腳本繼續(xù)執(zhí)行下去;若沒有找到,腳本將在此報錯并且結(jié)束。
      3、web_image_check()函數(shù)參數(shù)說明:
      web_image_check("web_image_check","Alt=","Src=",LAST);
      參數(shù)解釋:“Alt”和“Src”的值直接取該圖片在網(wǎng)頁源代碼中相應(yīng)參數(shù)的值;
      注意事項:使用該函數(shù)時,要在Vuser->Run-Tme Settings中勾選Enable Image and text check,具體操作請看web_find()中的注意事項。
      插入函數(shù)的方法
      1、 手工寫入,在需要插入函數(shù)的位置手工寫入該函數(shù);
      2、 光標停留在要插入函數(shù)的位置,在INSERT菜單中,選擇new step,在列表中選擇或查找要插入的函數(shù),根據(jù)提示填寫必要的參數(shù);
      3、 在tree view模式下,在樹狀菜單中選中要插入函數(shù)的位置,右鍵,選擇insert after或insert before,根據(jù)提示填寫必要的參數(shù);
      總結(jié):
      1、 這兩個函數(shù)函數(shù)類型不同,WEB_FIND是普通函數(shù),WEB_REG_FIND是注冊函數(shù);
      2、 WEB_FIND使用時必須開啟內(nèi)容檢查選項,而WEB_REG_FIND則不沒有此限制;
      3、 WEB_FIND只能用在基于HTML模式錄制的腳本中,而WEB_REG_FIND沒有此限制;
      4、 WEB_FIND是在返回的頁面中進行內(nèi)容查找,WEB_REG_FIND是在緩存中進行查找;
      5、 WEB_FIND在執(zhí)行效率上不如WEB_REG_FIND;
      使用web_concurrent_start報錯
      錄制方式選的是HTML-based script,改為url-based script就可以了。該函數(shù)不支持HTML-based script方式。
      LR中的腳本變量聲明報錯
      Loadrunner使用的是C語言的語法。腳本中變量必須在開頭聲明。比如說,在Vuser_init、Action、Vuser_end定義變量,必須現(xiàn)在最頂端生命,后面才能使用。如果不這樣,編譯器是通不過的。

    posted @ 2014-04-15 11:01 順其自然EVO 閱讀(271) | 評論 (0)編輯 收藏

    QTP自動化測試-TXT文件操作

     創(chuàng)建文本文件
      Set bjFSO = CreateObject("Scripting.FileSystemObject")
      Set bjFile = objFSO.CreateTextFile("C:\FSOScriptLog.txt")
      檢察文件是否存在
    Set bjFSO = CreateObject("Scripting.FileSystemObject")
    If objFSO.FileExists("C:\FSOScriptLog.txt") Then
    Set bjFolder = objFSO.GetFile("C:\FSOScriptLog.txt")
    Else
    MsgBox "File does not exist."
    End If
      刪除文本文件
      Set bjFSO = CreateObject("Scripting.FileSystemObject")
      objFSO.DeleteFile("C:\FSOScriptLog.txt")
      移動文件
      Set bjFSO = CreateObject("Scripting.FileSystemObject")
      objFSO.MoveFile "C:\FSOScriptLog.txt" , "D:\"
      復(fù)制文件
      Set bjFSO = CreateObject("Scripting.FileSystemObject")
      objFSO.CopyFile "C:\FSOScriptLog.txt" , "D:\"
      重命名文件
      Set bjFSO = CreateObject("Scripting.FileSystemObject")
      objFSO.MoveFile "C:\FSO\ScriptLog.txt" , "C:\FSO\BackupLog.txt"
      讀取全部內(nèi)容
    Const ForReading = 1
    Set bjFSO = CreateObject("Scripting.FileSystemObject")
    Set bjFile = objFSO.OpenTextFile("C:ScriptsTest.txt", ForReading)
    strContents = objFile.ReadAll
    Wscript.Echo strContents
    objFile.Close
      一行行的讀取文本文件內(nèi)容
    Const ForReading = 1
    Set bjFSO = CreateObject("Scripting.FileSystemObject")
    Set bjTextFile = objFSO.OpenTextFile ("C: \ScriptsTest.txt", ForReading)
    Do Until objTextFile.AtEndOfStream
    strComputer = objTextFile.ReadLine
    Wscript.Echo strComputer
    Loop
    objTextFile.Close
     追加文本文件一行內(nèi)容
    Const ForAppending = 8
    Set bjFSO = CreateObject("Scripting.FileSystemObject")
    Set bjTextFile = objFSO.OpenTextFile ("C:\ScriptsTest.txt ", ForAppending, True)
    objTextFile.WriteLine("追加的內(nèi)容")
    objTextFile.Close
      有用的幾個函數(shù):
      替換:將Jim替換成James。
      strNewText = Replace(strText, "Jim ", "James ")
      用逗號分隔字符串:
      arrpath=split(strDN,",")
      wscript.echo arrpath(0)
      讀取文本文件指定的行內(nèi)容(讀第四行內(nèi)容存到strLine變量中)
    Const ForReading = 1
    Set bjFSO = CreateObject("Scripting.FileSystemObject")
    Set bjTextFile = objFSO.OpenTextFile("C:\ScriptsTest.txt ", ForReading)
    For i = 1 to 3
    objTextFile.ReadLine
    Next
    strLine = objTextFile.Readline
    MsgBox strLine
    objTextFile.Close
      查看文件屬性
    Set bjFSO = CreateObject("Scripting.FileSystemObject")
    Set bjFile = objFSO.GetFile("c:\ScriptsTest.txt")
    msgbox "Date created: " & objFile.DateCreated
    msgbox "Date last accessed: " & objFile.DateLastAccessed
    msgbox "Date last modified: " & objFile.DateLastModified
    msgbox "Drive: " & objFile.Drive
    msgbox "Name: " & objFile.Name
    msgbox "Parent folder: " & objFile.ParentFolder
    msgbox "Path: " & objFile.Path
    msgbox "Short name: " & objFile.ShortName
    msgbox "Short path: " & objFile.ShortPath
    msgbox "Size: " & objFile.Size
    msgbox "Type: " & objFile.Type
      修改文件屬性
    Set bjFSO = CreateObject("Scripting.FileSystemObject")
    Set bjFile = objFSO.GetFile("C:\ScriptsTest.txt")
    If objFile.Attributes AND 1 Then
    objFile.Attributes = objFile.Attributes XOR 1
    End If
      寫入文本文件
    Const ForWriting=2
    Set bj=createobject("scripting.filesystemobject")
    Set bjfile=obj.opentextfile("C:\ScriptsTest.txt", ForWriting)
    objfile.write("This is line 1.")
    objfile.writeline("This is line2.")
    objfile.close
    版權(quán)聲明:本文出自 wpt1987 的51Testing軟件測試博客:http://www.51testing.com/?365260

    posted @ 2014-04-15 10:55 順其自然EVO 閱讀(881) | 評論 (0)編輯 收藏

    Python fabric實現(xiàn)遠程操作和部署

     fabric
      title是開發(fā),但是同時要干開發(fā)測試還有運維的活……為毛 task*3 不是 salary * 3 (o(╯□╰)o)
      近期接手越來越多的東西,發(fā)布和運維的工作相當(dāng)機械,加上頻率還蠻高,導(dǎo)致時間浪費還是優(yōu)點多。
      修復(fù)bug什么的,測試,提交版本庫(2分鐘),ssh到測試環(huán)境pull部署(2分鐘),rsync到線上機器A,B,C,D,E(1分鐘),分別ssh到ABCDE五臺機器,逐一重啟(8-10分鐘) = 13-15分鐘
      其中郁悶的是,每次操作都是相同的,命令一樣,要命的是在多個機器上,很難在本機一個腳本搞定,主要時間都浪費在ssh,敲命令上了,寫成腳本,完全可以一鍵執(zhí)行,花兩分鐘看下執(zhí)行結(jié)果
      直到,發(fā)現(xiàn)了fabric這貨
      作用
      很強大的工具
      可以將自動化部署或者多機操作的命令固化到一個腳本里
      和某些運維工具很像,用它主要是因為,python…..
      簡單好用易上手
      當(dāng)然,shell各種命令組合起來也可以,上古神器和現(xiàn)代兵器的區(qū)別
      環(huán)境配置
      在本機和目標機器安裝對應(yīng)包(注意,都要有)
      sudo easy_install fabric
      目前是1.6版本(或者用pip install,一樣的)
      安裝完后,可以查看是否安裝成功
      [ken@~$] which fab
      /usr/local/bin/fab
      裝完之后,可以瀏覽下官方文檔
      然后,可以動手了
      hello world
      先進行本機簡單操作,有一個初步認識,例子來源與官網(wǎng)
      新建一個py腳本: fabfile.py
      def hello():
      print("Hello world!")
      命令行執(zhí)行:
      [ken@~/tmp/fab$] fab hello
      Hello world!
      Done.
      注意,這里可以不用fabfile作為文件名,但是在執(zhí)行時需指定文件
    [ken@~/tmp/fab$] mv fabfile.py test.py
    fabfile.py -> test.py
    [ken@~/tmp/fab$] fab hello
    Fatal error: Couldn't find any fabfiles!
    Remember that -f can be used to specify fabfile path, and use -h for help.
    Aborting.
    [ken@~/tmp/fab$] fab -f test.py hello
    Hello world!
    Done.
      帶參數(shù):
      修改fabfile.py腳本:
      def hello(name, value):
      print("%s = %s!" % (name, value))
      執(zhí)行
    [ken@~/tmp/fab$] fab hello:name=age,value=20
    age = 20!
    Done.
    [ken@~/tmp/fab$] fab hello:age,20
    age = 20!
    Done.

     執(zhí)行本機操作
      簡單的本地操作:
    from fabric.api import local
    def lsfab():
    local('cd ~/tmp/fab')
    local('ls')
      結(jié)果:
    [ken@~/tmp/fab$] pwd;ls
    /Users/ken/tmp/fab
    fabfile.py   fabfile.pyc  test.py      test.pyc
    [ken@~/tmp/fab$] fab -f test.py lsfab
    [localhost] local: cd ~/tmp/fab
    [localhost] local: ls
    fabfile.py  fabfile.pyc test.py     test.pyc
    Done.
      實戰(zhàn)開始:
      假設(shè),你每天要提交一份配置文件settings.py到版本庫(這里沒有考慮沖突的情況)
      如果是手工操作:
      cd /home/project/test/conf/
      git add settings.py
      git commit -m 'daily update settings.py'
      git pull origin
      git push origin
      也就是說,這幾個命令你每天都要手動敲一次,所謂daily job,就是每天都要重復(fù)的,機械化的工作,讓我們看看用fabric怎么實現(xiàn)一鍵搞定:(其實用shell腳本可以直接搞定,但是fab的優(yōu)勢不是在這里,這里主要位后面本地+遠端操作做準備,畢竟兩個地方的操作寫一種腳本便于維護)
      from fabric.api import local
      def setting_ci():
      local("cd /home/project/test/conf/")
      local("git add settings.py")
      #后面你懂的,懶得敲了…..
      混搭整合遠端操作
      這時候,假設(shè),你要到機器A的/home/ken/project對應(yīng)項目目錄把配置文件更新下來
    #!/usr/bin/env python
    # encoding: utf-8
    from fabric.api import local,cd,run
    env.hosts=['user@ip:port',] #ssh要用到的參數(shù)
    env.password = 'pwd'
    def setting_ci():
    local('echo "add and commit settings in local"')
    #剛才的操作換到這里,你懂的
    def update_setting_remote():
    print "remote update"
    with cd('~/temp'):   #cd用于進入某個目錄
    run('ls -l | wc -l')  #遠程操作用run
    def update():
    setting_ci()
    update_setting_remote()
      然后,執(zhí)行之:
    [ken@~/tmp/fab$] fab -f deploy.py update
    [user@ip:port] Executing task 'update'
    [localhost] local: echo "add and commit settings in local"
    add and commit settings in local
    remote update
    [user@ip:port] run: ls -l | wc -l
    [user@ip:port] out: 12
    [user@ip:port] out:
    Done.
      注意,如果不聲明env.password,執(zhí)行到對應(yīng)機器時會跳出要求輸入密碼的交互
    多服務(wù)器混搭
      操作多個服務(wù)器,需要配置多個host
    #!/usr/bin/env python
    # encoding: utf-8
    from fabric.api import *
    #操作一致的服務(wù)器可以放在一組,同一組的執(zhí)行同一套操作
    env.roledefs = {
    'testserver': ['user1@host1:port1',],
    'realserver': ['user2@host2:port2', ]
    }
    #env.password = '這里不要用這種配置了,不可能要求密碼都一致的,明文編寫也不合適。打通所有ssh就行了'
    @roles('testserver')
    def task1():
    run('ls -l | wc -l')
    @roles('realserver')
    def task2():
    run('ls ~/temp/ | wc -l')
    def dotask():
    execute(task1)
    execute(task2)
      結(jié)果:
    [ken@~/tmp/fab$] fab -f mult.py dotask
    [user1@host1:port1] Executing task 'task1'
    [user1@host1:port1] run: ls -l | wc -l
    [user1@host1:port1] out: 9
    [user1@host1:port1] out:
    [user2@host2:port2] Executing task 'task2'
    [user2@host2:port2] run: ls ~/temp/ | wc -l
    [user2@host2:port2] out: 11
    [user2@host2:port2] out:
    Done.
      擴展
      1.顏色
      可以打印顏色,在查看操作結(jié)果信息的時候更為醒目和方便
      from fabric.colors import *
      def show():
      print green('success')
      print red('fail')
      print yellow('yellow')
      #fab -f color.py show
      2.錯誤和異常
      關(guān)于錯誤處理
      默認,一組命令,上一個命令執(zhí)行失敗后,不會接著往下執(zhí)行
      失敗后也可以進行不一樣的處理, 文檔
      目前沒用到,后續(xù)用到再看了
      3.密碼管理
      看文檔
      更好的密碼管理方式,哥比較土,沒打通,主要是服務(wù)器列表變化頻繁,我的處理方式是:
      1.host,user,port,password配置列表,所有的都寫在一個文件
      或者直接搞到腳本里,當(dāng)然這個更........
    env.hosts = [
    'host1',
    'host2'
    ]
    env.passwords = {
    'host1': "pwdofhost1",
    'host2': "pwdofhost2",
    }
    或者
    env.roledefs = {
    'testserver': ['host1', 'host2'],
    'realserver': ['host3', ]
    }
    env.passwords = {
    'host1': "pwdofhost1",
    'host2': "pwdofhost2",
    'host3': "pwdofhost3",
    }
      2.根據(jù)key解析成map嵌套,放到deploy中
      另外命令其實也可以固化成一個cmds列表的…

    posted @ 2014-04-15 10:52 順其自然EVO 閱讀(268) | 評論 (0)編輯 收藏

    僅列出標題
    共394頁: First 上一頁 125 126 127 128 129 130 131 132 133 下一頁 Last 
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導(dǎo)航

    統(tǒng)計

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 全免费一级毛片在线播放| 亚洲国产精品yw在线观看| 免费观看的毛片手机视频| 日本一区二区三区日本免费| 91精品免费观看| 日韩国产免费一区二区三区| 69影院毛片免费观看视频在线| 中文字幕一区二区免费| 51精品视频免费国产专区| 大陆一级毛片免费视频观看| gogo全球高清大胆亚洲| 久久综合AV免费观看| 免费国产成人午夜电影| 成人a免费α片在线视频网站| 免费一区二区三区四区五区| 亚洲热线99精品视频| 亚洲欧洲国产成人精品| 国产成人亚洲精品91专区高清| 亚洲综合一区国产精品| 一级做a爰黑人又硬又粗免费看51社区国产精品视| 亚洲精品天堂在线观看| 亚洲sss综合天堂久久久| 亚洲av无码久久忘忧草| 亚洲国产精品日韩在线| 老司机午夜精品视频在线观看免费| 亚洲av无码有乱码在线观看| 亚洲av中文无码乱人伦在线观看| 一区二区三区免费精品视频| 国产精品福利片免费看| 91麻豆最新在线人成免费观看| 99视频免费播放| 国产免费久久精品| 亚洲日韩涩涩成人午夜私人影院| 久久久久亚洲精品中文字幕| 亚洲午夜久久久影院| 亚洲1234区乱码| 99在线视频免费观看| 在线免费观看毛片网站| 亚洲av中文无码乱人伦在线咪咕| 亚洲国产精品99久久久久久| 国产成人精品无码免费看|