Robot Framework自动化测试框架核心指南-如何使用Java编写自定义的RobotFramework Lib
如何使用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的方式来启动我们的远程接口服务,如下图中所示
![](https://img2018.cnblogs.com/i-beta/1200756/202002/1200756-20200221145940234-335826251.png)
在RIDE中,我们通过Remote 连接到我们启动的远程接口服务中,如下图所示。
![](https://img2018.cnblogs.com/i-beta/1200756/202002/1200756-20200221145957305-2083552931.png)
然后通过F5快捷键,就可以看到我们远程服务中定义的关键字了,如下图所示。
![](https://img2018.cnblogs.com/i-beta/1200756/202002/1200756-20200221150015154-784196117.png)
示例:我们通过一个示例来调用一下我们远程接口服务中定义的关键字,如下图所示。
运行结果如下:
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库的使用