另類 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 工程師是看不懂的東西。有個好處,保證自己不容易被最佳化,免得教會徒弟餓死師傅。都三十多了,碰到新冠肺炎了,誰還敢隨便丟掉自己的飯碗啊!這個話題就不多說了,社會實踐感悟而已。

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

相關文章