另類 RobotFramework 使用法

Mr.Li發表於2020-07-30

目前的自動化測試工具使用了RobotFramework,把自己使用的方式大致分享一下。具體來說就是,只用RF作為一個執行器,其它底層API、業務API和測試用例全部用python來實現。
本文章純屬個人見解,水平也有一定限制,各位看官可以發表看法,但是勿噴。

最近把RF3.2的英文原手冊看得差不多了,也對這個工具一定的瞭解。從RF本身的發展來看,除了向Python3靠近、增加Task、增加BDD之外,有幾個地方是為了增強執行原生python程式碼的能力。這一點與我最初接觸RF的感觸是相符合的,就是普通API操作尚可,靈活操作和深入細緻操作的能力欠缺。

=======================================================================================

2019年之前我一直用的是自己用python寫的測試框架,包括測試執行工具,基本夠用。RF的大名早就聽過,但是沒用過。19年4月-5月短暫在某本地化外企待過,接觸了RF和REST測試。後來因為多頭管理及一些其它因素離職了,但在這兩個月中,也是把該公司(後簡稱A公司)的幾套自動化測試都摸清了。雖然在這家公司的經歷並不是重點,但是我還是覺得有必要把它的自動化測試情況大致介紹一下。

A公司做的是邊緣網路裝置,跟華為有類似產品。主要做介面測試,協議包括REST、NETCONF、SNMP當然還有CLI,自動化測試工具是用Python + RobotFramework。A公司有三套東西,第一套X是總部的Python REST庫,第二套Y是中歐某國分部的RF庫(API、業務API和測試用例都用Robot來實現),第三套Z是中國分部的RF用例庫+Python庫。X就是一個純粹的python庫,按照RF的規則來實現的,提供JSON合成/解析、REST訊息打包和收發等功能,非常基礎。Y則98%是Robot程式碼,呼叫X庫,包裝一層基礎關鍵字,在上面再套一層業務基礎關鍵字,接著網上套混合關鍵字、效能關鍵字、驗收業務關鍵字,最後是基礎用例、上層用例、等等,總共疊了八層。Z則是因為覺得Y不好,又做的一套,具體點就是二次用python包裝X,形成了協議介面+基礎業務介面的python RF庫,上面則是用Robot程式碼寫的測試用例了。

