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

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

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

    qileilove

    blog已經轉移至github,大家請訪問 http://qaseven.github.io/

    Facebook推出JavaScript單元測試和自動化Mock工具Jest

     Facebook發布了Jest,一個開源的、基于Jasmine框架的JavaScript單元測試工具。
      Jest源于Facebook兩年前的構想,用于快速、可靠地測試Web聊天應用。它吸引了公司內部的興趣,Facebook的一名軟件工程師Jeff Morrison半年前又重拾這個項目,改善它的性能,并將其開源。
      在最基礎層面,Jest被設計用于快速、簡單地編寫地道的JavaScript測試。Jest自動模擬require()返回的CommonJS模塊,并提供了包括內置的測試環境Dom API支持、合理的默認值、預處理代碼和默認執行并行測試在內的特性。通過在并行進程中同時運行測試,Jest讓測試更快地結束。
      Morrison說:
      Jest的目標是減少開始測試一個項目所要花費的時間和認知負荷,因此它提供了大部分你需要的現成工具:快速的命令行接口、Mock工具集以及它的自動模塊Mock系統。
      此外,如果你在尋找隔離工具例如Mock庫,大部分其它工具將讓你在測試中(甚至經常在你的主代碼中)寫一些不盡如人意的樣板代碼,以使其生效。
      我們已經在Facebook親眼看到花更多的時間用于開發你的應用是多么重要(相對于花時間去準備開發你的應用),而這就是Jest關注并正在解決的問題。
      Jest與Jasmine框架的區別是在后者之上增加了一些層。最值得注意的是,運行測試時,Jest會自動模擬依賴。Jest自動為每個依賴的模塊生成Mock,并默認提供這些Mock,這樣就可以很容易地隔離模塊的依賴。Morrison說對于新測試,默認會進行隔離,開發人員現在也能夠“完全控制”需要隔離多少模塊。每個測試都可以指明哪些模塊應該或者不應該Mock。
      關于自動化Mock,Facebook的文檔有進一步的說明:
      實際上,Jest在測試環境中執行自己的require()函數。Jest的自定義require()函數加載真正的模塊,檢查它是什么樣子,然后基于它所看到的創建一個Mock版本并返回。也就是說,Jest將給你一個與真實模塊具有相同形狀的對象,但它模擬每一個Export值而不是實際的值。
      盡管Jest引入了自動化Mock,需要注意的是,開發者仍然可以使用jest.mock()和jest.dontMock()控制哪些應該或者不應該進行Mock。
      來自社區的反應絕大部分都很正面。在Hacker News,用戶Cthulu說:
      看起來很有趣:我們現在的AngularJS項目的測試套件越來越慢,部分原因是逐漸增加的測試,但主要的性能瓶頸是:
      沒有并行,即使測試套件全部是獨立的;
      DOM測試,導致大量的GC暫停;
      (可能是)PhantomJS啟動和初始化(未度量)。
      我已經做了簡單的優化,將我的那些測試分成兩半,開兩個終端運行(開發時和持續測試中),但它看來有點玄。
      直接應對依賴注入和AngularJS,Facebook說:“Jest使用不同的方法來達到相同的結果。”對于Angular,依賴作為參數進行傳遞,因此測試很容易寫。然而,Facebook指出,為了Angular中函數的可測性,開發者必須遵循其特定模式,將其傳遞給Angular的依賴注入框架。Jest的解決方案略有不同:
      Jest也能以Angular相同的方式Mock依賴,但它使用CommonJS,而不是構建一個特定的模塊加載器。這讓你能夠測試任何使用CommonJS的現有代碼,不需要重度重構以使其兼容其它模塊系統。
      用戶Caiob認同關于Jest的樂觀情緒,他也是這種依賴注入方法的擁護者,他說:“Facebook能夠提升像Jasmine這樣的現有/熟悉的工具,這非常棒。并且,我喜歡他們處理CommonJS模塊的方式。”
      Morrison說,通過Jest,Facebook希望開始這樣一種趨勢,讓測試變得更簡單,讓開發者有更多時間開發應用。讀者如果想參與這個項目,可以檢出Github庫并發送Pull請求,或者在Freenode加入#jestjs。

    posted @ 2014-06-18 10:47 順其自然EVO 閱讀(236) | 評論 (0)編輯 收藏

    Window下安裝bugzilla

    一. 說明
      本講解是在Windows2003 sp1操作系統下進行Bugzillal環境的搭建,其他操作系統和各使用軟件間的版本兼容沒有進行測試,如遇到問題可以大家共同討論學習。
      二. 操作系統及使用軟件
      Windows 2003 中文企業版 +sp1
      ActivePerl-5.8.8.817-MSWin32-x86-257965.msi
      Mysql 4.1.19
      Bugzilla-2.20.2
      這里用到的軟件在同目錄software文件夾下
      三. 正式開始搭建環境
      推薦更改以下所有軟件的默認安裝路徑,不要放在系統盤。此處我將安裝主目錄設在 D盤下,本文下面的路徑均為此路徑,自行安裝更改為其他路徑后請配置時也作相應修改。
      還要說一下,在win下搭建bugzilla確實太難了,因為本來就不是為工作在win下而設計的,bugzilla也是在最近幾個版本才加強了對win的支持。
      3.1 安裝IIS
      我們這里是使用IIS發布bugzilla,Win2003默認不安裝iis,所以我們需要首先在Win組件中安裝,這個比較簡單我就不詳細說了。
      控制面板-〉添加刪除程序—〉添加刪除win組件-〉應用程序服務器-〉IIS。勾選上點擊下一步即可。
      3.2 安裝ActivePerl
      我這里安裝的是ActivePerl-5.8.8.817-MSWin32-x86-257965.msi。修改安裝路徑為:D:\usr\(根據國際習慣,也可以自己修改)。
      3.3      安裝mysql數據庫
      這個比較簡單,雙擊安裝程序,選擇Custom安裝,最好更改安裝路徑。之后就是安裝。
      安裝過程中會讓你注冊帳號,我選擇跳過。安裝完成后選擇配置mysql
      選擇standard configuration即可,如果想更為詳細的配置可以選擇detail,這里我們就不詳細講了。
      點擊next進入安裝數據庫服務配置,制定服務的名字,是否以后可以通過命令行操作mysql,我們都勾選安裝
      再點擊next進入帳戶設置,必須為root用戶設置一個密碼,建議使用比較強壯的密碼。
      next后就可以點擊execute來執行剛才你所做的設置了。
      mysql安裝全部完成。
      3.4 Mysql的配置:
      打開mysql的command line client
      輸入之前設置好的root密碼,創建數據庫bugs,用戶bugs,密碼為空。并賦予這個用戶一定的權限。(因為bugzilla配置文件中默認是數據庫bugs,用戶bugs,密碼為空,所以我們在這里設置好后往下進行就會較方便了。)
      創建數據庫:
      mysql>create database bugs;
      創建用戶并賦予權限:
      mysql> GRANT SELECT,INSERT,UPDATE,DELETE,INDEX, ALTER,CREATE,DROP,REFERENCES,LOCK TABLES,CREATE TEMPORARY TABLES ON bugs.* TObugs@localhostIDENTIFIED BY '';
      刷新一下:
      mysql> FLUSH PRIVILEGES;
      mysql的設置就完成了。
    3.5  安裝bugzilla
      將bugzilla 2.20.1文件夾所有文件全部拷貝到D:\bugzilla\下。在 開始-〉程序-〉運行 中輸入CMD,進入D:\bugzilla目錄下,運行 perl checksetup.pl 檢查bugzilla安裝所需模塊是否都已找到,默認情況下是需要安裝許多模塊的,不用著急,這里我已經把所需模塊都放到software文件夾下了:bugzilla-bundle.zip。解壓縮這個zip包,放到D盤下,打開CMD,定位到這里,運行ppm,在ppm>下依次輸入并回車:
    install AppConfig.ppd
    install DBI.ppd
    install GD.ppd
    install GDTextUtil.ppd
    install MailTools.ppd
    install PatchReader.ppd
    install Template-Toolkit.ppd
    install TimeDate.ppd
    install Chart.ppd
    install DBD-mysql.ppd
    install GDGraph.ppd
    install MIME-tools.ppd
      即可安裝完所有模塊(中間可能某一個模塊會提示安裝失敗,這時請安裝完其他模塊后再重新安裝失敗的模塊) 。
      再從命令行到D:\bugzilla\下運行 perl checksetup.pl,檢查是否需要的模塊都已經安裝并找到了。是的話則會在目錄下生成一個localconfig文件,這個文件是bugzilla運行時的配置文件。打開這個文件我們只需看一下用戶名和密碼那塊是否和我們在mysql中設置的一樣即可。
      再次運行 perl checksetup.pl 會生成bugzilla需要的模版和數據庫中的表。
      輸入exchange服務器(這個不要輸入錯誤,因為bugzilla以后很多的操作都是需要發送郵件的,比如新建一個account后初始密碼是發送到你的郵箱里的)。接著會讓你輸入管理員的郵箱地址,名字,密碼
      確認輸入后即完成bugzilla的安裝了。
      再次輸入perl checksetup.pl 確認數據庫已經連接正常。修改D:\bugzilla\目錄下所有cgi文件,去掉第一行的最后一個字符T。可以使用UE中“在多文件里替換”功能。
      3.6  配置IIS發布bugzilla
      打開IIS管理器,在默認網站下新建一個虛擬目錄 ,名稱為bugzilla(怎樣發布你可以根據自己的需要來設置,這里我就先說我是怎樣設置的,大概原理都一樣),勾選虛擬目錄的權限為“寫入”(這個比較重要,不然后面的漢化無法設置),路徑定位到D:\bugzilla\
      在iis上右鍵選擇“默認網站”-〉“屬性”,點擊“主目錄”下面的“配置”,“添加”對cgi擴展名的解析
      在“文檔”中添加默認主頁:index.cgi,并移到上面。
      在web服務擴展中開啟對perl的支持
      好了,打開IE,在地址欄中輸入http://127.0.0.1/bugzilla(因為我是設置為默認網站下的一個虛擬目錄,所以要多加一個/bugzilla)察看一下吧,應該出現bugzilla的主頁了吧
      漢化比較簡單,將漢化包(建議使用UTF8的那個)解壓縮到bugzilla\template\下,文件夾更名為cn(里面默認有一個en,解壓縮后注意查看一下結構是否一樣),使用管理員賬戶登錄bugzilla,點擊 Parameters(系統參數設置)鏈接,將 languages 一項的值改為 cn,保存即可,回過頭來看看你的bugzilla變成中文了吧。如果考慮到安全問題,我們可以在把IIS中的“寫入”權限去掉。
      如果服務器是在域中,則還需要在IIS的屬性-〉目錄安全性-〉身份驗證和訪問控制 中勾選“集成Windows身份驗證”,這樣管理員在bugzilla中所作的修改才能生效。
      3.7 注意事項:
      在將bugzilla漢化完成后還需作一些調整:
      <Buzilla安裝目錄>\template\cn\default\list\table.html.tmpl。
      將其中的 "bug_status" => { maxlength => 4 } , 改為 "bug_status" => { maxlength => 16 } ; "resolution" => { maxlength => 4 } 改為"resolution" => { maxlength => 16 } , 即將這兩欄的長度由4改為16。存盤退出
      為保證向后兼容,按照Bugzilla官方的建議,2.20版Bugzilla的漢化文件全部存為 UTF-8 格式。將 <Bugzilla安裝目錄>\Bugzilla\CGI.pm 的第55行改為 $self->charset('UTF-8')
      打開 系統設置(Parameters), 找到 newchangedmail:一項, 將該項下文本框里面的 Subject: [Bug %bugid%] %summary% 改為 Subject: [Bug %bugid%] 吧, 或改為 Subject: Attention [Bug %bugid%] ---總之避開 %summary% 這個變量里面的漢字
      四. 總結:
      Bugzilla的測試環境搭建與安裝全部講述完畢,由于時間原因我沒有對不同版本間的兼容性作試驗,且這幾種開源軟件不同版本可能會有較大的變化,所以如果使用不同環境搭建時遇到問題,就只能大家一塊來討論解決了。

    posted @ 2014-06-18 10:47 順其自然EVO 閱讀(373) | 評論 (0)編輯 收藏

    Webdriver 自動化測試初試

     之前已經搭建了測試需要的環境,也學習了locateelements的方法,下面我們就來創建第一個簡單的自動化測試用例。
      測試場景如下:
      1.打開百度首頁
      2.在搜索框輸入關鍵字搜索,比如:webdriverautomationtesting
      3.點擊百度一下button
      4.驗證搜索結果是否包含輸入的關鍵字
      用例自動化測試代碼實例如下:
    packagecom.example.tests;
    importorg.openqa.selenium.By;
    importorg.openqa.selenium.WebDriver;
    importorg.openqa.selenium.firefox.FirefoxDriver;
    importorg.testng.Assert;
    importorg.testng.annotations.AfterMethod;
    importorg.testng.annotations.BeforeMethod;
    importorg.testng.annotations.Test;
    publicclassBaiDuSearchTest{
    privateWebDriverdriver;
    privateStringbaseUrl;
    @BeforeMethod
    publicvoidsetUp()throwsException{
    //LaunchFirefoxbrowser
    driver=newFirefoxDriver();
    baseUrl="http://www.baidu.com";
    }
    @Test
    publicvoidbaiDuSearchTest()throwsException{
    StringexResult="WebDriverautomationtesting";
    //Open百度homepage
    driver.get(baseUrl);
    //Locatesearchboxandinputsearchkeyword
    driver.findElement(By.id("kw1")).sendKeys("WebDriverautomationtesting");
    //Click百度一下button
    driver.findElement(By.id("su1")).click();
    //在結果頁面找到第一個link并驗證搜索關鍵字顯示在鏈接中
    StringactResult=driver.findElement(By.id("1")).getText();
    Assert.assertTrue(actResult.contains(exResult));
    }
    @AfterMethod
    publicvoidtearDown()throwsException{
    driver.quit();
    }
    }
      然后直接右擊該java文件選擇runasTestNGtest,然后可以查看自動化測試用例的執行了。
      最簡單的一個測試用例就到這里了。是不是很easy?

    posted @ 2014-06-18 10:46 順其自然EVO 閱讀(270) | 評論 (0)編輯 收藏

    深入剖析Java中的裝箱和拆箱

     自動裝箱和拆箱問題是Java中一個老生常談的問題了,今天我們就來一些看一下裝箱和拆箱中的若干問題。本文先講述裝箱和拆箱最基本的東西,再來看一下面試筆試中經常遇到的與裝箱、拆箱相關的問題。
      一.什么是裝箱?什么是拆箱?
      在前面的文章中提到,Java為每種基本數據類型都提供了對應的包裝器類型,至于為什么會為每種基本數據類型提供包裝器類型在此不進行闡述,有興趣的朋友可以查閱相關資料。在Java SE5之前,如果要生成一個數值為10的Integer對象,必須這樣進行:
      Integer i = new Integer(10);
      而在從Java SE5開始就提供了自動裝箱的特性,如果要生成一個數值為10的Integer對象,只需要這樣就可以了:
      Integer i = 10;
      這個過程中會自動根據數值創建對應的 Integer對象,這就是裝箱。
      那什么是拆箱呢?顧名思義,跟裝箱對應,就是自動將包裝器類型轉換為基本數據類型:
      Integer i = 10;  //裝箱
      int n = i;   //拆箱
      簡單一點說,裝箱就是  自動將基本數據類型轉換為包裝器類型;拆箱就是  自動將包裝器類型轉換為基本數據類型。
      下表是基本數據類型對應的包裝器類型:
      int(4字節)Integer
      byte(1字節)Byte
      short(2字節)Short
      long(8字節)Long
      float(4字節)Float
      double(8字節)Double
      char(2字節)Character
      boolean(未定)Boolean
      二.裝箱和拆箱是如何實現的
      上一小節了解裝箱的基本概念之后,這一小節來了解一下裝箱和拆箱是如何實現的。
      我們就以Interger類為例,下面看一段代碼:
    public class Main {
    public static void main(String[] args) {
    Integer i = 10;
    int n = i;
    }
    }
      反編譯class文件之后得到如下內容:
      從反編譯得到的字節碼內容可以看出,在裝箱的時候自動調用的是Integer的valueOf(int)方法。而在拆箱的時候自動調用的是Integer的intValue方法。
      其他的也類似,比如Double、Character,不相信的朋友可以自己手動嘗試一下。
      因此可以用一句話總結裝箱和拆箱的實現過程:
      裝箱過程是通過調用包裝器的valueOf方法實現的,而拆箱過程是通過調用包裝器的 xxxValue方法實現的。(xxx代表對應的基本數據類型)。


     三.面試中相關的問題
      雖然大多數人對裝箱和拆箱的概念都清楚,但是在面試和筆試中遇到了與裝箱和拆箱的問題卻不一定會答得上來。下面列舉一些常見的與裝箱/拆箱有關的面試題。
      1.下面這段代碼的輸出結果是什么?
    public class Main {
    public static void main(String[] args) {
    Integer i1 = 100;
    Integer i2 = 100;
    Integer i3 = 200;
    Integer i4 = 200;
    System.out.println(i1==i2);
    System.out.println(i3==i4);
    }
    }
      也許有些朋友會說都會輸出false,或者也有朋友會說都會輸出true。但是事實上輸出結果是:
      為什么會出現這樣的結果?輸出結果表明i1和i2指向的是同一個對象,而i3和i4指向的是不同的對象。此時只需一看源碼便知究竟,下面這段代碼是Integer的valueOf方法的具體實現:
      而其中IntegerCache類的實現為:
      從這2段代碼可以看出,在通過valueOf方法創建Integer對象的時候,如果數值在[-128,127]之間,便返回指向IntegerCache.cache中已經存在的對象的引用;否則創建一個新的Integer對象。
      上面的代碼中i1和i2的數值為100,因此會直接從cache中取已經存在的對象,所以i1和i2指向的是同一個對象,而i3和i4則是分別指向不同的對象。
      2.下面這段代碼的輸出結果是什么?
    public class Main {
    public static void main(String[] args) {
    Double i1 = 100.0;
    Double i2 = 100.0;
    Double i3 = 200.0;
    Double i4 = 200.0;
    System.out.println(i1==i2);
    System.out.println(i3==i4);
    }
    }
      也許有的朋友會認為跟上面一道題目的輸出結果相同,但是事實上卻不是。實際輸出結果為:
      View Code
      至于具體為什么,讀者可以去查看Double類的valueOf的實現。
      在這里只解釋一下為什么Double類的valueOf方法會采用與Integer類的valueOf方法不同的實現。很簡單:在某個范圍內的整型數值的個數是有限的,而浮點數卻不是。
      注意,Integer、Short、Byte、Character、Long這幾個類的valueOf方法的實現是類似的。
      Double、Float的valueOf方法的實現是類似的。
      3.下面這段代碼輸出結果是什么:
    public class Main {
    public static void main(String[] args) {
    Boolean i1 = false;
    Boolean i2 = false;
    Boolean i3 = true;
    Boolean i4 = true;
    System.out.println(i1==i2);
    System.out.println(i3==i4);
    }
    }
      輸出結果是:
      至于為什么是這個結果,同樣地,看了Boolean類的源碼也會一目了然。下面是Boolean的valueOf方法的具體實現:
      而其中的 TRUE 和FALSE又是什么呢?在Boolean中定義了2個靜態成員屬性:
      至此,大家應該明白了為何上面輸出的結果都是true了。
      4.談談Integer i = new Integer(xxx)和Integer i =xxx;這兩種方式的區別。
      當然,這個題目屬于比較寬泛類型的。但是要點一定要答上,我總結一下主要有以下這兩點區別:
      1)第一種方式不會觸發自動裝箱的過程;而第二種方式會觸發;
      2)在執行效率和資源占用上的區別。第二種方式的執行效率和資源占用在一般性情況下要優于第一種情況(注意這并不是絕對的)。
      5.下面程序的輸出結果是什么?
    public class Main {
    public static void main(String[] args) {
    Integer a = 1;
    Integer b = 2;
    Integer c = 3;
    Integer d = 3;
    Integer e = 321;
    Integer f = 321;
    Long g = 3L;
    Long h = 2L;
    System.out.println(c==d);
    System.out.println(e==f);
    System.out.println(c==(a+b));
    System.out.println(c.equals(a+b));
    System.out.println(g==(a+b));
    System.out.println(g.equals(a+b));
    System.out.println(g.equals(a+h));
    }
    }
      先別看輸出結果,讀者自己想一下這段代碼的輸出結果是什么。這里面需要注意的是:當 "=="運算符的兩個操作數都是 包裝器類型的引用,則是比較指向的是否是同一個對象,而如果其中有一個操作數是表達式(即包含算術運算)則比較的是數值(即會觸發自動拆箱的過程)。另外,對于包裝器類型,equals方法并不會進行類型轉換。明白了這2點之后,上面的輸出結果便一目了然:
      第一個和第二個輸出結果沒有什么疑問。第三句由于  a+b包含了算術運算,因此會觸發自動拆箱過程(會調用intValue方法),因此它們比較的是數值是否相等。而對于c.equals(a+b)會先觸發自動拆箱過程,再觸發自動裝箱過程,也就是說a+b,會先各自調用intValue方法,得到了加法運算后的數值之后,便調用Integer.valueOf方法,再進行equals比較。同理對于后面的也是這樣,不過要注意倒數第二個和最后一個輸出的結果(如果數值是int類型的,裝箱過程調用的是Integer.valueOf;如果是long類型的,裝箱調用的Long.valueOf方法)。
      如果對上面的具體執行過程有疑問,可以嘗試獲取反編譯的字節碼內容進行查看。

    posted @ 2014-06-17 11:47 順其自然EVO 閱讀(236) | 評論 (0)編輯 收藏

    使用Python Selenium進行自動化功能測試

     Why Automation Testing
      現在似乎大家都一致認同一個項目應該有足夠多的測試來保證功能的正常運作,而且這些此處的‘測試’特指自動化測試;并且大多數人會認為如果還有哪個項目依然采用人工測試來保證代碼的正確性的話,那簡直是太落后了,太不可思議了。
      但是在我現在的項目里,之前大部分的情況下我們還是在使用手動測試,項目依然在每周一次井然有序的上線著。當然有部分原因是因為項目業務和技術上的特殊性,但是這開始讓我思考:我們究竟為什么要進行自動化?什么情況下該進行自動化?自動化測試使用與所有的測試場景嗎?
      我認為自動化測試對我們的項目之所以重要,有幾點原因:
      Automated Software Testing Saves Time
      我們的項目現在以每周一次的頻率上線,由于項目本身的特殊性,每次上線后就要進行一次大規模的手動測試來保證不會break任何已有功能。這樣的測試每周一次的重復著,測試的內容也毫無變化,這消耗了團隊成員大部分的時間和精力。所以引入自動化測試之后我們就能夠運行自動化測試來完成這些重復性的工作,節省了時間和不必要的勞動。
      Team Morale Improves
      并不是說如果沒有測試我們就對自己的代碼沒有了信心。但是無論多么厲害的程序員都沒有辦法保證自己的代碼能夠100%毫無差錯的運行,尤其是當這些代碼需要和一個已有的項目結合起來運作的時候。當我們的代碼和別的項目結合的時候,我們有時會擔心我們的代碼能夠單獨的運作,但是卻會在集成后破壞一些原有的功能。特別是在這種情況確實發生過之后,這樣的擔心又會被進一步放大。自動化運行的測試能夠在一定程度上保證我們的代碼是按照我們的期待運作的,這就加強了開發人員對自己的代碼的信心。并且這種信心不是出于程序員對自己的代碼的欣賞,而是自己的代碼能夠真的經受檢驗后正常運作。同時,這樣的信心也來自于自動化測試帶來的第三個好處:
      Increase Test Coverage
      正是因為自動化測試可以覆蓋到更多的人工測試需要花大量時間精力才能覆蓋到的測試范圍和深度,我們才能知道我們的代碼在一定程度上已經能夠經受住考驗了,才能對自己的代碼更有信心的繼續后續的集成和開發。
      Selenium + Python
      Selenium是一個自動化瀏覽器的工具,常被用來做web應用的自動化測試。它與其他的測試工具相比優勢主要在于:
      Selenium 測試直接在瀏覽器中運行,就像真實用戶所做的一樣。
      Selenium webdriver可以運行在各種不同的操作系統的眾多瀏覽器平臺上:
    Google Chrome 12.0.712.0+
    Internet Explorer 6, 7, 8, 9 - 32 and 64-bit where applicable
    Firefox 3.0, 3.5, 3.6, 4.0, 5.0, 6, 7
    Opera 11.5+
    HtmlUnit 2.9
    Android – 2.3+ for phones and tablets (devices & emulators)
    iOS 3+ for phones (devices & emulators) and 3.2+ for tablets (devices & emulators)
      另外,selenium提供多種編程語言支持:Java, Javascript, Ruby, PHP, Python, Perl , C#。
      在這么多的語言支持中,為什么我們選擇了python呢?
      首先,python是一門非常容易入門的面向對象的腳本語言。我在開始寫python+selenium之前完全沒有python的編程經驗,但是由于它的語法相當簡單,并且表意和英語十分接近,因此讓人能在簡單的學習之后就快速的上手。
      另外,作為一門腳本語言,相較于java來說就有了天生的優勢:解釋執行。這就意味著我寫了幾行代碼,只需要一行命令就可以快速的運行起來看到結果,而不像Java那樣需要漫長的編譯打包等過程。完成同樣的功能,python只需要一個py文件和一行命令,而java則需要整整一個project,然后編譯打包發布等等。就算使用maven,也要進行很多相關的配置,過程相當麻煩。
      在將python與selenium結合起來寫functional test時,只需要在機器上配置好python的環境,下載selenium(easy_install selenium),編寫測試代碼,然后一句簡單的命令:python xxx.py 就可以將測試代碼運行起來。

    How to Write Test Code
      首先,我們需要將selenium webdriver的依賴加入我們的測試代碼中:
      from selenium import webdriver
      webdriver組件包含了所有的WebDriver的實現,這樣我們就可以使用selenium webdriver為我們提供的瀏覽器交互等強大的功能了。
      driver = web driver.Firefox()
      driver.get("http://www.google.com")
      創建一個Firefox WebDriver的實例,driver.get方法將打開方法參數中給出的URL所指向的網頁。這行代碼將會等到指向的目標頁面完全加載后才會把控制還給后續的代碼。
      得到了我們想要打開的頁面后,我們就可以對網頁進行一些基礎的判斷:
      assert "Google" in driver.title
      這個斷言會判斷網頁的html <title>標簽中是否包含“Google”這個字符串。這種斷言很常見,可以用來判斷打開的是否是我們期待的頁面。
      之后,在目標頁面上,我們可以進一步的定位到每一個頁面元素,與這些元素進行交互來模仿用戶操作,測試元素的行為是否和我們預期的相符:
    searchInput = driver.find_element_by_id("lst-ib")
    searchInput.send_keys("selenium")
    searchBtn = driver.find_element_by_name("btnK")
    searchBtn.click()
      WebDriver提供了多種的定位到元素的方法:
      click()與send_keys()都是selenium.webdriver.common.action_chains.ActionChains中提供的與元素交互的方法。click()模擬了對一個元素的點擊,send_keys()模擬了向一個元素輸入一些鍵盤輸入。其他的交互方法可以查看API。
      最后,在完成了頁面操作之后我們可以使用driver.close()或是driver.quit()來退出。這兩者的區別是:close只關閉一個tab,quit則是關閉整個瀏覽器。
      A Simple Demo
      上面的代碼嚴格來說并不像我們常常寫的測試代碼,它只是打開了一個網頁并做了一些簡單的操作而已。我們可以使用python提供的標準unittest庫來把它寫得更符合我們的測試代碼的風格。使用unittest庫后,我們能在terminal中看到測試報告。
    import unittest
    from selenium import webdriver
    class GooglePageTest(unittest.TestCase):
    def setUp(self):
    self.driver = webdriver.Firefox()
    def test_click_all_links_on_page(self):
    driver = self.driver
    driver.get("http://www.google.com")
    length = len(driver.find_elements_by_tag_name("a"))
    for i in range(0,length):
    links = driver.find_elements_by_tag_name("a")
    if links[i].is_displayed():
    links[i].click()
    driver.back()
    self.assertIn("Google" or "YouTube",driver.title)
    def tearDown(self):
    self.driver.close()
    if __name__ == "__main__":
    unittest.main()
      這段代碼首先引入了unittest組件,然后使用我們熟悉的test case的風格寫了一個測試用例,測試了Google主頁上面的所有<a>標簽點擊,對每個打開的頁面檢查title中是否含有期待的關鍵字。測試結束后將自動關閉瀏覽器,并且在terminal中可以看到測試報告。

    posted @ 2014-06-17 11:47 順其自然EVO 閱讀(306) | 評論 (0)編輯 收藏

    php連接MSSQL數據庫的常用操作

    數據庫查詢不外乎4個步驟,1、建立連接。2、輸入查詢代碼。3、建立查詢并取出數據。4、關閉連接。
      php連接mssql數據庫有幾個注意事項,尤其mssql的多個版本、32位、64位都有區別。
      首先,php.ini文件中;extension=php_pdo_mssql.dll ;extension=php_pdo_odbc.dll 前面的分號去掉,對應的使哪種方式連接mssql。注意要重啟服務使其生效。
      一、建立連接
      1、odbc
      首先,在php程序所在的服務器設置odbc。這里32位和64位操作系統有區別。32位的從控制面板中管理工具中的數據源(odbc)直接建立就可以了,64位的要運行C:\Windows\SysWOW64\odbcad32.exe
      從這里面設置。注意:上面只的是數據庫服務器為32為的,數據源設置服務器為32位和64位兩種的情況。只要兩個服務器建立的數據源位數一致就好。
      下面是odbc建立連接代碼。
      $con = odbc_connect('odbc名稱','用戶名','密碼');
      2、連接mssql2000
      $con = mssql_connect('數據庫地址','用戶名','密碼');
      3、連接mssql2008
      $connectionInfo =  array("UID"=>用戶名,"PWD"=>密碼,"Database"=>"數據庫名稱");
      $con = sqlsrv_connect( 數據庫地址,$connectionInfo);
      二、輸入查詢代碼
      這個都一樣,可以直接寫入,也可以從mssql中驗證好后復制過來。簡單點說就是把一個sql語句賦值給一個變量。
      類似下面代碼
      $query = "SELECT top 12 * 數據庫名稱 order by id desc";
      三、建立查詢并取出數據
      1、odbc
      $result = odbc_do($con,$query);
      while(odbc_fetch_row($result))
      {
      $變量名稱 = odbc_result($result, "字段名稱");
      }
      2、連接mssql2000
      $result = mssql_query($con, $query);
      while($row =mssql_fetch_array($result))
      {
      $變量名稱 = $row["字段名稱"];
      }
      3、連接mssql2008
      $result = sqlsrv_query($con, $query);
      while($row = sqlsrv_fetch_array($result))
      {
      $變量名稱 = $row["字段名稱"];
      }
      在php5.3及以后的版本中不附帶sqlsrv庫了。所以要從微軟這里下載。
      四、關閉連接
      這個沒有什么區別,分別是odbc_close();和mssql_close()和sqlsrv_close();
      最后體會:php連接mssql比連接mssql的函數少了一些,但是也夠用了。具體函數可以參考php官方手冊或者oschina的php中文文檔。

    posted @ 2014-06-17 11:45 順其自然EVO 閱讀(295) | 評論 (0)編輯 收藏

    Tcpcopy兩種架構原理詳解 2

     Tcpcopy傳統架構在產品中實踐遇到一些問題,要理解和解決問題深入了解Tcpcopy兩種的架構的原理是必須的。當了解的越多就發現它不僅僅是一個工具,而需要掌握不僅僅是簡單的幾個使用命令。
      Tcpcopy傳統架構與新架構最大的區別:傳統架構的intercept進程與測試服務器在同一臺機器上,新架構的intercept進程從測試服務器上offload出來,單獨部署在輔助服務器上。下面分別對兩種結構的原理詳細介紹。
      傳統架構
      Tcpcopy
      傳統架構下,在線機器上面抓取請求數據包,默認采用raw socket input 接口。raw socket(原始套接字)可以接收本機網卡上的數據幀或者數據包,可監聽網絡的流量和分析。可以通過3種方式創建這類socket ,這里只詳細講tcpcopy使用的函數。Raw_socket的原理和其它使用方式,可參考 http://blog.sina.com.cn/s/blog_9599e95101010w2g.html
      抓包函數:int sock = socket(AF_INET,SOCK_RAW,IPPROTO_TCP)。 第一個參數表示協議簇, AF_INET 代表TCP/IP協議。第二個參數表示SOCKET類型。第三個參數表協議類型。該套接字可以接收協議類型為tcp(也可以設置其它協議類型)發往本機的IP數據包,不能收到非發往本機IP的數據包(IP軟過濾會丟棄這些不是發往本機的數據包)。Tcpcopy利用Raw Socket只抓進來的包,而不能收到從本機發送出去的數據包這一特點,實現抓包的功能。系統在IP層會檢查有沒有進程創建這種類型的raw socket,如果有,這個包就會被復制一份并發送到這個socket的緩沖區,Tcpcopy就是通過這種方式來復制訪問流量的。
      在發包前,調用函數sock = socket(AF_INET, SOCK_RAW,IPPROTO_RAW),并且設置setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &n, sizeof(n)),這樣IP數據包頭部就可以由用戶自己編寫(在不設置這個選項的情況下,IP協議會自動填充IP數據包的首部),Tcpcopy利用此函數將數據包的目的IP和端口改為測試機的IP和端口,如下:tcp_header->dest = remote_port;
      ip_header->daddr = remote_ip;最后調用sendto函數發送包到測試前端機:
      send_len = sendto(sock,(char *)ip_header,tot_len,0,(struct sockaddr *)&toaddr,sizeof(toaddr));
      Intercept
      測試機上Intercept進程主要完成的是對復制請求的響應包進行處理。復制的請求到達測試機經應用程序處理后的響應包如果不經處理,將會返回給線上客戶端。Tcpcopy傳統架構的使用需要Iptable這一工具輔助實現對響應包的處理。
      modprobe ip_queue
      iptables -I OUTPUT -p tcp –sport 2080 -j QUEUE
      以上iptable命令,表示OUTPUT鏈從2080端口發出的包在IP層會被匹配發往目標QUEUE,而QUEUE是由ip_queue模塊實現(http://bbs.chinaunix.net/thread-1941806-1-1.shtml).因此在使用iptable命令前,內核需要使用modprobbe命令加載ip_queue模塊。有了以上兩個步驟, 所有匹配到iptable命令的報文將會調用IP Queue模塊的相關函數。
      Tcpcopy服務器端的Intercept進程用如下方式創建Netlink socket:
      int sock = socket(AF_NETLINK,SOCK_RAW,NETLINK_FIREWALL);
      Netlink詳細介紹http://linux.chinaunix.net/techdoc/beginner/2008/11/12/1044982.shtml。
      NETLINK_FIREWALL協議有三種消息類型:IPQM_MODE,IPQM_PACKET,IPQM_VERDICT.其中內核通過IPQM_PACKET消息將剛才截獲的返回結果包發送到Inercept。Intercept給內核發送一個IPQM_VERDICT消息告訴內核對這個包的裁決結果(DROP,ACCEPT)。Tcpcopy通過這樣的辦法將測試機上應用返回的結果截獲丟棄,并由Intercept返回一個Ip header。 Tcpcopy利用這個特點保留了一個允許訪問的ip列表,因為默認情況下訪問測試前端機上應用服務所得到的結果會在IP層被drop掉,造成在2080端口上無法訪問應用服務。有了這個白名單,即使是設置了iptables規則,在白名單內的機器上也是可以正常訪問測試前端機上的應用服務的。
      新架構
      Tcpcopy
      新架構的Tcpcopy進程的實現與舊架構相比差別不大,在線機器上面抓請求數據包默認采用raw socket input 接口,增加了采用pcap 接口抓包的功能。Libpcap是Packet Capture Libray的英文縮寫,即數據包捕獲函數庫。該庫提供的C函數接口用于捕捉經過指定網絡接口的數據包,該接口應該是被設為混雜模式。常用的抓包軟件Tcpdump就是在Libpcap的基礎上開發而成的。Libpcap提供的接口函數實現和封裝了與數據包截獲有關的過程,工作原理不贅述,詳細可參考http://www.cnblogs.com/coder2012/archive/2013/04/13/3012390.html。根據使用手冊上的描述,新架構一般推薦使用Pcap抓包,安裝命令如下:
      ./configure --enable-advanced --enable-pcap
      make
      make install
      新架構和傳統架構一樣,默認使用Raw socket output 接口發包,采用Raw Socket命令發包命令如下: ./tcpcopy -x 80-測試機IP:測試機應用端口 -s 服務服務器IP -i eth0 。其中-i參數指定pcap從哪個網卡抓取請求包。
      此外,新架構還支持通過pcap_inject(編譯時候增加--enable-dlinject)來發包。使用pcap_inject發包有兩點好處:1.可以避開在線機器在IP層的防火墻設置,因為tcpcopy進程復制過來的包源IP還是線上客戶端的IP,在線機器上可能會被直接扔掉,在不能改變防火墻設置的情況下,采用pacp_inject直接從數據鏈路層發包,可以避開IP層復雜的防火墻設置;2.在壓力比較大的場合推薦使用pcap_inject 來發包,根據測試結果來看合理利用pcap_inject 來發包可提高30%的性能(詳見使用手冊),但是pcap_inject發包需要知道數據包從在線機器發出下一跳的網卡地址,這需要使用tcpdump工具抓包獲取.
      Pcap發包命令:sudo ./tcpcopy -x 在線端口號@在線機器的出口網卡地址-測試機器的IP地址:測試機器的端口@下一跳網卡地址 -s 運行intercept的機器IP地址 -o 出口網卡設備 -i 抓包網卡設備。
      測試服務器
      新架構測試機部署上,需要更改其路由設置,目的是將測試應用程序的響應包路由到輔助測試服務器。以外網應用為例如下:
      刪除測試服務器的外網IP的默認路由
      route del default gw 原外網網關IP
      添加輔助測試服務器IP作為測試服務器的默認路由
      route add default gw 輔助服務器的外網IP
      這里的意思就是說,在測試服務器返回給客戶端的響應走默認網關-輔助服務器的外網IP,但這臺機器其實并沒有開啟路由模式,所以這些響應包到了輔助測試機后,會在ip層被drop掉,這樣internet進程就可以在輔助測試服務器的數據鏈路層抓到這些響應包
      輔助服務器
      輔助服務器主要是用于捕獲測試服務器轉發過來的響應包,輔助服務器要確保沒有開啟路由模式cat /proc/sys/net/ipv4/ip_forward,為0表示沒有開啟。輔助服務器上采用的也是pcap抓取響應包,安裝命令如下:
      ./configure --enable-advanced --enable-pcap
      make
      make install
      輔助服務器intercept進程通過pcap抓取測試機應用程序的響應包,將頭部抽取后發送給線上的tcpcopy進程,完成一次請求的復制。
      小結:
      Tcpcopy兩種架構都是通過巧妙地應用一些網絡工具和包實現其復制轉發的功能,傳統架構rawsocket+iptable+netlink,新架構pacp+route,通過對其深入的了解也拓展了許多網絡知識,在之后遇到一些問題也可以比較清楚明白的去解釋和分析。
      對比兩種架構的原理和實踐中遇到的問題可以得出,傳統架構更容易實施,但是由于它借助于linux的IP_QUEUE模塊,其性能完全依賴于系統,在壓力較大時性能表現較差;而新架構將測試機和輔助服務器分離開來,性能有所提升,但是在部署實施受硬件條件制約,比如測試機和輔助測試服務器需在一個網段等,同時需要用到的網絡知識更多。在使用時,結合條件選擇合適的架構。
    相關文章:
    容量規劃概述

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

    使用Python Selenium進行自動化功能測試

    Why Automation Testing
      現在似乎大家都一致認同一個項目應該有足夠多的測試來保證功能的正常運作,而且這些此處的‘測試’特指自動化測試;并且大多數人會認為如果還有哪個項目依然采用人工測試來保證代碼的正確性的話,那簡直是太落后了,太不可思議了。
      但是在我現在的項目里,之前大部分的情況下我們還是在使用手動測試,項目依然在每周一次井然有序的上線著。當然有部分原因是因為項目業務和技術上的特殊性,但是這開始讓我思考:我們究竟為什么要進行自動化?什么情況下該進行自動化?自動化測試使用與所有的測試場景嗎?
      我認為自動化測試對我們的項目之所以重要,有幾點原因:
      Automated Software Testing Saves Time
      我們的項目現在以每周一次的頻率上線,由于項目本身的特殊性,每次上線后就要進行一次大規模的手動測試來保證不會break任何已有功能。這樣的測試每周一次的重復著,測試的內容也毫無變化,這消耗了團隊成員大部分的時間和精力。所以引入自動化測試之后我們就能夠運行自動化測試來完成這些重復性的工作,節省了時間和不必要的勞動。
      Team Morale Improves
      并不是說如果沒有測試我們就對自己的代碼沒有了信心。但是無論多么厲害的程序員都沒有辦法保證自己的代碼能夠100%毫無差錯的運行,尤其是當這些代碼需要和一個已有的項目結合起來運作的時候。當我們的代碼和別的項目結合的時候,我們有時會擔心我們的代碼能夠單獨的運作,但是卻會在集成后破壞一些原有的功能。特別是在這種情況確實發生過之后,這樣的擔心又會被進一步放大。自動化運行的測試能夠在一定程度上保證我們的代碼是按照我們的期待運作的,這就加強了開發人員對自己的代碼的信心。并且這種信心不是出于程序員對自己的代碼的欣賞,而是自己的代碼能夠真的經受檢驗后正常運作。同時,這樣的信心也來自于自動化測試帶來的第三個好處:
      Increase Test Coverage
      正是因為自動化測試可以覆蓋到更多的人工測試需要花大量時間精力才能覆蓋到的測試范圍和深度,我們才能知道我們的代碼在一定程度上已經能夠經受住考驗了,才能對自己的代碼更有信心的繼續后續的集成和開發。
      Selenium + Python
      Selenium是一個自動化瀏覽器的工具,常被用來做web應用的自動化測試。它與其他的測試工具相比優勢主要在于:
      Selenium 測試直接在瀏覽器中運行,就像真實用戶所做的一樣。
      Selenium webdriver可以運行在各種不同的操作系統的眾多瀏覽器平臺上:
    Google Chrome 12.0.712.0+
    Internet Explorer 6, 7, 8, 9 - 32 and 64-bit where applicable
    Firefox 3.0, 3.5, 3.6, 4.0, 5.0, 6, 7
    Opera 11.5+
    HtmlUnit 2.9
    Android – 2.3+ for phones and tablets (devices & emulators)
    iOS 3+ for phones (devices & emulators) and 3.2+ for tablets (devices & emulators)
      另外,selenium提供多種編程語言支持:Java, Javascript, Ruby, PHP, Python, Perl , C#。
      在這么多的語言支持中,為什么我們選擇了python呢?
      首先,python是一門非常容易入門的面向對象的腳本語言。我在開始寫python+selenium之前完全沒有python的編程經驗,但是由于它的語法相當簡單,并且表意和英語十分接近,因此讓人能在簡單的學習之后就快速的上手。
      另外,作為一門腳本語言,相較于java來說就有了天生的優勢:解釋執行。這就意味著我寫了幾行代碼,只需要一行命令就可以快速的運行起來看到結果,而不像Java那樣需要漫長的編譯打包等過程。完成同樣的功能,python只需要一個py文件和一行命令,而java則需要整整一個project,然后編譯打包發布等等。就算使用maven,也要進行很多相關的配置,過程相當麻煩。
      在將python與selenium結合起來寫functional test時,只需要在機器上配置好python的環境,下載selenium(easy_install selenium),編寫測試代碼,然后一句簡單的命令:python xxx.py 就可以將測試代碼運行起來。
      How to Write Test Code
      首先,我們需要將selenium webdriver的依賴加入我們的測試代碼中:
      from selenium import webdriver
      webdriver組件包含了所有的WebDriver的實現,這樣我們就可以使用selenium webdriver為我們提供的瀏覽器交互等強大的功能了。
      driver = web driver.Firefox()
      driver.get("http://www.google.com")
      創建一個Firefox WebDriver的實例,driver.get方法將打開方法參數中給出的URL所指向的網頁。這行代碼將會等到指向的目標頁面完全加載后才會把控制還給后續的代碼。
      得到了我們想要打開的頁面后,我們就可以對網頁進行一些基礎的判斷:
      assert "Google" in driver.title
      這個斷言會判斷網頁的html <title>標簽中是否包含“Google”這個字符串。這種斷言很常見,可以用來判斷打開的是否是我們期待的頁面。
      之后,在目標頁面上,我們可以進一步的定位到每一個頁面元素,與這些元素進行交互來模仿用戶操作,測試元素的行為是否和我們預期的相符:
    searchInput = driver.find_element_by_id("lst-ib")
    searchInput.send_keys("selenium")
    searchBtn = driver.find_element_by_name("btnK")
    searchBtn.click()
      WebDriver提供了多種的定位到元素的方法:
      click()與send_keys()都是selenium.webdriver.common.action_chains.ActionChains中提供的與元素交互的方法。click()模擬了對一個元素的點擊,send_keys()模擬了向一個元素輸入一些鍵盤輸入。其他的交互方法可以查看API。
      最后,在完成了頁面操作之后我們可以使用driver.close()或是driver.quit()來退出。這兩者的區別是:close只關閉一個tab,quit則是關閉整個瀏覽器。
      A Simple Demo
      上面的代碼嚴格來說并不像我們常常寫的測試代碼,它只是打開了一個網頁并做了一些簡單的操作而已。我們可以使用python提供的標準unittest庫來把它寫得更符合我們的測試代碼的風格。使用unittest庫后,我們能在terminal中看到測試報告。
    import unittest
    from selenium import webdriver
    class GooglePageTest(unittest.TestCase):
    def setUp(self):
    self.driver = webdriver.Firefox()
    def test_click_all_links_on_page(self):
    driver = self.driver
    driver.get("http://www.google.com")
    length = len(driver.find_elements_by_tag_name("a"))
    for i in range(0,length):
    links = driver.find_elements_by_tag_name("a")
    if links[i].is_displayed():
    links[i].click()
    driver.back()
    self.assertIn("Google" or "YouTube",driver.title)
    def tearDown(self):
    self.driver.close()
    if __name__ == "__main__":
    unittest.main()
      這段代碼首先引入了unittest組件,然后使用我們熟悉的test case的風格寫了一個測試用例,測試了Google主頁上面的所有<a>標簽點擊,對每個打開的頁面檢查title中是否含有期待的關鍵字。測試結束后將自動關閉瀏覽器,并且在terminal中可以看到測試報告。

    posted @ 2014-06-17 10:13 順其自然EVO 閱讀(327) | 評論 (0)編輯 收藏

    手機APP測試體系

      軟件測試這個職業,相信大家都很熟悉了,只是傳統的手工測試大家比較多見,覺得測試就是小case了,不就是拿著設備用手指點來點去嗎?或者拿著鼠標在屏幕上不斷點擊嗎?真有大家想象得那么簡單嗎?點擊這事,也要知道你要怎么點,點了這個,下一個要點哪個?也要經過整體的規劃的是吧!
      其實測試就是一項有計劃有活動,所有計劃,就是要做很多準備工作的,比如:寫測試計劃,測試用例,測試用例又分很多種了。下面簡單對android手機客戶端測試做個全面的測試介紹。見下圖。

    posted @ 2014-06-17 10:05 順其自然EVO 閱讀(225) | 評論 (0)編輯 收藏

    談分布式測試體系構建

     自谷歌提出云計算概念之后,大數據領域的發展就逐漸加速日新月異,云計算具體到實例,可以歸納為調度、均衡、容錯、監控、運維等一整套操作海量數據的方案。有別于傳統小規?;蚬铝Ⅲw系產品,云計算生態圈存在錯綜復雜的系統級別關聯,并行其中的不同架構和模塊流轉于超大規模的分布式軟硬體資源中,很難劃分出明顯的界限。對于這樣的產品體系,傳統領域的測試方案要么逐漸失效,要么作用域縮減到僅能覆蓋體系末端。為了保證大數據平臺的可靠性、穩定性和高性能,亟需構建一套與之相匹配的測試體系來衡量產品是否合格。
      存在的問題
      業界在大數據測試領域的探索始終沒有停止過,以hadoop生態圈為例,與之相關的各類測試工具自成一體,例如Hadoop本身通過mock出MiniCluster(包括MR和HDFS)用來為開發代碼做功能驗證,DFSIO/Slive等用來做壓力和性能測試;HBase則通過一系列模擬隨機/順序讀寫相關的工具來做性能測試。而我們自己的ODPS則通過HiveUT來完成功能覆蓋和有限的性能驗證。仔細梳理這些工具不難發現存在一些問題,列舉如下:
      1.這些獨立的測試工具和體系很難被其他產品復用,比如說驗證hadoop功能的MiniCluster上是不能搭建HBase的,也不能跑Hive。MR輸出的默認Counters很難在HBase的測試調優中發揮作用。
      2.各種工具之間對比性較差,例如DFSIO和Slive的輸出結果幾乎沒有什么關聯性;還有的時候同一個工具測不同版本,判斷耗時、資源占用狀況幾乎相同,實際上某些第三方指標出現了變化,工具卻不能很好的反映出來。
      3.各種工具自身的運行效率無評判標準,被測目標無第三方監控依據。缺乏系統的繪制性能趨勢圖的能力。
      4.傳承性不夠,跨產品使用的可能性較小,例如HBase的測試中,很少對HDFS的性能做一個預判,原因是相關的人員缺乏對HDFS體系的了解,對其工具可起到的測試作用缺乏理解。
      5.工具易用性較差,幾乎所有類似獨立體系工具由于想在廣度上覆蓋盡量多的應用場景,因此使用了大量的參數用于配合用戶不同的測試目的。
      6.此類工具往往依賴產品自身架構來進行相關測試,缺乏完全獨立于產品本身的第三方驗證方式,如果產品相關聯部分發生了變動,要么造成基于老版本的工具失效,要么可能會影響到測試結果的準確性。
      諸如以上所述的問題,幾乎存在于大數據測試領域的每一個角落,對于阿里數據平臺的相關產品來說,隨著時間的推移規模的擴大和業務的日漸繁忙,測試上的這些缺陷越來越無法容忍,構建一套與之匹配的分布式測試框架體系就成為了必經之路。為了構造這樣一個測試體系,分布式測試框架與集群管理(DST)于2012年初應聲而出,從雛形開始一步步構造成為如今擁有數十個頁面、數萬次構建、數千測試場景和報告,既可以應對復雜業務場景,也可以滿足小版本單一功能快速集測需求的自動化測試框架體系。
      歷史溯源
      解決上述存在的問題,構造與之匹配的測試體系,就要從分布式測試框架與集群管理(DST)的歷史說起,因為DST的發展過程恰恰正是解決上述問題的軌跡。以下是里程碑級別事件的時間線:
      2012年1月,DST開始立項,第一行代碼提交版本控制
      2012年3月,場景管理(用于構造測試用例)和實驗室管理(用于調度執行測試)制作完成
      2012年4月,指標配置器和指標計算模板配置功能完成
      2012年5月,第一次執行從場景到調度,如今可供查閱這份古老的測試報告:隱藏
      2012年5月,ganglia監控數據導入HBase成功,可供查閱第一份有監控數據的測試報告:隱藏
      2012年7月,生成集測報告功能上線,最古老的一份集測報告:隱藏
      2012年7月底,三線(BI線、廣告線、搜索線)回歸納入DST調度體系,首次實現業務線自動化回歸
      2012年8月,實現基線對比功能,多個版本測試結果可自動進行趨勢對比
      2012年11月,數據魔方業務線回歸納入DST調度體系(由于對比工具的復雜性導致納入體系的難度很大)
      2013年1月,DST接入Kelude體系使用kelude接口進行用戶認證管理和通知等功能
      2013年2月,實現測試報告評審體系,通過工具引導流程,迫使測試報告必須通過開發、運維、測試的三方會審
      2013年上半年,隨著云梯1跨機房項目啟動,DST最高接受超過7000臺機器的平均每臺150多個監控指標的同時導入
      2013年3月,配置管理上線,海量測試資源首次實現圖形化調度管理
      2013年12月,優化監控指標查詢系統,將分級查詢耗時優化到秒級查詢耗時
      2014年2月,集群管理上線,用戶可以自由分配測試資源組裝自己的測試集群,其中云梯1產品更實現了一鍵自動化部署
      綜上所述,最終構造成功的體系與架構可以從下面幾張圖來看:
    圖:DST的構成

      圖:DST的體系架構
     圖:工具引導過程
      問題的解決
      回到我們剛才提到的6個問題上,DST通過場景管理促使用例復用和使用便利程度得以提升,通過監控體系的創新和改進,促使海量監控數據得到有效的管理和查詢。此外,由第三方監控構成的性能評價系統能夠排除產品本身的干擾,可以更客觀的反應性能結果。
      DST在大數據分布式測試上有三個優點:
      1.分布式調度器。調度器采用總分的形式,由console調度多個agent執行測試代碼,這樣可以模擬出大并發產生的壓力。好處是測試代碼獨立于被測目標,可以防止受被測目標的干擾,且測試代碼的分發和結果的收集合并過程都由框架自動化實現,免去用戶自行做分布式測試時候對測試結果收集整理的煩惱。
      2.海量監控數據收集展示。DST將數據存儲到HBase中,利用HBase的高效率和高容量保證了超過7000臺機器的海量監控數據可以實時容納到DST系統中。數據經過壓縮整理,進一步提高了展示速度。業界在2013年2月左右出現一個開源產品OpenTSDB,有點類似這套系統。不同的是,OpenTSDB并沒有利用在大數據監控領域使用廣泛的成熟產品ganglia來收集監控數據,雖然在數據存儲和性能效率方面更好一些,但是并不適用云梯1產品線的測試。
      3.集群管理實現動態測試資源調整。云計算最大的特點是集群和計算資源的動態伸縮,對于測試來說,為了獲得不同規模下的性能數據,需要不斷調整測試資源的大小,而每一次調整過程通過人工去實現都非常繁瑣。DST通過集群管理實現了自動化調整測試資源,圖形界面使得配置更加直觀,測試資源的利用率狀況也可以一目了然。此外,用戶獨占互斥鎖的存在也避免了同一個資源被其他測試目標污染,有效保證測試的可靠性。
     DST在設計成功后,于2013年初引入其他非大數據產品中,依托高度自由的框架體系,幫助用戶在不同的產品中構建復雜的測試場景。
      
    圖:2014年4月新建實驗室與調度次數分布
      分布式測試體系架構成功后,DST進入了產品推廣階段,我們認為DST更適用于以下測試場景:
      1.被測目標是一個后端服務。無論是獨立單機還是多機集群,通過簡單的一鍵部署監控工具后,被測目標就將被納入DST監控體系。同時,可以通過簡單地配置將JMX端口監聽起來,用于收集JVM的各項指標信息。
      2.性能、壓力和穩定性測試。這些場景往往測試耗時較長,人工值守存在很大的困難,對結果數據的分析也比較困難。接入DST系統后,除了實現無人值守,自動報警通知用戶之外。當監控數據的量也比較大的時候,通過指標模板的自動化計算更方便閱讀和查找問題。穩定性測試更是可以揉入多個實驗室,通過不同工作機的調度實現非常復雜且真實的用戶實際使用場景。
      3.需要高效利用測試資源的產品。集群管理使得用戶間溝通成本大大降低,測試資源的利用狀況一目了然,每日報表更可以看到哪些產品的測試更為繁忙。
      4.多機聯合制造負載。被測目標需要足夠大的壓力才能得出準確的測試結果,而且測試場景構造復雜,通過LR之類工具實現,要么難度太大,要么根本不能實現。DST通過分布式調度器,將測試代碼自動分發,并實現結果的收集整理。而最關鍵的是,整套runner完全可以由用戶自行編碼訂制,自由度與方便性并存。
      5.有指標監控需求的產品。監控體系納入后,結果更加準確,有利于對被測目標的精致觀察。
      6.存在大數據工具的復用和傳承需求。由于DST中已經積累了數千個測試場景,因此用戶在接入相關產品時便可以利用已有的測試場景來驗證被測目標。例如,當Hive接入測試時,可以通過Hadoop的基準測試判斷環境是否已經完備,發現bug時也更方便定位是Hive還是Hadoop上的問題。
      前景展望
      DST架構體系的建成并非一蹴而就,期間經歷了復雜的論證、摸索、重構和優化。其中僅監控收集一塊,由于完全是創新的產品,在多次摸索中推翻了數種方案,對其進行的優化更是持續數月。在DST推進的過程中,業務測試的需求成為其改進優化的第一源動力。例如早期云梯1由于監控數據存儲在mysql中,導致100臺機器的監控數據僅需兩三周就可以撐爆mysql服務器,而每次測試報告的生成往往耗時達數小時。這一切在DST系統中,由于采用海量存儲的緣故,得以縮短到秒級展現。此外,由于調度的自動化,收集體系的自動化,測試環境運維的自動化,促使云梯1回歸集測從長達月余,縮短到最快4天以內。
      對于DST來說,目前將會跟隨項目腳步,逐步實現對云梯2相關的性能、壓力和穩定性測試的需求。未來的工作集中于三個方向,一個是納入神農監控體系,實現調度執行與神農監控數據的對應關系;第二個是指標的收集整理,云梯2相關指標數量巨大,理清這些將會方便用戶的測試目的性;第三個是構造各種測試場景,用于對云梯2進行多角度的驗證。
      分布式測試體系的構建依然任重而道遠,以數據為己任,為數據的流轉,計算的調度保駕護航是這套體系的價值所在。能跟隨這個世界級規模的海量數據平臺前行,見證這一切,既是人生之幸,也是責任之所在。

    posted @ 2014-06-17 10:03 順其自然EVO 閱讀(320) | 評論 (0)編輯 收藏

    僅列出標題
    共394頁: First 上一頁 99 100 101 102 103 104 105 106 107 下一頁 Last 
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導航

    統計

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 99精品视频免费在线观看| 久久久久亚洲av无码专区| 亚洲国产综合精品中文第一区| 四虎永久成人免费| 国产精品亚洲综合天堂夜夜| 免费在线观看a级毛片| 99在线视频免费观看视频| 亚洲Aⅴ在线无码播放毛片一线天| 成人免费视频69| 亚洲看片无码在线视频| 亚洲国产精品婷婷久久| 亚洲精品黄色视频在线观看免费资源| 免费一级全黄少妇性色生活片| 久久久久久免费视频| 亚洲欧洲无码一区二区三区| 精品亚洲麻豆1区2区3区| 在线观看亚洲成人| 亚洲人成无码久久电影网站| 国产片免费福利片永久| 成年人在线免费观看| 免费视频爱爱太爽了| 四虎一区二区成人免费影院网址| 国产AⅤ无码专区亚洲AV| 亚洲国产综合精品中文字幕| 四只虎免费永久观看| 日日操夜夜操免费视频| 最好免费观看高清在线| 亚洲jizzjizz少妇| 亚洲精华国产精华精华液 | 亚洲伊人久久大香线蕉影院| 国产亚洲福利一区二区免费看| 国产精品免费久久久久久久久| 免费一级毛片免费播放| 国产成人精品高清免费| 成人无遮挡毛片免费看| 成人男女网18免费视频| 国产91在线免费| 亚洲人成影院在线观看| 国产AV无码专区亚洲AWWW| 亚洲精品午夜国产VA久久成人 | 亚洲免费视频在线观看|