如何使用Java編寫自定義的RobotFramework Lib
本文包括2個章節
1、 Robot Frdamwork中如何調用java Lib庫
2、使用 java編寫自定義的Lib
本文作者為:張永清,轉載請注明出處,版權歸作者所有。Robot Framework自動化測試框架核心指南-如何使用Java編寫自定義的RobotFramework Lib
1、 Robot Frdamwork中如何調用java Lib庫
我們在前面介紹了,Robot Framework可以支持跨語言,那么對java肯定也是可以支持的。
而且Robot Framework中,RIDE中本身也提供了對測試案例的兩種執行方式,支持pybot和jybot兩種執行方式,如下圖所示。

其中jybot 就是以java虛擬機的形式來執行測試案例,此種方式執行,執行的環境中,需要安裝java jdk運行環境以及jython 安裝包,jython是一個python語言在java中完全實現,也就是說用java來實現了python語言的功能,jython中不僅提供了python庫,也支持java方法的執行。所以jython其實就是解決了Robot Framework中python 不支持直接調用java語言的問題。Jython 可以從http://www.jython.org/downloads.html 鏈接中進行下載,然后安裝完成后,就可以在Robot Framework中進行使用,如下圖所示。

我們來看一個jython 語言來執行測試案例的例子。
示例:這是一個將字符串全部轉換成大寫形式的例子,這個例子我們用jython語言來執行。
${str} Set Variable aaBBccDDeeFF
${result} Convert To Uppercase ${str}
log ${result}
運行結果如下:
如下圖 所示,這里我們選擇了jybot 來進行執行,執行時,同pybot一樣得到了我們想要的運行結果。

其實在Robot Framework的官方網站中很多Library庫都提供了java語言版本的實現,如下圖所示。

這里我們以我們在第二章節中講到的Database Library python庫來作為示例,來看下這個庫對應的java語言的實現以及如何來通過java語言的形式來進行調用。
我們使用時,可以通過Robot Framework提供的maven插件robotframework-maven-plugin來直接引入
<dependency>
<groupId>com.github.hi-fi</groupId>
<artifactId>robotframework-dblibrary</artifactId>
<version>3.1.1</version>
</dependency>
或者我們將源碼下載下來后,自己通過執行編譯打包的方式來生成都可以。這里我們選擇直接用源碼的形式進行編譯,源碼可以從https://github.com/Hi-Fi/robotframework-dblibrary上直接獲取到。下載完成解壓到自己需要的目錄后,可以通過cmd命令行切入到對應的目錄下,使用maven命令行進行編譯,前提是需要在自己的環境中事先安裝好maven的編譯環境,編譯打包時執行mvn clean install -Dmaven.test.skip=true 即可以生成我們想要的java語言實現的Library庫,如下圖所示。


打包完成后,再生成的target目錄中,就可以獲取到編譯好的java語言實現的Library,如下圖所示。

將編譯生成好的robotframework-dblibrary-3.2-SNAPSHOT.jar包和mysql的Driver驅動包一起加入到運行環境的CLASSPATH下面,然后在測試案例集中引入DatabaseLibrary庫,如下圖所示。

引入后,我們就可以正常使用jython的方式來調用java語言版本的DatabaseLibrary庫了,如下圖所示。