總體感受到的痛點如下:
1. 引數定義和傳遞累贅
每個特性負責人寫robot用例的時候,都一定會出現獨特的需求,感覺每個特性的suite下面總要帶個額外的引數配置檔案和一組自定義關鍵字檔案。
引數傳遞的時候,有些還需要單獨指定哪個需要傳遞給下面的子suite。當時第一次直接使用RF,對於哪些引數要指定傳遞模糊不清,即使現在我也覺得模糊不清。
2. 程式碼閱讀難
這個點是相對的,如果只是簡單的用別人寫好的關鍵字來寫用例和執行用例,其它的都不用關心和負責,那對於沒有程式碼基礎的人來說,會沒有什麼感覺。
但是如果是一個需要負責解析業務流程,學習新業務特性的人來說,花費的時間就要多很多了。Robot語言本來就很鬆散,大小寫和下劃線不敏感,再加上一些引數的特殊文字表達方式,加上那八層架構,繞來繞去把我搞得暈頭轉向。當時的Y架構,我花了大半個月的時間才摸清楚。設計說明?沒有;關鍵字說明?沒有;程式碼註釋?沒有;skype或郵件求教?對不起,上班時間不一樣,也懶得義務回答。一般情況下,我覺得除了最後那個skype交流的問題外,其它的問題大家都會有的,別說自己的公司是大公司如何如何規範,在國內的工作量和進度壓力面前,規範不值一提。
3. Robot程式碼堆砌成一堆垃圾
基於前面的第二點,在我看來,Y套的Robot程式碼,已經形成了一堆屎山。我好歹搞自動化測試也陸陸續續有十年的經驗了,看那堆東西都有點吃力,那些三四年或四五年經驗的年輕人來搞?
鬆散關鍵字和用例的堆疊,每個人的水平和習慣都不一樣,寫出來的內容就五花八門,慢慢地形成了一堆垃圾。內容各式各樣,看吧又不容易看懂,動又不敢隨便動,有些關鍵字介面呢擴充套件性很差,不得不重新寫一個,像我這樣有程式碼潔癖的人看起來都想吐又無可奈何。
Z套就比Y套好多了,起碼要是垃圾的話也是分成了兩堆,看起來沒那麼難受。先不評價python RF庫那邊的情況,Robot用例這邊,還是充斥著各種各樣的引數和補充關鍵字,原因就是python庫的定義的關鍵字不夠用。
4. Robot語法表達能力不足
這個其實是一個重要的問題,程式碼表達能力不足,而且表達的方式也很鬆散。這個鬆散可以是優點也可以是缺點,大小寫不敏感,空格不敏感,這樣表達也可以,那樣寫也沒錯。但是這種基於文字的鬆散,可能對於閱讀者的理解會帶來一些困擾,特別是在引數的表達方面,由於受到文字處理的限制,所以就搞了好多特殊型別引數的文字表達方式。
至於程式碼表達能力不足,這個就顯而易見了,從RF加強原生python程式碼執行能力這點就可以看出來了。在測試用例中那些靈活度很大或者比較深入細節操作的地方,RF是有欠缺的。但是就我個人而言,這些改進仍然是不足的,當然不是說它不好。也許這些表達能力不足的地方也就是佔了整個測試的10%不到,也還可以嵌入Python指令碼來實現,但是這樣我就感覺複雜化了。引數無法表達可以用python代替,程式碼邏輯無法表達的部分也可以python代替,那我幹嘛不直接用python?統一化、乾淨、不混亂。
從目前我用的方式來看,普通用例的python程式碼量與Robot可以持平,靈活場景或細節場景的程式碼量python可以少得多,唯一的不同就是需要懂python。但是如果從真實的情況來評估的話,學習一個python跟學習一個robot的成本是一樣的,因為用python來寫用例的話都是基礎語法,沒什麼難的,又不是寫底層框架。再說,學完基礎python,還能進階提升,學學爬蟲搞搞工具開發,學完robot語法除了寫個測試用例,還能幹什麼?
5. 測試報告太大難受
如果像Y套那樣,堆疊了多層關鍵字,跟蹤業務流程的時候,我點測試日誌頁面上的加號都點得手痛。
測試日誌上面那一層層花花綠綠的太多,別人我不知道,反正我是被晃得眼花繚亂。
6. 可能的多執行緒
這個是痛點之外的東西,順便提一下。RF文件裡面說明了,Robot無法多執行緒,想搞多執行緒必須用Python/Java庫來實現,而且在多執行緒中的log列印是延後的。
我現在也沒有多執行緒的需求,但是log方面我是自定義修改的,所以即使有多執行緒需求,也不會有問題。

=======================================================================================

只幹了兩個月就離職了,反正感受到的東西就是這些,也不怎麼全面。在新公司(簡稱B公司)也是用Python + RobotFramework,經過前面的一些總結,所以我現在使用RF的方式就是簡單化、好用、夠用就行,把RF僅僅當成一個庫和執行器。當然這跟我現在的工作現狀有關係,公司就七八個人,我一個人負責全部的測試設計、自動化框架、自動化指令碼、版本執行等等,按老闆的意思,你幹好測試就行了,不管你怎麼搞。

