robotframework筆記24


偵聽器接口

機器人框架有一個偵聽器接口,可以用於接收 對測試執行通知。 示例用法包括 外部測試監控,測試失敗時發送郵件消息, 與其他系統進行通信。 偵聽器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 可以使用。

在偵聽器API方法2
方法 參數 文檔
start_suite 名稱、屬性

當一個測試套件的開始。

內容屬性字典:

  • id :套件id。 s1 的頂層套房, s1-s1 第一個孩子套件, s1-s2 對於第二個 孩子,等等。 在射頻2.8.5新。
  • longname :套件名稱包括父套件。
  • 醫生 :套件文檔。
  • 元數據 免費測試套件的元數據 作為一個字典/地圖。
  • 源 :文件/目錄的絕對路徑 被創建的。 新在射頻2.7。
  • 套房 :直接兒童套房此套件的名稱 作為一個列表。
  • 測試 :測試此套件的名稱列表。 不包括測試可能的兒童套房。
  • totaltests :在此套件測試的總數。 及其所有sub-suites作為一個整數。
  • 開始時間 :套件執行開始時間。
end_suite 名稱、屬性

當一個測試套件。

內容屬性字典:

  • id :一樣 start_suite 
  • longname :一樣 start_suite 
  • 醫生 :一樣 start_suite 
  • 元數據 :一樣 start_suite 
  • 源 :一樣 start_suite 
  • 開始時間 :一樣 start_suite 
  • endtime :套件執行結束時間。
  • elapsedtime :總執行時間以毫秒為單位 一個整數
  • 狀態 :套件作為字符串 通過 或 失敗 
  • 統計數據 :套件統計(傳遞的數量 和失敗的測試套件)作為一個字符串。
  • 消息 :錯誤消息如果套件安裝或拆卸 沒有,否則空。
start_test 名稱、屬性

當一個測試用例開始。

內容屬性字典:

  • id :測試id等格式 s1-s2-t2 ,在那里 一開始是父組件id和最后一部分 顯示測試套件的指數。 在射頻2.8.5新。
  • longname 父套件包括:測試名稱。
  • 醫生 :測試文檔。
  • 標簽 :測試標簽作為一個字符串列表。
  • 至關重要的 是的 或 沒有 根據測試被認為是 至關重要的。
  • 模板 :用於測試模板的名稱。 一個空字符串如果測試沒有模板化。
  • 開始時間 測試執行:執行開始時間。
end_test 名稱、屬性

當測試用例結束。

內容屬性字典:

  • id :一樣 start_test 
  • longname :一樣 start_test 
  • 醫生 :一樣 start_test 
  • 標簽 :一樣 start_test 
  • 至關重要的 :一樣 start_test 
  • 模板 :一樣 start_test 
  • 開始時間 :一樣 start_test 
  • endtime 測試執行:執行結束時間。
  • elapsedtime :總執行時間以毫秒為單位 一個整數
  • 狀態 :測試作為字符串 通過 或 失敗 
  • 消息 :狀態信息。 通常一個錯誤 消息或一個空字符串。
start_keyword 名稱、屬性

當一個字開始。

的名字 是完整的包含關鍵字的名字嗎 可能的庫或資源名稱作為前綴。 例如, MyLibrary。 例子的關鍵字 

內容屬性字典:

  • 類型 :字符串 關鍵字 普通關鍵字, 設置 或 拆卸 的頂級關鍵詞作為安裝/拆卸, 為 for循環, 為項目 對個人for循環 迭代。注意: 關鍵字類型報告了 3.0射頻。 看到問題 # 2248 獲取詳細信息。
  • kwname :沒有庫或關鍵字的名字 資源前綴。 新在射頻2.9。
  • 庫名 :圖書館或資源的名稱 關鍵詞屬於,或一個空字符串 關鍵字在一個測試用例文件。 新在射頻2.9。
  • 醫生 :關鍵字的文檔。
  • arg游戲 :關鍵字參數作為一個字符串列表。
  • 分配 :一個變量名,關鍵字的列表 返回值分配給。 新在射頻2.9。
  • 標簽 關鍵字標簽 作為一個字符串列表。 新在射頻3.0。
  • 開始時間 :關鍵字執行開始時間。
end_keyword 名稱、屬性

一個關鍵字結束的時候叫。

的名字 是完整的包含關鍵字的名字嗎 可能的庫或資源名稱作為前綴。 例如, MyLibrary。 例子的關鍵字 

內容屬性字典:

  • 類型 :一樣 start_keyword 
  • kwname :一樣 start_keyword 
  • 庫名 :一樣 start_keyword 
  • 醫生 :一樣 start_keyword 
  • arg游戲 :一樣 start_keyword 
  • 分配 :一樣 start_keyword 
  • 標簽 :一樣 start_keyword 
  • 開始時間 :一樣 start_keyword 
  • endtime :關鍵字執行結束時間。
  • elapsedtime :總執行時間以毫秒為單位 一個整數
  • 狀態 :關鍵字作為字符串 通過 或 失敗 