使用java語言版本的DatabaseLibrary庫中的關鍵字時,和使用python語言版本的DatabaseLibrary庫中的部分關鍵字的傳參有些不一樣。Java語言版本的DatabaseLibrary連接數據庫時,是通過jdbc的方式來進行鏈接,這里我們列舉了java語言版本的DatabaseLibrary庫鏈接一些常用數據庫的示例,如下表所示。Java語言版本的Connect To Database關鍵字接收 [數據庫driver類|jdbc鏈接地址|數據庫用戶名|數據庫密碼| alias=default ]五個參數,alias如果不傳入的話,默認為取名為default。
| Connect To Database |
com.mysql.jdbc.Driver |
jdbc:mysql://localhost:3306/world |
root |
root |
連接mysql數據庫 |
| Connect To Database |
oracle.jdbc.driver.OracleDriver |
jdbc:oracle:thin:@servername:port:dbname |
system |
12345678 |
連接oracle數據庫 |
| Connect To Database |
org.h2.Driver |
jdbc:h2:mem:robotframeworkt;DB_CLOSE_DELAY=-1 |
sa |
sa |
連接h2數據庫庫 |
這里我們看一個java語言實現的DatabaseLibrary庫的源碼的片段,讓大家可以了解下,java語言版本中是如何實現和封裝關鍵字的,這是Connect To Database關鍵字的實現方法,
我們可以看到是通過在方法上加java注解的方式來實現的,@RobotKeyword和@ArgumentNames注解均來自javalib-core庫,我們自己在開發時,可以通過maven依賴的方式引入。
<dependency> <groupId>org.robotframework</groupId> <artifactId>javalib-core</artifactId> <version>1.2.1</version> </dependency>
DatabaseLibrary庫的源碼片段:
@RobotKeyword("Establish the connection to the database. This is mandatory before any of"
+ "the other keywords can be used and should be ideally done during the "
+ "suite setup phase. To avoid problems ensure to close the connection again "
+ "using the disconnect-keyword.\n\n"
+ "It must be ensured that the JAR-file containing the given driver can be "
+ "found from the CLASSPATH when starting robot. Furthermore it must be "
+ "noted that the connection string is database-specific and must be valid of course.\n\n"
+ "If alias is given, connection can be later referred with that. If alias was in use, existing connection "
+ "is replaced with new one\n\n" + "" + "Example: \n"
+ "| Connect To Database | com.mysql.jdbc.Driver | jdbc:mysql://my.host.name/myinstance | UserName | ThePassword | default |")
@ArgumentNames({ "Driver class name", "Connection string", "Database username", "Database password","Database alias=default" })
public void connectToDatabase(String driverClassName, String connectString, String dbUser, String dbPassword,
String... aliasParam)
throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException {
String alias = aliasParam.length > 0 ? aliasParam[0] : defaultAlias;
Class.forName(driverClassName).newInstance();
setConnection(DriverManager.getConnection(connectString, dbUser, dbPassword), alias);
}
除了通過jython語言來調用java的Library外,我們還可以通過Remote的方式來實現調用Java語言實現的Library庫。從https://github.com/ombre42/jrobotremoteserver 鏈接中,可以獲取到用java語言來實現的遠程接口服務,如下圖所示。

我們不建議在實際工作中,過多的使用的jython的方式來調用java語言實現的Library,因為每個測試案例在執行時,都需要一個啟動jvm虛擬機的過程,執行會比使用python語言的方式執行耗時更長,而且兼容性並不是十分好,推薦使用Remote的方式來調用Java語言實現的Library庫。
2、使用 java編寫自定義的Lib
本文作者為:張永清,轉載請注明出處,版權歸作者所有。Robot Framework自動化測試框架核心指南-如何使用Java編寫自定義的RobotFramework Lib
前面我們已經講了如何調用java語言編寫的Lib庫,這一節中,我們來介紹下如何使用java語言編寫自定義的Lib庫。
要使用java編寫自定義Lib庫,我們首先需要構建一個java的開發工程,這里我們以構建一個java的maven項目為例。在構建的maven工程的的pom.xml文件中,我們需要引入如下必要依賴。
<dependency> <groupId>org.robotframework</groupId> <artifactId>javalib-core</artifactId> <version>0.9.1</version> </dependency>
這個是必須引入的依賴包,作用是提供了創建RobotFramework的關鍵字的注解等功能,方便我們快速的去創建一個Lib庫以及對應的關鍵字。
<dependency> <groupId>com.github.ombre42</groupId> <artifactId>jrobotremoteserver</artifactId> <version>2.0-BETA</version> </dependency>
這個是Remote Server的依賴包,作用是可以啟動一個RobotFramework的遠程調用接口服務,然后RIDE中通過Remote的方式就可以連接到該遠程調用服務上,如果不使用遠程調用服務的話,可以不引入該依賴包。
<plugin>
<groupId>com.googlecode.robotframework-maven-plugin</groupId>
<artifactId>robotframework-maven-plugin</artifactId>
<version>1.1.1</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<configuration>
<variables>
<variable>BUILDING:True</variable>
</variables>
</configuration>
</plugin>
</plugins>
這個是RobotFramework提供的maven插件,這個不是一個必須的maven工程依賴,該插件的作用在於可以模擬我們的RIDE一樣來執行測試案例,在使用maven編譯打包時,可以同時來執行RobotFramework的測試案例。通過如下的方式來指定測試案例的位置。
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
在maven工程構建好了后,我們就可以來編寫自定義的Lib庫了,下表中描述了使用java語言來編寫自定義Lib時,一些常用的java注解。
| 注解名稱 |
使用描述 |
| @RobotKeywords |
該注解一般用於java類的頭部,用來標注該java類提供的是一個RobotFramework關鍵字類。 |
| @RobotKeyword |
該注解和@RobotKeywords注解需要一起配合使用,@RobotKeyword注解一般用於java中的某個具體方法的頭部,用來標注該方法提供的是一個RobotFramework關鍵字。 可以通過@RobotKeyword后面加括號的方式來說明該關鍵字的用途,比如@RobotKeyword("這是一個示例關鍵字") |
@ArgumentNames |
該注解需要和@RobotKeyword注解一起使用,該注解用於標注一個RobotFramework關鍵字需要傳入的參數,使用示例: @ArgumentNames({"elementString"}) |
代碼示例:我們這里用java的方式來實現RobotFramework 中的Sting Lib庫(如下圖所示)中的部分關鍵字Convert To Lowercase和Convert To Uppercase。