我現在的專案自動化的內容包含了Serial、SSH和WEB,除了WEB頁面使用了PO,其它的都是程式導向的。大概使用RF的特點有如下幾個:
1. 獨立配置引數
一個產品只有一個引數配置檔案,並不多,所有二十個特性加一起也就六十多個,而且每次測試需要修改的引數只在六七個左右,大多是產品型號、軟體版本、產品IP等這些。
引數配置檔案用一個ini檔案管理,放在robot測試套路徑中,每次測試執行前就會自動載入。
這個引數與RF的命令列變數並不衝突,如果覺得需要,可以增加robot命令列變數,我因為不需要所有沒用。
2. 額外的日誌系統
前面說到了,RF預設的測試報告裡面的log過多,而且如果關鍵字存在多層疊加的話,看log很累人。
因為我的測試用例其實是關鍵字,而測試用例呼叫的API都是python程式碼,所以在測試報告上面,基本上就只會有一層用例關鍵字,而用例關鍵字下面那些API是否需要列印則是由API的裝飾器來控制,總體不會太多;所有的列印,都同時會列印到另外的本地日誌檔案中,用TimedRotatingFileHandler來處理,比report網頁中的詳細,它包括了所有級別的列印。
3. 用例是函式形式的關鍵字
除了WEB頁面是物件導向之外,其它的API都是程式導向的函式。(在大量資源申請/釋放的業務中,千萬不要對節點資源使用物件導向方式,要不然會很慢;A公司的REST採用OOP來定義每個層級節點,包括資源和配置,結果在效能測試的時候不得不重新寫一套程式導向的關鍵字。)
使用Pyerial、SSHLibrary、SeleniumLibrary,雖然SSHLibrary和SeleniumLibrary已經是標準的RF庫了,但是我把它進行了整合包裝,既保留了原生的關鍵字,又新增了一套符合自己習慣的關鍵字。
業務API函式是關鍵字,我稱為Action關鍵字,當然Fixture也是關鍵字。
最上層的相互函式獨立的測試用例關鍵字,每個測試用例是一個函式,可帶引數。
最終,在python庫的init.py中,定義庫同名的類,將需要匯出的關鍵字函式繫結到該類上。我繫結了基礎協議SSH/Selenium的關鍵字、業務Action關鍵字、測試用例關鍵字,原生的SSHLibrary和SeleniumLibrary的關鍵字也繫結了。實際上除了測試用例關鍵字以外,其它都還沒有用到。
4. robot測試套檔案
檔案裡面只包含匯入測試庫、設定Setup/Teardown和測試用例。一個測試用例只包含一個名稱和一個測試用例關鍵字,攜帶可能的測試用例引數。
這樣的話,robot有用的功能又沒有丟失,比如測試標籤,而且另外複雜性的東西都交給了更靈活的python來實現。
5. 測試用例函式如何識別以及引數如何恢復
測試用例用簡單的裝飾器來包裹屬性,在python庫的init.py中讀取識別並繫結。
引數恢復的話,是在具體的測試用例程式碼前設定本用例觸碰的引數,在測試用例的Teardown中根據設定的引數來恢復產品設定。
A公司的Z套robot指令碼沒有引數恢復這個概念,只有一個全域性的資源池,要用的時候就去資源池申請,用完了就釋放。可問題是下次重跑的時候,資源池根本不知道資源在產品中是不是真的都沒有使用,還需要人工去檢查一番或者用個專門的指令碼去釋放。Y套robot指令碼就更加離譜了,根本沒有全域性管理這個概念。

=======================================================================================

以上就是我的RF框架的大致使用方式,總體看起來就是‘懶’,我只想用最少的改變來完成一個夠用的工具來工作。能力有限,有些想法和概念,也無法用一些工程化的思想來表述,也有不少東西我不懂所以講不出來。反正在我這裡,很多框架或模組都是自己寫的,夠自己用就行,在具體的產品實施中,感覺用得還不錯,沒有碰到什麼特別棘手的問題。

這種層次的測試介面和測試用例,就是三層:基礎協議API、業務API、測試用例函式,比較扁平化,普通測試用例寫起來不含糊,複雜用例實現起來也不痛苦,簡簡單單。

至於底層在實現上,肯定會用到一些裝飾器之類的技巧,至少初級別的python工程師是看不懂的東西。有個好處,保證自己不容易被優化,免得教會徒弟餓死師傅。都三十多了,碰到新冠肺炎了,誰還敢隨便丟掉自己的飯碗啊!這個話題就不多說了,社會實踐感悟而已。

以上內容屬個人實踐和見解,僅供參考~

相關文章