介紹
- 這篇文檔將會是一篇在「高層面」的怎么用 Robotframework 來編寫優秀測試用例的原則。至於如何使用 Robotframework 來與您的待測試系統相作用這樣的細節討論是不包含在這篇文檔中的。
- 最重要的一條原則就是保證測試用例對於(不?)熟悉這個領域的人來講越簡單越好。
- 關於這個主題的更多信息,你可以查看以下這些優秀的資源:
- Writing Maintainable Automated Acceptance Tests 作者:Dale H. Emery
- How to Structure a Scalable And Maintainable Acceptance Test Suite 作者:Andreas Ebbert-Karroum
命名
測試套件的命名
- 套件的名稱應該盡可能地描述這個套件的用途。
- 如果必須的話,頂層套件的命名可以在命令行中使用--name選項來修改。
- 名稱可以相對長一些,但是如果超過40個字那也太長了一些。
- 記住 Robotframework 的套件名稱是直接從文件/目錄的名字轉換來的。
- 文件的后綴名被去掉了
- 而且下划線會被轉換成空格,
- 如果你的用到的單詞都是小寫的,那么開頭字母會被轉換成大寫的。比如 login_test.txt 會被轉換成 Login Tests, DHCP_and_DNS 會被轉換成 DHCP and DNS。
Examples:
login_tests.robot->Login TestsIP_v4_and_v6->IP v4 and v6
測試用例的命名
- 測試用例的名字應該與套件的名字描述相似。
- 如果一個套件里包含了好多個相似的測試用例,而且測試套件本身已經很好地命名了,那么用例的名稱可以簡短一些。
- 在測試用例文件中的名稱應該恰好表達了你需要做什么。
Good:
*** Test Cases ***
Empty Password Empty Username Empty Username And Password Invalid Username Invalid Password Invalid Username And Password
Bad:過長的命名
*** Test Cases ***
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

關鍵詞命名
- 同樣的,關鍵詞的名稱也應該是清晰具體的。
- 應該可以表達這個關鍵詞干了什么,而不是它如何去做。
- 關鍵詞應該是非常不同的抽象層次(比如,「輸入字符」或者「用戶登錄到系統」)。
Good:
*** Keywords ***
Login With Valid Credentials
Bad:
*** Keywords ***
Input Valid Username And Valid Password And Click Login Button

生成setup和分解teardown的命名
- 試着用名稱來描述這個步驟完成了什么。
- 或許你可以用一個已經存在的關鍵詞
- 如果生成或者分解包含了不相關的步驟,那么可以接受更抽象一點的名稱。
- 在名稱中列舉步驟是一個重復化和維護的問題(比如:登入系統,添加用戶,激活警報和檢查平衡)。
- 或許需要用到一些通用一些的名稱比如「初始化系統」
- 每個用到這幾個測試用例的人都需要明白這幾個生成或者分解動作是干什么的。
Good:
*** Settings ***
Suite Setup Initialize System
Good (if only used once):
*** Settings ***
Suite Setup Run Keywords ... Login To System AND ... Add User AND ... Activate Alarms AND ... Check Balance
Bad:
*** Settings ***
Suite Setup Login To System, Add User, Activate Alarms And Check Balance

文檔
測試套件的文檔
- 通常把文檔添加到包含測試用例的最底層套件中是一個不錯的想法。
- 高層的套件不需要那么頻繁地文檔化。
- 文檔應該包含必要的背景信息,比如為什么要創建這些測試用例,測試環境中需要注意的點等等。
- 文檔內容不要只是簡單地重復套件的名稱。
- 如果不是真的有文檔還不如不添加文檔。
- 文檔的內容不要包含關於測試用例的太詳細的信息。
- 測試用例本身就應該足夠清楚易懂了。
- 重復的信息是一種浪費,而且也不容易維護。
- 文檔中可以添加一些詳細內容的鏈接。
- 如果你需要在文檔中添加一些比如(版本:1.0 或者 OS:Linux)這樣的「名稱-值」組的話,可以考慮使用測試套件 metadata

測試用例的文檔
- 測試用例通常來說不需要文檔。
- 套件名稱和文檔以及用例的名稱已經提供了足夠的背景信息。
- 測試用例的結構應該是不需要文檔或者其他注釋都足夠清楚了的。
- Tag 通常比文檔更靈活,還能提供更多的功能。
- 當測試用例的文檔是有用的時候,也不要擔心而不去添加喲。

