偵聽器接口
機器人框架有一個偵聽器接口,可以用於接收 對測試執行通知。 示例用法包括 外部測試監控,測試失敗時發送郵件消息, 與其他系統進行通信。 偵聽器API版本3也使得 它可以修改測試在測試執行和結果。
偵聽器類或模塊與某些特殊的方法,和他們 可以用Python和Java實現。 偵聽器監控 整個測試執行必須納入使用從命令行。 除此之外, 測試庫可以注冊偵聽器 接收 通知,圖書館是活躍的。
監聽使用
監聽被使用從命令行 ——偵聽器 選項,偵聽器是給它的名稱作為參數。 的 偵聽器的名稱叫從類或模塊實現 監聽器接口,同樣 測試庫的名字 從類 實現它們。 指定監聽器必須是相同的 模塊搜索 路徑 在測試庫搜索時都是進口的。 其他 選擇是給聽眾一個絕對或相對路徑文件 同樣與測試庫 。 可以把多個偵聽器 通過多次使用這個選項使用:
robot --listener MyListener tests.robot robot --listener com.company.package.Listener tests.robot robot --listener path/to/MyListener.py tests.robot robot --listener module.Listener --listener AnotherListener tests.robot
還可以給偵聽器類從命令參數 線。 參數指定偵聽器后名稱使用冒號(或路徑) ( :
)作為分隔符。 如果一個偵聽器作為一個絕對Windows路徑, 冒號后驅動器並不被視為分隔符。 從 2.8.7機器人框架,可以使用分號( ;
)作為 替代參數分隔符。 這是有用的偵聽器參數 包含冒號,但是需要周圍的整個價值 引用在類unix操作系統:
robot --listener listener.py:arg1:arg2 tests.robot robot --listener "listener.py;arg:with:colons" tests.robot robot --listener C:\Path\Listener.py;D:\data;E:\extra tests.robot
偵聽器接口版本
有兩個版本支持偵聽器接口。 偵聽器版本2 因為機器人框架2.1,支持版本3 機器人3.0和新框架。 一個監聽器必須有屬性 ROBOT_LISTENER_API_VERSION
值2或3,作為字符串或作為 整數,這取決於它所使用的API版本。 也有一個年長的 偵聽器版本1,但是它不支持了由機器人框架3.0。
偵聽器版本2和3之間的主要區別是前者 得到執行,但不能直接影響它的信息。 后者 接口獲取數據和結果對象機器人框架本身使用,因此 能改變執行和變化的結果。 看到 偵聽器的例子 更多的 信息的聽眾能做什么。
另一個版本2和3之間的區別是,前者支持 Python和Java,但后者只支持Python。
偵聽器接口方法
機器人框架測試執行時創建偵聽器類的實例 直接啟動和使用監聽器實現模塊。 在測試期間 執行不同的偵聽器方法時調用測試套件、測試用例 和關鍵詞的開始和結束。 額外的方法被稱為當圖書館或 資源或變量文件導入,當輸出文件准備好了, 最后整個測試執行結束時。 不需要一個偵聽器 實現任何官方接口,它只需要它的方法 實際的需求。
偵聽器版本2和3有基本相同的方法,但是參數 他們接受是不同的。 這些方法及其參數解釋道 在接下來的部分。 所有的方法都有一個強調以他們的名義 也 camelCase 的選擇。 例如,start_suite
方法可以 也有使用的名字 startSuite
。
偵聽器版本2
偵聽器API版本2中的方法在下表中列出。 所有方法與測試執行進展具有相同的簽名 方法(名稱、屬性)
,在那里 屬性
是一個詞典,它包含 事件的細節。 偵聽器方法可以自由做任何他們想做的事 他們收到的信息,但他們不能直接改變 它。 如果這是必要的, 偵聽器版本3 可以使用。
方法 | 參數 | 文檔 |
---|---|---|
start_suite | 名稱、屬性 | 當一個測試套件的開始。 內容屬性字典:
|
end_suite | 名稱、屬性 | 當一個測試套件。 內容屬性字典:
|
start_test | 名稱、屬性 | 當一個測試用例開始。 內容屬性字典:
|
end_test | 名稱、屬性 | 當測試用例結束。 內容屬性字典:
|
start_keyword | 名稱、屬性 | 當一個字開始。
內容屬性字典:
|
end_keyword | 名稱、屬性 | 一個關鍵字結束的時候叫。
內容屬性字典:
|
log_message | 消息 | 當執行一個字寫一個日志消息。
3.0從射頻,調用這個方法並不是如果消息 低於當前水平嗎 閾值水平 。 |
消息 | 消息 | 框架本身寫時調用的方法 syslog 消息。
|
library_import | 名稱、屬性 | 時調用一個圖書館已導入。
內容屬性字典:
2.9新機器人框架。 |
resource_import | 名稱、屬性 | 當一個資源文件導入。
內容屬性字典:
2.9新機器人框架。 |
variables_import | 名稱、屬性 | 時調用一個變量文件導入。
內容屬性字典:
2.9新機器人框架。 |
output_file | 路徑 | 當編寫一個 輸出文件 已經准備好了。
|
log_file | 路徑 | 當寫作 日志文件 已經准備好了。
|
report_file | 路徑 | 當寫作 報告文件 已經准備好了。
|
xunit_file | 路徑 | 當編寫一個 xunit文件 已經准備好了。
|
debug_file | 路徑 | 當寫作 調試文件 已經准備好了。
|
關閉 | 整個測試執行結束時調用。 與 圖書館的聽眾 外出時調用圖書館 的范圍。 |
可用的方法和他們的論點也正式Java所示 下面的接口規范。 的內容 java.util。 映射屬性
是 如上表。 它應該記得一個偵聽器 不 需要 實現任何顯式接口或者所有這些方法。
public interface RobotListenerInterface { public static final int ROBOT_LISTENER_API_VERSION = 2; void startSuite(String name, java.util.Map attributes); void endSuite(String name, java.util.Map attributes); void startTest(String name, java.util.Map attributes); void endTest(String name, java.util.Map attributes); void startKeyword(String name, java.util.Map attributes); void endKeyword(String name, java.util.Map attributes); void logMessage(java.util.Map message); void message(java.util.Map message); void outputFile(String path); void logFile(String path); void reportFile(String path); void debugFile(String path); void close(); }
偵聽器版本3
偵聽器版本3相同的方法 偵聽器版本2 但相關參數的方法測試執行是不同的。 這個API得到實際運行和結果模型對象所使用的機器人 框架本身,聽眾可以直接查詢信息 他們需要和動態變化的模型對象。
偵聽器版本3是在機器人框架3.0中引入的。 至少 最初它沒有版本2的所有方法。 的 主要原因是 合適的模型對象內部不可用 。 的 關閉
方法和方法相關的輸出文件被稱為完全 在兩個版本一樣。
方法 | 參數 | 文檔 |
---|---|---|
start_suite | 數據,結果 | 當一個測試套件的開始。
|
end_suite | 數據,結果 | 當一個測試套件。 同樣的參數作為 |
start_test | 數據,結果 | 當一個測試用例開始。
|
end_test | 數據,結果 | 當測試用例結束。 同樣的參數作為 |
start_keyword | N /一個 | 在射頻3.0中沒有實現。 |
end_keyword | N /一個 | 在射頻3.0中沒有實現。 |
log_message | 消息 | 當執行一個字寫一個日志消息。 調用這個方法並不是如果消息級別以下 當前的 閾值水平 。 |
消息 | 消息 | 框架本身寫時調用的方法 syslog 消息。
|
library_import | N /一個 | 在射頻3.0中沒有實現。 |
resource_import | N /一個 | 在射頻3.0中沒有實現。 |
variables_import | N /一個 | 在射頻3.0中沒有實現。 |
output_file | 路徑 | 當編寫一個 輸出文件 已經准備好了。
|
log_file | 路徑 | 當寫作 日志文件 已經准備好了。
|
report_file | 路徑 | 當寫作 報告文件 已經准備好了。
|
xunit_file | 路徑 | 當編寫一個 xunit文件 已經准備好了。
|
debug_file | 路徑 | 當寫作 調試文件 已經准備好了。
|
關閉 | 整個測試執行結束時調用。 與 圖書館的聽眾 外出時調用圖書館 的范圍。 |
4.3.4聽眾日志
機器人提供了一個框架 程序化的日志記錄api 聽眾可以 利用。 有一些局限性,然而,不同的聽眾 方法可以日志消息在下面的表格說明。
方法 | 解釋 |
---|---|
start_keyword, end_keyword, log_message | 消息記錄到正常 日志文件 根據關鍵字執行。 |
start_suite, end_suite, start_test,end_test | 消息記錄到 syslog 。 警告 所示的 執行錯誤 的部分 正常的日志文件。 |
消息 | syslog消息通常是記錄。 如果 這個方法用於執行關鍵字時, 消息記錄到日志文件正常。 |
其他方法 | 只記錄到syslog的消息。 |
請注意
為了避免遞歸,聽眾不發送消息記錄 偵聽器方法 log_message
和 消息
。
偵聽器的例子
本節包含的例子使用偵聽器接口。 有 第一個例子,剛從機器人框架,然后接收信息 示例修改執行測試並創建的結果。
獲取信息
第一個例子是作為Python模塊實現和使用 偵聽器 版本2 。
"""Listener that stops execution if a test fails."""
ROBOT_LISTENER_API_VERSION = 2 def end_test(name, attrs): if attrs['status'] == 'FAIL': print 'Test "%s" failed: %s' % (name, attrs['message']) raw_input('Press enter to continue.')
如果上面的例子將被保存,例如, PauseExecution.py 文件,可以使用它從命令行如下:
robot --listener path/to/PauseExecution.py tests.robot
同樣的例子也可以使用更新的實現 偵聽器版本3 和使用完全相同的方式從命令行。
"""Listener that stops execution if a test fails."""
ROBOT_LISTENER_API_VERSION = 3 def end_test(data, result): if not result.passed: print 'Test "%s" failed: %s' % (result.name, result.message) raw_input('Press enter to continue.')
下一個示例,它仍然使用Python,稍微復雜一些。 它 寫它到一個文本文件的所有信息在一個臨時目錄中 沒有格式。 文件名可以從命令行,但是 也有一個默認值。 請注意,在實際使用中, 調試文件 功能可以通過命令行選項 ——debugfile 是 可能比這個例子更有用。
import os.path import tempfile class PythonListener: ROBOT_LISTENER_API_VERSION = 2 def __init__(self, filename='listen.txt'): outpath = os.path.join(tempfile.gettempdir(), filename) self.outfile = open(outpath, 'w') def start_suite(self, name, attrs): self.outfile.write("%s '%s'\n" % (name, attrs['doc'])) def start_test(self, name, attrs): tags = ' '.join(attrs['tags']) self.outfile.write("- %s '%s' [ %s ] :: " % (name, attrs['doc'], tags)) def end_test(self, name, attrs): if attrs['status'] == 'PASS': self.outfile.write('PASS\n') else: self.outfile.write('FAIL: %s\n' % attrs['message']) def end_suite(self, name, attrs): self.outfile.write('%s\n%s\n' % (attrs['status'], attrs['message'])) def close(self): self.outfile.close()
下面的示例實現了與上一個相同的功能, 但使用Java,而不是Python。
import java.io.*; import java.util.Map; import java.util.List; public class JavaListener { public static final int ROBOT_LISTENER_API_VERSION = 2; public static final String DEFAULT_FILENAME = "listen_java.txt"; private BufferedWriter outfile = null; public JavaListener() throws IOException { this(DEFAULT_FILENAME); } public JavaListener(String filename) throws IOException { String tmpdir = System.getProperty("java.io.tmpdir"); String sep = System.getProperty("file.separator"); String outpath = tmpdir + sep + filename; outfile = new BufferedWriter(new FileWriter(outpath)); } public void startSuite(String name, Map attrs) throws IOException { outfile.write(name + " '" + attrs.get("doc") + "'\n"); } public void startTest(String name, Map attrs) throws IOException { outfile.write("- " + name + " '" + attrs.get("doc") + "' [ "); List tags = (List)attrs.get("tags"); for (int i=0; i < tags.size(); i++) { outfile.write(tags.get(i) + " "); } outfile.write(" ] :: "); } public void endTest(String name, Map attrs) throws IOException { String status = attrs.get("status").toString(); if (status.equals("PASS")) { outfile.write("PASS\n");