log_message 消息

當執行一個字寫一個日志消息。

消息 是一個字典,以下內容:

  • 消息 :消息的內容。
  • 水平 日志級別 用於日志消息。
  • 時間戳 :消息創建時間格式 YYYY-MM-DD hh:mm:ss.mil 
  • html :字符串 是的 或 沒有 表示消息是否 應該解釋為HTML或不是。

3.0從射頻,調用這個方法並不是如果消息 低於當前水平嗎 閾值水平 

消息 消息

框架本身寫時調用的方法 syslog 消息。

消息 字典的內容是一樣的嗎 log_message 方法。

library_import 名稱、屬性

時調用一個圖書館已導入。

的名字 是導入的庫的名稱。 如果圖書館 使用進口嗎 與名語法 的名字 是 指定的別名。

內容屬性字典:

  • arg游戲 :參數傳遞給庫列表。
  • originalname 當使用:原庫的名字 與名語法,否則一樣 的名字 
  • 源 :絕對路徑庫源。 沒有一個 與庫與Java或者得到實現 源庫失敗的一些原因。
  • 進口國 :一個絕對路徑文件導入 圖書館。 沒有一個 當 內裝式 當導入得好嗎 使用 導入庫 關鍵字。

2.9新機器人框架。

resource_import 名稱、屬性

當一個資源文件導入。

的名字 是導入的資源文件的名字沒有 文件擴展名。

內容屬性字典:

  • 源 :導入的資源文件的絕對路徑。
  • 進口國 :一個絕對路徑文件導入 資源文件。 沒有一個 當使用 進口資源 關鍵字。

2.9新機器人框架。

variables_import 名稱、屬性

時調用一個變量文件導入。

的名字 是進口變量文件的名稱 文件擴展名。

內容屬性字典:

  • arg游戲 :參數傳遞到變量文件作為一個列表。
  • 源 :進口變量文件的絕對路徑。
  • 進口國 :一個絕對路徑文件導入 資源文件。 沒有一個 當使用 進口 變量 關鍵字。

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的所有方法。 的 主要原因是 合適的模型對象內部不可用 。 的 關閉 方法和方法相關的輸出文件被稱為完全 在兩個版本一樣。

在偵聽器API方法3
方法 參數 文檔
start_suite 數據,結果

當一個測試套件的開始。

數據 和 結果 模型對象是代表 的 執行測試套件 和 它的 執行結果 ,分別。

end_suite 數據,結果

當一個測試套件。

同樣的參數作為 start_suite 

start_test 數據,結果

當一個測試用例開始。

數據 和 結果 模型對象是代表 的 執行測試用例 和 它的 執行結果 ,分別。

end_test 數據,結果

當測試用例結束。

同樣的參數作為 start_test 

start_keyword N /一個 在射頻3.0中沒有實現。
end_keyword N /一個 在射頻3.0中沒有實現。
log_message 消息

當執行一個字寫一個日志消息。 消息 是一個模型對象代表 記錄 消息 

調用這個方法並不是如果消息級別以下 當前的 閾值水平 

消息 消息

框架本身寫時調用的方法 syslog 消息。

消息 是相同的對象 log_message 

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"); } else { outfile.write("FAIL: " + attrs.get("message") + "\n"); } } public void endSuite(String name, Map attrs) throws IOException { outfile.write(attrs.get("status") + "\n" + attrs.get("message") + "\n"); } public void close() throws IOException { outfile.close(); } } 

修改執行和結果

這些例子說明如何修改執行測試和套房 以及執行結果。 所有這些例子都需要使用 的 偵聽器版本3 

修改測試套件和執行

改變是什么需要修改模型對象包含執行 的執行 測試套件 或 測試用例 作為第一個參數傳遞給對象 start_suite 和 start_test 方法。 下面的示例所示 添加一個新的測試,每個測試套件和一個新的關鍵字來執行每個測試。

ROBOT_LISTENER_API_VERSION = 3 def start_suite(suite, result): suite.tests.create(name='New test') def start_test(test, result): test.keywords.create(name='Log', args=['Keyword added by listener!']) 

試圖修改執行 end_suite 或 end_test 方法不工作, 僅僅因為這套房或測試已經執行。 試圖修改 名稱、文檔或其他類似的當前套件或元數據 測試 start_suite 或 start_test 方法不奏效,因為 相應的結果對象已經創建。 只有改變 實際上孩子測試或關鍵詞有影響。

這個API非常相似 跑前修飾符 可以使用API 修改套件和測試在整個測試執行開始之前。 主要的 使用偵聽器API的好處是,可以做修改 根據執行結果或動態。 例如,這使得 基於模型的測試的有趣的可能性。

盡管偵聽器接口不是機器人框架之上的 內部 訪問接口 同樣是跑前修改器API, 聽眾自己仍然可以使用游客接口。 例如, 的 SelectEveryXthTest 客人使用 跑前修飾符 例子可以 使用這樣的:

