<ruby id="h6500"><table id="h6500"></table></ruby>
    1. <ruby id="h6500"><video id="h6500"></video></ruby>
          1. <progress id="h6500"><u id="h6500"><form id="h6500"></form></u></progress>
            • 軟件測試技術(shù)
            • 軟件測試博客
            • 軟件測試視頻
            • 開(kāi)源軟件測試技術(shù)
            • 軟件測試論壇
            • 軟件測試沙龍
            • 軟件測試資料下載
            • 軟件測試雜志
            • 軟件測試人才招聘
              暫時(shí)沒(méi)有公告

            字號: | 推薦給好友 上一篇 | 下一篇

            如何設計自動(dòng)化測試平臺和自動(dòng)化測試框架

            發(fā)布: 2011-3-11 09:56 | 作者: 網(wǎng)絡(luò )轉載 | 來(lái)源: 領(lǐng)測軟件測試網(wǎng)采編 | 查看: 227次 | 進(jìn)入軟件測試論壇討論

            領(lǐng)測軟件測試網(wǎng)

              最近利用些業(yè)余時(shí)間自己編寫(xiě)了一個(gè)小型自動(dòng)化測試框架,在設計過(guò)程中自己也漸漸對自動(dòng)化框架的作用有了些新的認識,希望能和大家分享一下。

              其實(shí)設計這個(gè)框架最初的動(dòng)機是來(lái)源于工作中的一個(gè)任務(wù)——同事讓我維護一個(gè)很久以前編寫(xiě)的“自動(dòng)化腳本”,難度不大,只是一串處理和過(guò)程,看懂代碼以后只需要修改個(gè)別邏輯和參數即可。但后來(lái)我想了想,這樣純粹只有過(guò)程的腳本,在開(kāi)發(fā)測試時(shí)用來(lái)當做小工具用不錯,但一旦需要建立穩定的自動(dòng)化測試機制,有大量功能點(diǎn)和測試數據的時(shí)候就會(huì )顯得力不從心。一個(gè)功能點(diǎn)對應一個(gè)腳本,新增功能點(diǎn)甚至測試數據都需要對應增加腳本,開(kāi)發(fā)維護的成本則會(huì )非常高。

              后來(lái)我自己嘗試去做了一個(gè)小型的自動(dòng)化測試框架,雖然花費了不少時(shí)間才實(shí)現了原來(lái)腳本的內容,但是磨刀不誤砍柴工,有了框架,接下來(lái)新增功能點(diǎn)的開(kāi)發(fā)工作量大大減輕。自己在設計該框架時(shí)也基本上是摸著(zhù)石頭過(guò)河,一邊思考自動(dòng)化框架究竟需要做什么,一邊也參考一些開(kāi)源自動(dòng)化框架例如Ruby Watir的設計方式,以下便是我總結的一些經(jīng)驗和心得。

              一、測試腳本與測試框架脫離

              我開(kāi)頭提到的那個(gè)“測試腳本”,從程序啟動(dòng),測試動(dòng)作執行,測試結果反饋都一手包干,例如對于A(yíng)1和A2兩個(gè)相似的功能點(diǎn),其測試代碼如下:

              功能A-1的腳本:A1Test.java

              public static void main(String[] args) throws Exception {

              // A1測試邏輯實(shí)現

              ……

              Class.forName("oracle.jdbc.driver.OracleDriver");

              String url = "jdbc:oracle:thin:@localhost:1521:cui";

              Connection conn = DriverManager.getConnection(url, "cui", "cui");

              ……

              }

              功能A-2的腳本:A2Test.java

              public static void main(String[] args) throws Exception {

              // A2測試邏輯實(shí)現

              ……

              Connection conn = null;

              try {

              Class.forName("oracle.jdbc.driver.OracleDriver");

              String connectionUrl = "jdbc:oracle:thin:@localhost:1521:cui";

              conn = DriverManager.getConnection(connectionUrl, "cui", "cui");

              ……

              }

              這樣一來(lái)A1和A2的測試腳本都可以獨立運行,也不需要什么自動(dòng)化框架,但是原本相似的A1和A2功能,卻因為這樣的架構要寫(xiě)兩次代碼,如果TestA1和TestA2由兩個(gè)不同的程序員編寫(xiě),那么即便是如上面所示連接一個(gè)相同的數據庫,每個(gè)人需要自己寫(xiě)出實(shí)現方式,且都可能有不同的代碼風(fēng)格,這樣極大增加了測試代碼的編寫(xiě)和維護成本。

              對于測試腳本而言,僅僅只需要負責測試邏輯本身,不應該負責諸如腳本啟動(dòng),管理的功能,同時(shí)降低提升測試腳本編寫(xiě)和維護成本,一些公用的方法例如數據庫連接等,都最好封裝成方法放在測試框架中,然后供測試腳本調用。

              我在編寫(xiě)自動(dòng)化腳本時(shí),將每個(gè)測試功能點(diǎn)腳本作為一個(gè)Scenario類(lèi)供測試框架調用的,測試框架可以根據用戶(hù)輸入或者任務(wù)設定選擇執行哪些腳本。

              TestFramework.excute(Scenario userInputScenarioName);

              同時(shí),對于如數據庫連接查詢(xún)這樣的操作,也都做了封裝,在每個(gè)Scenario腳本里,編寫(xiě)者可以通過(guò)1行代碼就能查詢(xún)想要的數據:

              在配置文件中填入數據庫信息:

              #別名 db_dev #類(lèi)型 Oracle #IP 127.0.0.1 #端口 1521 #數據庫名 db1 #用戶(hù)名 cui #密碼 cui

              在腳本文件中就可以這樣來(lái)訪(fǎng)問(wèn)數據庫:

              String id = DB("db_dev").getSingleResult("select id from ……");

              數據庫的鏈接,關(guān)閉工作都由框架進(jìn)行統一封裝。

              二、測試數據與測試腳本脫離

              測試腳本與測試框架脫離后,測試腳本更加專(zhuān)注于業(yè)務(wù)邏輯,但僅僅這樣是不是就夠了呢?對于同一個(gè)功能點(diǎn),我們往往也需要測很多數據,如果每個(gè)測試數據都“硬編碼”到測試腳本里,那么數據增加的時(shí)候又要將硬編碼的部分代碼復制粘貼,犯了和先前一樣的毛�。�

              // 測試腳本脫離測試框架后的A1Test

              class A1Test() {

              ……

              // 測試A的實(shí)現過(guò)程

              id = DB("db_dev").getSingleResult("select id from …… where coutry = 'CN'");

              Assert(id == 100000);

              id = DB("db_dev").getSingleResult("select id from …… where coutry = 'US'");

              Assert(id == 200000);

              id = DB("db_dev").getSingleResult("select id from …… where coutry = 'CA'");

              Assert(id == 300000);

              ……

              }

              我們可以看到,雖然測試腳本TestA1的確不再負責程序啟動(dòng)這樣的雜事,同時(shí)數據鏈接也更加方便和規范,但是對于多個(gè)用例(country值不同,需要校驗的id大小不同),仍然需要復制粘貼代碼來(lái)實(shí)現。

              因此我們也需要將測試數據從測試腳本中獨立出來(lái),實(shí)現“一個(gè)框架對應多個(gè)測試腳本,一個(gè)測試腳本對應多個(gè)測試數據”。

              對于這樣的測試數據,往往是相對整齊規范的,我們可以用Excel,txt等文件,用表格的方式存儲測試數據,然后寫(xiě)出程序逐行讀取(jxl可以支持Excel2003以前Excel文件的讀取),每一行就是單次測試所需的數據。

              用例ID 用例描述 是否執行 國家縮寫(xiě) 期望結果ID

            用例ID 用例描述 是否執行 國家縮寫(xiě) 期望結果ID
            1 測試CN對應ID y CN 100000
            2 測試US對應ID y US 200000
            3 測試CA對應ID y CA 300000

              我采用jxl去讀取Excel數據,同時(shí)再對參數取用的方法進(jìn)行簡(jiǎn)化和封裝,最終可以用例如param("期望結果")這樣的方式返回當前執行的數據行對應列的數據。

              // 測試數據與測試腳本脫離后的A1Test

              class A1Test() {

              ……

              // 測試A的實(shí)現過(guò)程

              id = DB("db_dev").getSingleResult("select id from …… where coutry = " + param("國家縮寫(xiě)"));

              Assert(id == param("期望結果ID"));

              ……

              }

              三、總結

              測試腳本從測試框架脫離,即是將“一個(gè)測試腳本負責整個(gè)測試執行過(guò)程”的設計思路變?yōu)椤皽y試腳本只負責業(yè)務(wù)邏輯,一個(gè)測試框架驅動(dòng)多個(gè)測試腳本完成測試”。當業(yè)務(wù)邏輯變化時(shí),我們可以只修改測試腳本和數據而無(wú)須修改測試框架,當測試數據需要增加和修改時(shí),我們可以只修改測試數據而無(wú)須修改測試腳本,這樣的思路歸根結底還是來(lái)源于面向對象,但不管怎樣,提高效率,降低成本才是最終的目的。

            延伸閱讀

            文章來(lái)源于領(lǐng)測軟件測試網(wǎng) http://kjueaiud.com/

            TAG: 自動(dòng)化


            關(guān)于領(lǐng)測軟件測試網(wǎng) | 領(lǐng)測軟件測試網(wǎng)合作伙伴 | 廣告服務(wù) | 投稿指南 | 聯(lián)系我們 | 網(wǎng)站地圖 | 友情鏈接
            版權所有(C) 2003-2010 TestAge(領(lǐng)測軟件測試網(wǎng))|領(lǐng)測國際科技(北京)有限公司|軟件測試工程師培訓網(wǎng) All Rights Reserved
            北京市海淀區中關(guān)村南大街9號北京理工科技大廈1402室 京ICP備10010545號-5
            技術(shù)支持和業(yè)務(wù)聯(lián)系:info@testage.com.cn 電話(huà):010-51297073

            軟件測試 | 領(lǐng)測國際ISTQBISTQB官網(wǎng)TMMiTMMi認證國際軟件測試工程師認證領(lǐng)測軟件測試網(wǎng)

            老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月
              <ruby id="h6500"><table id="h6500"></table></ruby>
              1. <ruby id="h6500"><video id="h6500"></video></ruby>
                    1. <progress id="h6500"><u id="h6500"><form id="h6500"></form></u></progress>