package com.example.keywords; import org.robotframework.javalib.annotation.ArgumentNames; import org.robotframework.javalib.annotation.RobotKeyword; import org.robotframework.javalib.annotation.RobotKeywords; @RobotKeywords public class StringKeyWord { @RobotKeyword("Convert To Lowercase") @ArgumentNames({"string"}) public String convertToLowercase(String string) { System.out.print("Convert "+string+" To Lowercase"); return string.toLowerCase(); } @RobotKeyword("Convert To Uppercase") @ArgumentNames({"string"}) public String convertToUppercase(String string){ System.out.print("Convert "+string+" To Uppercase"); return string.toUpperCase(); } } 關鍵字編寫完了后,我們還需要定義一個Library庫,通過繼承AnnotationLibrary這個類, 並且這里我們通過RemoteServer的方式來啟動。 package com.example; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.nio.charset.Charset; import org.apache.commons.io.IOUtils; import org.robotframework.javalib.library.AnnotationLibrary; import org.robotframework.remoteserver.RemoteServer; public class MyRemoteLibrary extends AnnotationLibrary { public MyRemoteLibrary() { // 關鍵字類的路徑 super("com/example/keywords/*.class"); } @Override public String getKeywordDocumentation(String keywordName) { if (keywordName.equals("__intro__")) return getIntro(); return super.getKeywordDocumentation(keywordName); } /** * 遠程接口服務的啟動 * @param args * @throws Exception */ public static void main(String[] args) throws Exception { RemoteServer.configureLogging(); RemoteServer server = new RemoteServer(); //向server中加入自定義的library,並且設置遠程接口服務的端口 server.addLibrary(MyRemoteLibrary.class, 8270); server.start(); } /** * 定義Library的說明信息 * @return */ private String getIntro() { try { InputStream introStream = MyRemoteLibrary.class.getResourceAsStream("__intro__.txt"); StringWriter writer = new StringWriter(); IOUtils.copy(introStream, writer, Charset.defaultCharset()); return writer.toString(); } catch (Exception e) { throw new RuntimeException(e); } } }
定義完Library后,我們就可以以RemoteServer的方式來啟動我們的遠程接口服務,如下圖中所示

在RIDE中,我們通過Remote 連接到我們啟動的遠程接口服務中,如下圖所示。

然后通過F5快捷鍵,就可以看到我們遠程服務中定義的關鍵字了,如下圖所示。

示例:我們通過一個示例來調用一下我們遠程接口服務中定義的關鍵字,如下圖所示。

運行結果如下:
Starting test: RobotFrameworkTest1.TestSuite11.TestCase001
20180822 10:04:23.328 : INFO : Convert robotFramework To Lowercase
20180822 10:04:23.328 : INFO : ${strLowercase } = robotframework
20180822 10:04:23.330 : INFO : robotframework
20180822 10:04:23.337 : INFO : Convert robotframework To Uppercase
20180822 10:04:23.338 : INFO : ${strUppercase } = ROBOTFRAMEWORK
20180822 10:04:23.340 : INFO : ROBOTFRAMEWORK
Ending test: RobotFrameworkTest1.TestSuite11.TestCase001
從運行結果看,可以成功調用到我們遠程接口服務中自定義編寫的兩個關鍵字。
上面我們是通過RemoteServer的方式來調用java編寫的自定義的關鍵字,我們也可以改用jybot的方式來調用java編寫的自定義關鍵字,在工程中,我們引入maven-assembly-plugin這個插件,這個插件可以通過執行mvn clean assembly:assembly -Dmaven.test.skip=true 打包時,將所有相關的依賴包打包在一個jar包中,方便我們在執行時,不需要手動一個個去配置執行時需要依賴的其它相關jar包。
<properties>
<!-- 定義打包時的字符集格式 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<testLibraryClass>MyRemoteLibrary</testLibraryClass>
</properties>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<!-- 配置執行時的java main方法 -->
<mainClass>${testLibraryClass}</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-my-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
另外需要注意是,我們需要將我們上面定義的MyRemoteLibrary這個類移動到我們maven工程的根目錄下,如下圖所示。

執行mvn clean assembly:assembly -Dmaven.test.skip=true打包后,就可以生成我們需要的jar包了,如下圖所示。

將MyRemoteLibrary-1.0-jar-with-dependencies.jar 放置到java的classpath目錄下后,我們就可以在RIDE中引入MyRemoteLibrary庫了,如下圖所示。

引入后,我們再用jybot的方式執行上面RemoteServer運行時的同樣示例,如下圖所示。

運行結果如下:如下圖所示。

可以看到,運行后得到了同樣的結果。
備注:本文內容摘選自作者自己出版的Robot Framework自動化測試框架核心指南 一書。
關於自動化測試的更多內容,請關注:

Robot Framework自動化測試框架核心指南京東官方購買
Robot Framework自動化測試框架核心指南電子版試讀
Robot Framework自動化測試框架核心指南天貓官方旗艦店購買
Robot Framework自動化測試框架核心指南當當網購買
Robot Framework自動化測試框架核心指南 作者簽名版本購買
相關博文匯總:
RobotFramework下的http接口自動化Create Http Context關鍵字的使用
RobotFramework下的http接口自動化Get關鍵字的使用
RobotFramework下的http接口自動化post關鍵字的使用
RobotFramework下的http接口自動化Get Response Body關鍵字的使用
RobotFramework下的http接口自動化Get Response Status 關鍵字的使用
RobotFramework下的http接口自動化Get Response header 關鍵字的使用
RobotFramework下的http接口自動化Set Request Header 關鍵字的使用
RobotFramework下HttpLibrary庫其它關鍵字
RobotFramework下的http接口自動化Set Request Body 關鍵字的使用
RobotFramework下的http接口自動化Follow Response關鍵字的使用
RobotFramework自動化測試框架的基礎關鍵字(一)
RobotFramework自動化測試框架的基礎關鍵字(二)
RobotFramework自動化測試框架的基礎關鍵字(三)
RobotFramework自動化測試框架的基礎關鍵字(四)
RobotFramework自動化測試框架的基礎關鍵字(五)
RobotFramework自動化測試框架-移動手機自動化測試AppiumLibrary介紹
RobotFramework自動化測試框架-移動手機自動化測試Open Application關鍵字的使用
RobotFramework自動化測試框架-移動手機自動化測試AppiumLibrary庫其它的常見自動化關鍵字
RobotFramework自動化測試框架-移動手機自動化測試Input Text和Click Button關鍵字的使用
RobotFramework自動化測試框架-移動手機自動化測試Clear Text關鍵字的使用
RobotFramework自動化測試框架-移動手機自動化測試Click Element關鍵字的使用
RobotFramework自動化測試框架-移動手機自動化測試Click A Point關鍵字的使用
RobotFramework自動化測試框架-移動手機自動化測試Click Element At Coordinates關鍵字的使用
RobotFramework自動化測試框架-移動手機自動化測試Get Element Location關鍵字的使用
RobotFramework自動化測試框架-移動手機自動化測試Get Network Connection Status和Set Network Connection Status關鍵字的使用
RobotFramework自動化測試框架-移動手機自動化測試Element Attribute Should Match關鍵字的使用
RobotFramework自動化測試框架-DatabaseLibrary庫的使用(對數據庫的操作)
RobotFramework自動化測試框架-使用Python編寫自定義的RobotFramework Lib
RobotFramework自動化測試框架-Selenium Web自動化(-)-Open Browser和Close Browser
RobotFramework自動化測試框架-Selenium Web自動化(二)關於在RobotFramework中如何使用Selenium很全的總結(上)
RobotFramework自動化測試框架-MongoDBLibrary庫的使用