from SelectEveryXthTest import SelectEveryXthTest ROBOT_LISTENER_API_VERSION = 3 def start_suite(suite, result): selector = SelectEveryXthTest(x=2) suite.visit(selector) 
修改的結果

測試執行結果可以被修改 測試套件 和 測試用例 結果對象 作為第二個參數傳遞 start_suite 和 start_test 方法, 分別通過修改 消息 對象傳遞 到 log_message 方法。 這是證明了下面的聽眾 這是作為一個類實現。

class ResultModifier(object): ROBOT_LISTENER_API_VERSION = 3 def __init__(self, max_seconds=10): self.max_milliseconds = float(max_seconds) * 1000 def start_suite(self, data, suite): suite.doc = 'Documentation set by listener.' # Information about tests only available via data at this point. smoke_tests = [test for test in data.tests if 'smoke' in test.tags] suite.metadata['Smoke tests'] = len(smoke_tests) def end_test(self, data, test): if test.status == 'PASS' and test.elapsedtime > self.max_milliseconds: test.status = 'FAIL' test.message = 'Test execution took too long.' def log_message(self, msg): if msg.level == 'WARN' and not msg.html: msg.message = '<b style="font-size: 1.5em">%s</b>' % msg.message msg.html = True 

一個限制是,修改現有的測試套件的名稱或測試 情況下是不可能的,因為它已經被寫入 output.xml 文件時,調用偵聽器。 由於同樣的原因修改了 完成了測試 end_suite 方法沒有效果。

這個API非常相似 pre-Rebot修飾符 可以使用API 修改結果報告和日志生成之前。 主要的區別是 聽眾修改創建的 output.xml 文件。

測試庫作為監聽器

有時它也很有用 測試庫 以獲得關於的通知 測試執行。 這允許它們,例如,執行特定的清理 活動時自動測試套件或整個測試執行結束。

請注意

這個功能是新的2.8.5機器人框架。

注冊監聽器

一個測試庫可以通過注冊一個偵聽器 ROBOT_LIBRARY_LISTENER 屬性。 這個屬性的值應該偵聽器的一個實例 使用。 它可能是一個完全獨立的偵聽器或圖書館本身 作為一個偵聽器。 為了避免偵聽器方法公開為關鍵詞 后者的情況下,可以用下划線前綴。 例如,而不是使用 end_suite 或 endSuite ,它是 可以使用 _end_suite 或 _endSuite 

下面的例子演示了使用外部偵聽器以及圖書館 作為一個偵聽器本身:

import my.project.Listener; public class JavaLibraryWithExternalListener { public static final Listener ROBOT_LIBRARY_LISTENER = new Listener(); public static final String ROBOT_LIBRARY_SCOPE = "GLOBAL"; public static final int ROBOT_LISTENER_API_VERSION = 2; // actual library code here ... } 
class PythonLibraryAsListenerItself(object): ROBOT_LIBRARY_SCOPE = 'TEST SUITE' ROBOT_LISTENER_API_VERSION = 2 def __init__(self): self.ROBOT_LIBRARY_LISTENER = self def _end_suite(self, name, attrs): print 'Suite %s (%s) ending.' % (name, attrs['id']) # actual library code here ... 

如上秒的例子已經證明,圖書館的聽眾 指定 監聽器接口的版本 使用 ROBOT_LISTENER_API_VERSION 屬性就像其他任何偵聽器。

從2.9版開始,您還可以提供任何喜歡的對象列表 實例的 ROBOT_LIBRARY_LISTENER 屬性。 這將會導致所有的 注冊作為監聽器實例的列表。

偵聽器方法調用

圖書館的偵聽器將得到關於套件中所有事件通知 圖書館是進口的。 在實踐中這意味着 start_suite end_suite start_test end_test start_keyword end_keyword log_message ,消息 方法是 在這些套件。

如果庫創建一個新的偵聽器實例每次圖書館 本身就是實例化,實際使用的監聽器實例將會改變 根據 測試庫范圍 。 除了前面列出的偵聽器方法, 關閉 方法被調用時,圖書館超出范圍。

看到 監聽器接口方法 上面部分的更多信息 所有這些方法。

擴展機器人框架Jar

額外的測試庫或支持代碼添加到機器人框架jar 很簡單的使用 jar 命令包含在標准JDK 安裝。 必須放置在Python代碼 自由 目錄里面 jar和Java代碼可以直接放在jar的根源,根據 包結構。

例如,添加Python包 mytestlib jar,第一次復制 mytestlib 目錄下的一個目錄 自由 ,然后運行 目錄包含以下命令 自由 :

jar uf /path/to/robotframework-2.7.1.jar Lib

編譯后的java類添加到罐子里,你必須有一個目錄結構 對應於Java包結構和添加,遞歸 郵政編碼。

例如,添加類 MyLib.class 在包 org.test , 必須的文件 org/test/MyLib.class 你可以執行:

jar uf /path/to/robotframework-2.7.1.jar org


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM