QTP自動化測試 軟件測試
一、QTP自動化測試流程
1)準備TestCase
- 在進行自動化之前,將測試內容進行文檔化,不建議直接錄制腳本
- 在錄制腳本之前設計好腳本,便于錄制過程的流暢
- 由于測試用例設計和腳本開發可能不是同一個人完成,便于團隊合作
- 便于后期的維護
- 文檔化的方式:TD或者文檔
2)配置QTP
QTP支持不同的開發環境,在正式錄制之前,需要根據被測程序的開發環境,選擇合適的Add-In,并進行加載。
3)錄制腳本
啟動QTP的錄制功能,按照Test Case的操作步驟描述執行,QTP自動記錄每一步操作,并自動生成VBScript腳本。
4)修改增強腳本
剛剛錄制好的腳本可能包含錯誤,或者沒有達到預期的目的,這就需要在錄制腳本的基礎上,進行修改增強
- 刪除錄制過程中多余的以及錯誤的操作,以最少的腳本完成任務
- 如果前面操作的輸出是后面操作的輸入,則需要使用變量或者輸出值來進行替換
- 不是所有的操作都可以通過錄制產生的,有些需要通過手工編碼實現這些功能
- 錄制產生的腳本是線性的,可以加入條件、循環控制語句,實現更復雜的流程
- 對腳本進行結構化
- 加入注釋,便于閱讀和維護
5)調試腳本
- 回放通過的腳本,不一定是正確的,也可能會包含錯誤
- 在測試腳本正式使用之前,要保證其本身的正確性
- 避免測試腳本故障和被測程序故障攪在一起,不容易定位
6)回放腳本
- 對于回放的錯誤,不要急于馬上提交Bug,首先要判斷是腳本本身的錯誤還是程序的錯誤,確認后再提交。
7)腳本維護
- 隨著工作的不斷推進,腳本量會越來越多
- 被測試程序的不斷更新,也需要更新相應的測試腳本
- 采用版本管理工具保存腳本,如CVS、VSS,可以隨時獲取歷史版本
- 采用統一的腳本架構
- 采用統一的命名規范
- 添加充分的注釋,避免時間久了,自己都不能馬上讀懂腳本。
二、QTP識別對象的原理
QTP里的對象有兩個概念,一個是Test Object(簡稱TO),一個是Runtime Object(簡稱RO)。
這兩個概念從字面上不大好理解,也容易混淆。
但從實際作用上來看,應該說TO就是是倉庫文件里定義的倉庫對象,RO是被測試軟件的實際對象。
QTP識別對象,一般是要求先在對象倉庫文件里定義倉庫對象,里面存有實際對象的特征屬性的值。
然后在運行的時候,QTP會根據腳本里的對象名字,在對象倉庫里找到對應的倉庫對象,
接著根據倉庫對象的特征屬性描述,在被測試軟件里搜索找到相匹配的實際對象,最后就可以對實際對象進行操作了。
倉庫對象TO一般在錄制/編寫腳本時加入倉庫文件,它不僅可以在錄制編寫時進行修改,
也可以在運行過程中進行動態修改,以匹配實際對象。
和TO、RO相關的幾個函數有:
GetTOProperty():取得倉庫對象的某個屬性的值
GetTOProperties():取得倉庫對象的所有屬性的值
SetTOProperty():設置倉庫對象的某個屬性的值
GetROProperty():取得實際對象的某個屬性的值
理解了TO的含義,你就可以自由的用SetTOProperty()定義TO,以靈活的操作RO
比如有個測試任務,窗口上有很多待檢查的記錄,每條記錄右邊都有一個Check按鈕,用來檢查各條記錄。
記錄個數不定,所以Check按鈕個數也就不定,只有一個Edit顯示記錄個數。
我們要對每條記錄進行檢查,也就是要點擊每個Check按鈕。
但是Check按鈕個數不定,不好錄制,而且個數可能也很多(上百個),即使能一一錄制,那也很麻煩。
那我有一個好辦法,只錄制一個按鈕對象,它設有兩個特征屬性 label=OK, index=0
然后用下面的腳本,就可以完成測試
buttnNum = CInt(JavaWindow("Test").JavaEdit("Record Num").GetROProperty("value"))
For buttonIndex = 0 to buttonNum - 1
JavaWindow("Test").JavaButton("Check").SetTOProperty("index", buttonIndex)
JavaWindow("Test").JavaButton("Check").Click
Next
或者窗口上有New、Modify、Delete、Check等好幾個按鈕,要把這幾個按鈕一一按過去
我在對象倉庫里只設置一個按鈕對象AnyButton,label特征屬性值填任意值,然后用下面腳本執行測試
JavaWindow("Test").JavaButton("AnyButton").SetTOProperty("label", "New")
JavaWindow("Test").JavaButton("AnyButton").Click
JavaWindow("Test").JavaButton("AnyButton").SetTOProperty("label", "Modify")
JavaWindow("Test").JavaButton("AnyButton").Click
JavaWindow("Test").JavaButton("AnyButton").SetTOProperty("label", "Delete")
JavaWindow("Test").JavaButton("AnyButton").Click
JavaWindow("Test").JavaButton("AnyButton").SetTOProperty("label", "Check")
JavaWindow("Test").JavaButton("AnyButton").Click
另外,QTP還支持腳本描述的方法來定義和訪問對象,即不需要在倉庫里定義,也能訪問和操作實際對象
( Written by yabest,http://yabest.net )
如上面兩個任務,可以如下實現
1. 不需要在倉庫里定義Check按鈕對象,直接用下面腳本來實現測試
buttonNum = CInt(JavaWindow("Test").JavaEdit("Record Num").GetROProperty("value"))
For buttonIndex = 0 to buttonNum - 1
JavaWindow("Test").JavaButton("label:=Check", "index:="+CStr(buttonIndex)).Click
Next
2. 不需要在倉庫里定義New、Modify、Delete、Check按鈕對象,直接用下面腳本來實現測試
JavaWindow("Test").JavaButton("label:=New").Click
JavaWindow("Test").JavaButton("label:=Modify").Click
JavaWindow("Test").JavaButton("label:=Delete").Click
JavaWindow("Test").JavaButton("label:=Check").Click
三、QTP自動化發展方向
1. 入門,初識自動化相信很多的朋友,包括我自己也是一樣,在剛聽到或接觸到自動化測試的時候,迫不及待的下載了一個工具開始用,然后傻眼了,面對例如功能強大QTP,不知如何下手,同時也會嚴重的打消我們的積極性,在這里,我建議每個剛開始接觸或學習自動化的朋友,先了解一些自動化的概念,在這一階段你要先搞清楚這幾個問題:
什么是自動化測試?
自動化可以做什么?
學好自動化測試需要哪些知識準備?
自動化測試的局限性?
你做的項目適不適合做自動化測試?為什么?
為什么要先搞懂這幾個問題?因為你先了解了這些問題后,有助于消除你對自動化測試學習的恐懼,也會有一個初步的思路,不會覺得無所適從,再者,帶著問題去學習,能更好的理解并記住然后形成自己的思維。
2. 下載安裝QTP 這時候是不是對自動化測試有所了解了,那現在就下載一個自動化測試工具,然后安裝并破解它或使用試用版本,開始自動化工具的學習吧。在這里我要談一點我個人的經驗:我應該學習哪個工具?對于這個問題,我想說這跟我當時學習編程語言一樣的,到處找資料看人家的經驗,人家說VB容易上手,馬上學習VB,看到人家說DEPHI好就學習DEPHI,人家說JAVA好就學習JAVA。。。。。。。,甚至一天幾變,幾個月下來,什么也沒學會,最后安下心來從C開始吧,自動化測試也是一樣,不要老去問別人學什么好,選擇一個,硬著頭皮學下來就是了,你精通了一門工具后,再去用另一個工具也就是一兩周的時間就能運用自如,所以,就從QTP開始吧,它的IDE很直觀,適合新手,然后下載一份用戶手冊,先了解下各個功能
3. 簡單自動化 QTP裝好了吧,那現在就開始我們的第一個自動化體驗:錄制flight自動化腳本,這個過程比較簡單,錄制三個部分:登陸、定票、查詢定票和刪除定票,具體的業務過程和錄制過程我就不說了,網上有很多資料,本文也不是一個實驗指導書,只是提供一個比較清晰的自動化學習路線。當然,在錄制了這些腳本之后,回放成功,第一個自動化完成了。
4. 增強腳本功能 這個階段主要是學習一些QTP的基本功能,在這里你要去增強一下你的腳本了,參數化登陸用戶名和密碼,參數化航班選擇、定票張數,增加金額的檢查。主要是學習參數化和檢查點,這里會遇到一些困難:那就是選擇航班這里,可以運用隨機數等方法來參數化航班金額的檢查會需要用到一些簡單編程,總金額=張數*單價.通過定單號查詢定票會要用到對象的GetRoProperty("")方法.這個學習的過程,還會遇到一些調試方面的困難,不過不用心急,慢慢來,成功是建立在失敗之上的,記得在調試時,可以按F11單步運行,建立你的輸出如:msgbox實時輸出你想要看到的信息。
5. 數據驅動 經歷了上面的階段,在這里將要接觸一點數據驅動的思想了,其實很簡單,就是把你參數化的地方拿出來,放到一個外置的excel文件里面,然后通過讀取excel里面的數據來控制循環次數,大概的步驟如下:
創建excel對象
循環讀取excel數據賦值給變量
在腳本中引用變量
6. 功能函數化 這個階段主要是把各個可以重用的功能寫成函數,而主控腳本主要是用來調用這些功能函數,實現重用和結構清晰化,這個階段又可以分成以下幾個子階段:
把單個的功能寫成一個action,主腳本調用這些action,在這里會遇到一個問題,那就是關于被調用action的設置,這個在我的博客里面有一篇文章有介紹,可以去看看把單個的功能寫成函數放到一個action里面,腳本最下面調用這些函數
把單個的功能寫成函數到一個.vbs文件,腳本中調用這些函數,在這里也會遇到一個問題,那就是QTP調用.vbs文件,這在我的博客里面也有一篇文章詳細寫了,這里就不再重復這個過程完成后,就大概有基本的框架了,接下來進入下一個階段
7. 完善框架 在這個階段,我們以網上一位朋友的輕量級自動化測試框架來說,相信有很多朋友都有看過,我也懶得重新去做一個示例了,在這里你需要建立你自己的report、日志文件、函數文件、數據驅動文件、腳本文件等,把這些都放到單獨的文件夾里面,方便管理,并對函數的創建、定義進行規范,詳情參見輕量級自動化測試框架
8. 理清框架思想 在這個階段主要是用來思考和完善你的框架思想了,此時你們應該有一個清晰的思路了,明白自動化腳本開發的各個階段,并知道最后要做成什么樣子,現在重要的一點就是學習做分析和計劃了,一個項目交到你手里,你要先評估這個項目適不適合做自動化、自動化哪些東西、哪些功能可以封裝起開寫成函數、哪些地方需要進行數據來控制驅動,最后評估各個階段的耗時、需要的資源、各階段的產出(文檔、腳本等)
四、QTP操作對象的原理
QTP為用戶提供了兩種操作對象的接口,一種就是對象的封裝接口,另一種是對象的自身接口。
對象的自身接口是對象控件本身的接口,只要做過軟件開發,使用過控件的人應該很清楚。
對象的封裝接口是QTP為對象封裝的另一層接口,它是QTP通過調用對象的自身接口來實現的。
兩種接口的腳本書寫格式的差別在于:
自身接口需要在對象名后面加object再加屬性名或方法名,
封裝接口就不用在對象名后面加object。
具體格式如下:
對實際對象的操作:
對象.object.自身屬性
對象.object.自身方法()
對象.GetROProperty("封裝屬性")
對象.封裝方法()
對倉庫對象的操作:
對象.GetTOProperty("封裝屬性")
對象.GetTOProperties() ’獲取所有封裝屬性的值
對象.SetTOProperty("封裝屬性", "封裝屬性值")
比如操作JavaEdit對象,通過QTP封裝的封裝接口,腳本如下:
設置JavaEdit的內容:
JavaDialog("Add NE").JavaEdit("NE Name").Set "NE1"
讀取JavaEdit的內容:
msgbox JavaDialog("Add NE").JavaEdit("NE Name").GetROProperty("value")
如果通過JavaEdit的自身接口,腳本如下:
設置JavaEdit的內容:
JavaDialog("Add NE").JavaEdit("NE Name").object.setText("NE1")
讀取JavaEdit的內容:
Msgbox JavaDialog("Add NE").JavaEdit("NE Name").object.getText()
QTP執行JavaEdit().Set語句時,是通過執行JavaEdit().object.setText()來實現的。
QTP執行JavaEdit().GetROProperty("value"),是通過執行JavaEdit().object.getText()來實現的。
JavaEdit對象的封裝接口Set()和GetROProperty("value"),是QTP封裝JavaEdit對象的自身接口setText()和getText()而得來的。
對象的封裝接口是QTP使用的缺省接口,我們錄制出來的腳本都是使用封裝接口,大家用的也都是封裝接口。
但是封裝接口不如自身接口豐富,因為QTP只是封裝了部分常用的自身接口嘛。
所以我們在需要時,可以繞過封裝接口,直接調用對象的自身接口。
不過有些自身接口不夠穩定,在實踐中偶爾會出現問題,但是概率很少。
封裝接口有相應功能的話,就盡量用封裝接口吧!
( Written by yabest,http://yabest.net )
理解了封裝接口和自身接口的原理,我們就可以更加靈活的操作對象了。
但是我們怎么知道對象都有哪些封裝接口和自身接口呢?
其實很簡單,用對象查看器(Object Spy)查看對象,在查看窗口里有列出這些接口,包括屬性和方法。
窗口中間有選擇欄讓你選擇Run-time Object或者Test Object,
當你選擇Runtime Object時,它顯示的就是對象的自身接口(自身的屬性和方法)
當你選擇Test Object時,它顯示的就是對象的封裝接口(封裝的屬性和方法)
(注意:GetROProperty訪問的是實際對象的封裝接口,GetTOProperty訪問的是倉庫對象的封裝接口,
兩者訪問的都是對象的封裝接口,即Object Spy窗口里選Test Object時顯示的屬性。
不要以為GetROProperty訪問的是自身接口,即Object Spy窗口里選Run-time Object時顯示的屬性。
QTP里的Test Object/Run-time Object的概念太容易讓人混淆了!
它既用來區分倉庫對象和實際對象,又用來區分對象的封裝接口和自身接口。
原文轉自:http://www.anti-gravitydesign.com