如何使用Robot Framework編寫優秀的測試用例
- 概述
- 命名
- 測試套件命名
- 測試用例命名
- 關鍵字命名
- setup和teardown的命名
- 文檔
- 測試套件文檔
- 測試用例文檔
- 用戶關鍵字文檔
- 測試套件結構
- 測試用例結構
- 工作流測試
- 數據驅動測試
- 用戶關鍵字
- 變量
- 變量的命名
- 傳參和返回值
- 避免使用Sleep關鍵字
- 我們AT中的一些約定
概述
- 這篇文檔是使用Robot Framework編寫好的測試用例的高級綱要,至於如何實際和被測系統(SUT)交互超出了本文檔的范圍。
- 最重要的大綱是使得測試用例盡可能地讓熟悉相關領域的人容易理解,這樣會降低維護成本。
- 更多信息請查看以下鏈接:
Robot Framework該做的和不該做的
編寫可維護的自動化接收測試 文章
如何結構化一個可伸縮且可維護的接收測試套件 博客
命名
測試套件命名
- 套件名稱應該盡可能描述清楚。
- 套件名稱會從文件名或目錄名自動創建:
- 文件名的擴展名不會出現在套件名稱中;
- 下划線會被轉成空格;
- 如果套件名稱都是小寫字母,那么名稱會自動轉成首字母大寫。
- 名稱可以相對長一點,但是過長的話在文件系統中不方便。
- 如果需要的話,頂級套件的名稱可以在命令行使用
--name
選項進行重寫。
舉例:
- 在文件系統中看到的是login_tests.robot,在RIDE中看到的是Login Tests
- IP_v4_and_v6在RIDE中看到的是IP v4 and v6
測試用例命名
- 測試用例和測試套件名稱描述應該相似。
- 如果套件包含了多個相似的測試,並且套件命名良好的話,那么測試名稱可以短一點。
- 測試用例名稱就是你在測試用例文件中指定的名稱,不會有任何的轉換。
比如,如果我們在一個和非法登錄相關的invalid_login.robot
文件中有很多測試,那么下面這些測試用例名稱都是可以的:
*** Test Cases ***
Empty Password
Empty Username
Empty Username And Password
Invalid Username
Invalid Password
Invalid Username And Password
下面的名稱就有點長了:
Login With Empty Password Should Fail
Login With Empty Username Should Fail
Login With Empty Username And Password Should Fail
Login With Invalid Username Should Fail
Login With Invalid Password Should Fail
Login With Invalid Username And Invalid Password Should Fail
關鍵字命名
- 關鍵字名稱描述應該清晰。
- 應該解釋該關鍵字做什么而不是怎么做。
- 不同的抽象級別(比如,
Input Text
和Administrator logs into system
)。 - 至於應該是每個單詞首字母大寫還是應該只有名稱的首字母大寫沒有明確的規范。
- 每個單詞的首字母大寫通常用於關鍵字名稱很短的情況,比如
Input Text
; - 如果關鍵字的命名像一個句子,那么一般將該關鍵字的首字母大寫。比如
Administrator logs into system
。這些關鍵字通常也具有更高的級別。
- 每個單詞的首字母大寫通常用於關鍵字名稱很短的情況,比如
好的關鍵字命名:
*** Keywords ***
Login With Valid Credentials
不好的關鍵字命名:
*** Keywords ***
Input Valid Username And Valid Password And Click Login Button
setup和teardown的命名
- 盡量使用描述做什么的名稱。可能使用一個已存在的關鍵詞。
- 如果setup和teardown包含了不相干的步驟,那么可以接受更抽象的名稱:
- 將關鍵字名稱逐個列出來會產生重復和維護問題(比如
Login to system, add user, activate alarms and check balance
) - 使用一些通用的名字通常來說更好一些(比如
Initialize system
)。
- 將關鍵字名稱逐個列出來會產生重復和維護問題(比如
- 如果已存在實現了更低級別步驟的關鍵字,那么建議使用內置的
Run Keywords
。
*如果setup或teardown只需要一次的話,那么使用最好,這樣不會重復。 - 使用測試的每個人務必要明白該setup或teardown做了什么。
好的命名:
*** Settings ***
Suite Setup Initialize System
好的命名2(如果只使用一次):
*** Settings ***
Suite Setup Run Keywords
... Login To System AND
... Add User AND
... Activate Alarms AND
... Check Balance
不好的命名:
*** Settings ***
Suite Setup Login To System, Add User, Activate Alarms And Check Balance
文檔
測試套件文檔
- 通常,最好是將所有的文檔添加到測試用例文件中。
- 應該包含背景信息,比如為什么創建測試,執行環境需要注意的地方等等。
- 不要重復測試套件名稱,如果真的不需要,那就最好不要有文檔。
- 不要包含太多的詳細信息和測試用例。
- 測試用例本身應該是理解起來清晰的。
- 重復信息浪費時間和精力,還會造成維護問題。
- 文檔可以包含更多信息的鏈接。
- 如果需要以鍵值對形式的文檔信息,可以考慮使用測試套件元數據metadata,比如
Version:1.0
。 - 頂級套件的文檔和元數據可以分別使用
--doc
和--metadata
選項從命令行進行設置。
好的文檔:
*** Settings ***
Documentation Tests to verify that account withdrawals succeed and
... fail correctly depending from users account balance
... and account type dependent rules.
... See http://internal.example.com/docs/abs.pdf
Metadata Version 0.1
不好的文檔(特別當套件名稱像account_withdrawal.robot
時):
*** Settings ***
Documentation Tests Account Withdrawal.
測試用例文檔
- 測試用例通常不需要文檔。
- 父套件的名字和可能的文檔以及測試用例本身的名字應該給出足夠的背景信息。
- 測試用例的結構應該盡可能地清晰,不需要文檔或其它注釋。
- Tags標簽通常比文檔更靈活,並提供了更多的功能,比如statistics【統計】、include/exclude等等。
- 有時測試文檔是有用的,適當地使用很關鍵。
好的文檔:
*** Test Cases ***
Valid Login
[Tags] Iteration-3 Smoke
Open Login Page
Input Username ${VALID USERNAME}
Input Password ${VALID PASSWORD}
Submit Credentials
Welcome Page Should Be Open
不好的文檔:
*** Test Cases ***
Valid Login
[Documentation] Opens a browser to login url, inputs valid username
... and password and checks that the welcome page is open.
... This is a smoke test. Created in iteration 3.
Open Browser ${URL} ${BROWSER}
Input Text field1 ${UN11}
Input Text field2 ${PW11}
Click Button button_12
Title Should Be Welcome Page
用戶關鍵字文檔
- 如果關鍵字很簡單的話就不需要文檔了,此時應該具備好的關鍵字和參數名以及清晰的結構。
- 重要的用法是給參數和返回值加文檔。
- 在資源文件中,使用 Libdoc生成的文檔可以在編輯器(RIDE)中完成關鍵字輸入之后,按下Ctrl鍵看到注釋。
測試套件結構
- 套件中的測試應該是相關的,公用的setup和teardown通常是一個很好的說明。
- 一個文件中不應該有太多的測試用例(最大10個),除非是數據驅動的測試。
- 測試應是獨立的,使用setup/teardown初始化。
- 有時,測試間的依賴是無法避免的。
- 比如,分別初始化所有的測試可能花費太多時間。
- 絕對不要有太長的測試依賴鏈。
- 使用內置的變量
${PREV TEST STATUS}
驗證前一個測試的狀態。
測試用例結構
- 測試用例應該容易理解。
- 一個測試用例應該測試一個東西,可以很小(一個功能的一部分),也可以很大(端到端)。
- 選擇合適的抽象級別:
- 使用抽象級別要一致
- 在測試用例的級別不要包含不必要的詳細信息
- 兩種測試用例:工作流測試和數據驅動測試。
工作流測試
- 通常有以下階段:
- 前置條件(可選,通常在setup中)
- 操作(對系統做一些操作)
- 驗證(對結果進行驗證,必須要有)
- 清理工作(可選,總是在teardown中完成)
- 關鍵字描述測試做了什么
- 使用明確的關鍵字名稱和合適的抽象級別
- 應該包含足夠的信息以手動運行。
- 不需要文檔或注釋來解釋測試做了什么。
- 不同的測試可以有不同的測試級別
- 細節功能的測試可以更精確。
- 端到端的測試可以是非常高的級別。
- 一個測試應該只包含一個測試級別。
- 不同的風格:
- 對於低級別細節的更技術性的測試和集成測試。
- 將“可執行的說明書”作為需求。
- 使用領域語言。
- 每個人(包括客戶和產品擁有者)應該總可以理解。
- 測試用例級別沒有復雜的邏輯。
- 沒有循環或if/else
- 小心使用變量賦值
- 測試用例不應該看起來像腳本
- 最大10個步驟,最好更少。
下面是使用了“正常的”關鍵字驅動的樣式:
*** Test Cases ***
Valid Login
Open Browser To Login Page
Input Username demo
Input Password mode
Submit Credentials
Welcome Page Should Be Open
下面是使用了更高級的"gherkin"樣式:
*** Test Cases ***
Valid Login
Given browser is opened to login page
When user "demo" logs in with password "mode"
Then welcome page should be open
數據驅動測試
- 每個測試應該有一個高級的關鍵字
- 不同的參數創建不同的測試
- 一個測試可以運行相同的關鍵字多次來驗證相關變化的結果
- 如果該關鍵字是以用戶關鍵字實現的,那么它一般包含了和工作流測試相似的工作流。
- 如果在其它地方不需要該關鍵字,那么在和測試相同的文件中創建該關鍵字是個好主意。
- 推薦使用數據驅動測試
- 不需要重復寫該關鍵字多次
- 在一個測試中方很容易測試多種變化。
- 如果可能的話,推薦給列命名標題頭。
- 如果真的需要大量的測試,可以考慮基於一個外部模型生成。
樣例:
*** Settings ***
Test Template Login with invalid credentials should fail
*** Test Cases *** USERNAME PASSWORD
Invalid Username invalid ${VALID PASSWORD}
Invalid Password ${VALID USERNAME} invalid
Invalid Both invalid invalid
Empty Username ${EMPTY} ${VALID PASSWORD}
Empty Password ${VALID USERNAME} ${EMPTY}
Empty Both ${EMPTY} ${EMPTY}
*** Keywords ***
Login with invalid credentials should fail
[Arguments] ${username} ${password}
Input Username ${username}
Input Password ${password}
Submit Credentials
Error Page Should Be Open
用戶關鍵字
- 應該容易理解,和工作流測試具有相同的規則。
- 不同的抽象級別。
- 可以包含一些編程邏輯(比如循環,if/else等等)
- 尤其是在一些低級的關鍵字種。
- 復雜的邏輯一般在測試庫種而不是在用戶關鍵字中。
變量
- 封裝一些長的或者復雜的值。
- 在關鍵字之間傳遞信息。
變量的命名
- 名字明確但不要太長。
- 可以對變量進行注釋。
- 使用一致的大小寫規范:
- 在一個確定的范圍內部對局部變量使用小寫。
- 其它情況使用大寫(全局,套件或測試用例級別的變量)。
- 空格和下划線都可以作為單詞分隔符。
- 推薦在變量表中也要列出那些會動態設置的變量:
- 使用內置的關鍵字
Set Global Variable,Set Suite Variable
等對變量動態設置值。 - 初始值應該解釋真正的值在哪里/如何設置。
- 使用內置的關鍵字
樣例:
*** Settings ***
Suite Setup Set Active User
*** Variables ***
# Default system address. Override when tested agains other instances.
${SERVER URL} http://sre-12.example.com/
${USER} Actual value set dynamically at suite setup
*** Keywords ***
Set Active User
${USER} = Get Current User ${SERVER URL}
Set Suite Variable ${USER}
傳參和返回值
- 通常的做法是從關鍵字中返回值,再將它們賦值給其它變量,然后將它們作為實參傳給其它關鍵字。
- 另一種方法是將信息存在一個測試庫中,或者使用內置的
Set Test Variable
關鍵字。- 避免在測試用例級別使用編程風格。
- 使用此方法可能會更復雜,並使得可復用關鍵字變得困難。
好的例子:
*** Test Cases ***
Withdraw From Account
Withdraw From Account $50
Withdraw Should Have Succeeded
*** Keywords ***
Withdraw From Account
[Arguments] ${amount}
${STATUS} = Withdraw From User Account ${USER} ${amount}
Set Test Variable ${STATUS}
Withdraw Should Have Succeeded
Should Be Equal ${STATUS} SUCCESS
不是很好的例子:
*** Test Cases ***
Withdraw From Account
${status} = Withdraw From Account $50
Withdraw Should Have Succeeded ${status}
*** Keywords ***
Withdraw From Account
[Arguments] ${amount}
${status} = Withdraw From User Account ${USER} ${amount}
[Return] ${status}
Withdraw Should Have Succeeded
[Arguments] ${status}
Should Be Equal ${status} SUCCESS
避免使用Sleep關鍵字
- 同步測試時,Sleep是一種非常不穩定的方式。
- 安全邊際會使得平均Sleep時間太長。
- 使用那些具有輪詢確定操作發生的關鍵字代替Sleep關鍵字:
- 關鍵字名稱通常以
Wait
開頭 - 應該設置一個等待的最大時間
- 內置的關鍵字
Wait Unitl Keyword Succeeds
內部可能封裝了其它關鍵字
- 關鍵字名稱通常以
- 有時Sleep是最簡單的解決方案:
- 總是要小心使用
- 不要在用戶關鍵字中使用,因為它們可能被其它測試或關鍵字使用。
- 在調試時阻止執行可能很有用。
以上翻譯自https://github.com/robotframework/HowToWriteGoodTestCases/blob/master/HowToWriteGoodTestCases.rst
我們AT中的一些約定
我們項目現在做的是接口測試,比如對api/user/mobileregister
接口進行測試。
測試套件的命名:TC_接口類名_方法名,比如上面的接口對應的套件名稱是TC_User_MobileRegister
。其中TC是TestCase的縮寫,本該是TS【TestSuite】的,但一直這樣用了,姑且就這樣用吧。User是上面的接口所對應的類型,MobileRegister是該類中方法名,注意都是單詞首字母大寫。對一個接口的測試必須都寫在一個測試套件中。
測試用例的命名:沒有強制要求,如果說有,就是名字要明確、有序
比如,下面這個創建購買訂單時的測試用例。明確體現在每個case名稱后面都有簡短的關鍵漢字說明;有序體現在有數字編號。還有一點是,如果有多個單詞,單詞之間沒有分隔符,並且單詞首字母大寫。
變量的命名:
- 全局變量都定義在Common文件夾下的
variables.txt
文件中,見下圖。規則是必須以G_
開頭,單詞首字母大寫,只有一個單詞的話全部大寫也可以。比如${G_Server}或${G_SERVER}都可以,但有兩個及以上單詞時建議使用${G_ServerUrl}(這里還有幾個之前沒遵守的變量還沒改)。 - 套件范圍的變量命名建議單詞之間以下划線分隔。比如
${user_name},${user_Name}
都可以。 - 測試用例中的變量和關鍵字中的變量建議使用首個單詞首字母小寫,比如
${userName},${tradePwd}
等等。 - 注意:robot framework IDE中,如果一個關鍵字定義的形式參數包含
${userName}
,但在測試用例中包含了一個從服務端返回的UserName字段,你將返回的值放到了${user_name}
或${User_Name}
,驗證期望的${userName}
和返回的值是否相等時,RF會將這兩個肉眼看着不同的變量當作同一個變量對待,所以必須明確區分這兩個要比較的變量。比如,將返回的值存在變量${res_userName}
中。
關鍵字的命名:
目前項目中有兩種用戶關鍵字,一種是在Common文件夾下的resource.txt中的關鍵字,一種是每個測試套件中定義的關鍵字。
resource.txt文件中的關鍵字是經常使用的一些關鍵字,命名規范是每個單詞首字母大寫,區別於系統關鍵字。雖然字體顏色本身有所區分了,但是形式上再有所區分不是更明顯了嗎,而且顏色可以隨意設置的。見下圖。
每個測試套件中定義的關鍵字是只在該測試套件中使用關鍵字,命名規范是單詞之間以下划線分隔,分割線之間的單詞或詞組都是首字母小寫。見下圖。