用戶自定義關鍵詞文檔
- 如果這個關鍵詞非常簡單明了的話,不需要文檔。
- 好的名稱和明確的結構就足以說明一切了。
- 用戶自定義關鍵詞文檔的一個重要的用途是用來記錄參數和返回值的信息。
- 在 RIDE(比如在關鍵詞補全的地方)以及在資源文件中顯示的文檔是由 libdoc.py 生成的。
測試套件的結構
- 在套件中的用例應該是互相相關的。
- 如果測試用例擁有同樣的生成或者分解部分,那么他們應該是屬於一個套件的。
- 除非是數據驅動的,在一個套件中不要放10個以上的測試用例。
- 測試用例應該是獨立的。
- 用生成和分解來初始化他們。
- 有時候如果測試用例之間無法避免地相關聯
- 比如說,它可能是因為把所有的用例獨立出來要化太多的時間在初始化上。
- 相關聯的測試用例就那么幾個(最多4到5個)
- 下一個用例是用來驗證上一個用例的結果的。(用${PREV TEST STATUS} 這個內建變量)
測試用例的結構
- 測試用例應該是易懂的。
- 一個測試用例只測試一件事情。
- 當然,事情本身可大可小。
- 選擇一個合適的抽象層面。
- 一致地使用抽象水平(單一水平的抽象原則)
- 只包含與測試相關的信息。
- 用例可以分為兩種
- 工作流程的測試用例
- 數據驅動的測試用例
工作流程的測試用例
- 通常來說有以下這些部分:
- 前置條件(可選,通常在生成部分)
- 動作 (對被測系統執行一些動作)
- 驗證 (必須有一個驗證的部分!)
- 清理 (可選,通常在分解部分,以保證用例已經執行完畢)
- 關鍵詞是用來描述這個用例做了什么。
- 用清晰的關鍵詞名稱和合適的抽象層次。
- 應該包含足夠的信息使得手動執行可以啟動。
- 應該從來不需要文檔或者溝通來告訴你這個用例在做什么。
- 不同的用例可以有不同的抽象層次。
- 詳細的功能測試是更精確的。
- 端到端的測試可以是一個很高的抽象層次。
- 一個測試用例應該只使用一種抽象層次。
- 不同的風格
- 對於底層的詳細測試和集成測試用例來講應該是更關注技術細節。
- 「可執行定義」來扮演需求。
- 使用領域中的語言(術語?)。
- 所有人(包括顧客和產品負責人)都應該可以看明白。
- 不復雜的邏輯
- 不用 for 循環或者 if/else 判斷結構。
- 小心給變量賦值。
- 測試用例不應該看起來像腳本一樣難讀。
- 最多10步,越少越好。
Example using "normal" keyword-driven style:
*** Test Cases ***
Valid Login Open Browser To Login Page Input Username demo Input Password mode Submit Credentials Welcome Page Should Be Open
Example using higher level "gherkin" style:
*** 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
數據驅動的測試用例
- 每個測試用例有一個高層次的關鍵詞。
- 不同的參數創建不同的測試。
- 關鍵詞通常包含了與同一個用例文件中工作流程測試用例中描述的流程類似的流程。
- 推薦使用測試模板功能。
- 不需要多次地去重復關鍵詞。
- 在一個用例里去測試更容易去測試多種變化。
- 如果可能,推薦在列頭部命名。
- 如果真的需要很多測試用例,考慮把他們做成依賴於外部的模型。
Example:
*** 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

用戶定義關鍵詞
- 應該容易讓人理解
- 和工作流程測試用例一樣的標准。
- 不同的抽象層次。
- 可以包含一些編程邏輯(for 循環,if 判斷這些)
- 特別對於底層的的關鍵詞。
- 復雜的邏輯應該放在庫里而不是用戶定義的關鍵詞里。
變量
- 封裝長的或者復雜的值。
- 從命令行傳遞信息,使用--variable選項。
- 在關鍵詞之間傳遞信息。
變量的命名
- 清楚,但是不要太長。
- 可以在變量表格里用注釋來說明。
- 對每個使用場景保持一致:
- 小寫的本地變量只在當前的用例或者關鍵詞中可用。
- 全局變量和套件或用例級別的變量需要大寫。
- 空格或者下划線都可以用來分割變量中的詞。
- 推薦在變量表格中也把設置成動態的變量也列出來。
- 用
Set Global/Suite/Test variable內建關鍵詞來命名變量。 - 變量的初始值應該可以解釋真實的值應該是什么。
- 用
Example:
*** 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關鍵詞- 不需要在測試用例層面上有什么編程風格。
- 要遵循越比較復雜,就越難重用關鍵詞。
Good:
*** 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
Not so good:
*** 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

避免使用sleeping
- Sleeping 是非常脆弱的。
- 平均來說,安全的邊界值會使得 Sleeping 很長時間。
- 用包含了一定的動作觸發的關鍵詞來替代 Sleeping
- 關鍵詞可以用
Wait Until…來開頭。 - 等待需要有一個超時的值。
- 可能的話用內置的關鍵詞
Wait Until Keyword Succeeds來包裝其他關鍵詞。
- 關鍵詞可以用
- 有時候 Sleeping 是一種最簡單的解決方式
- 請總是小心使用。
- 不要在經常用到的自定義關鍵詞或者其他關鍵詞中用 Sleeping。
- 在 Debugging 的時候 Sleeping 用來暫停測試執行還是很有用的。
- DialogsLibrary 通常更適合用來干這個。
