远程测试库接口
远程测试库接口使得测试库可以运行在Robot Framework所在之外的机器上, 并且也使测试库的实现语言不再局限于原生支持的Python和Java. 对于测试库的用户来说, 远程库和使用其它测试库基本雷同. 使用远程测试库接口来开发测试库也和创建 普通测试库 大同小异.
介绍
使用远程测试库API的两大原因:
- 是实际测试库和Robot Framework运行在不同的机器上, 可以实现分布式的测试.
- 远程测试库可以使用支持 XML-RPC 远程协议的任意编程语言来实现.对于大部分主流编程语言如Python, Java, Ruby, .NET, Clojure, Perl 和 node.js, 当前已经存在了 现成可用的远程服务 实现.
远程库接口由 standard libraries 中的 Remote 库提供. Remote库自身不提供任何关键字, 只是作为一个代理存在于测试框架和在别处实现的关键字之间.
Remote库通过远程服务器和实际的库进行交互, 它们之间的通信是基于XML-RPC的一种简单的 远程协议.
整体的结构参见下图:
Robot Framework architecture with Remote library
注解
Remote库的远程客户端使用的是Python标准库 xmlrpclib . 不支持某些XML-RPC服务器实现的自定义扩展.
使用Remote库
导入Remote库
Remote库需要指定远程服务器的地址, 其它使用关键字的方式和别的测试库并无二致. 如果在一个测试套件中用到多次Remote库, 或者只是想要取个描述性的名字, 都可以在import时使用 测试库设置别名.
- *** Settings ***
- Library Remote http://127.0.0.1:8270 WITH NAME Example1
- Library Remote http://example.com:8080/ WITH NAME Example2
- Library Remote http://10.0.0.2/example 1 minute WITH NAME Example3
如果没有提供地址, 则上面第一个例子中的URL将是Remote库所用默认值. 类似地, 如果没有指定端口, 则默认使用端口号8270. (82和70在ASCII码中分别对应字母R和F)
注解
当在本机使用时, 推荐使用地址 127.0.0.1
, 避免使用 localhost
.因为在Windows上, 地址解析可能会非常的慢, 见 问题.在2.8.4版本之前的Robot Framework中Remote库默认地址用的是localhost
注解
值得注意的是, 如果远程服务器地址的后面没有路径,Remote库所使用的 xmlrpclib模块 会默认使用 /RPC2
作为路径. 也就是说, 实际使用中 http://127.0.0.1:8270
等价于http://127.0.0.1:8270/RPC2
. 这是否会带来问题取决于远程服务器的实现.如果指定了路径, 哪怕只有一个 /
, 则后面不会再自动追加. 例如,http://127.0.0.1:8270/
和 http://127.0.0.1:8270/my/path
都将原封不动.
上面的最后一个例子展示了如何设置超时时间(timeout). timeout是Remote库的第2个可选参数. 超时时长用于初始连接服务器, 或者中途连接中断的情形. 超时时间的格式是Robot Framework 的 time format ,如 60s
或 2 minutes 10 seconds
.
默认的超时值取决于操作系统和其配置, 一般是几分钟. 注意如果超时时长短于关键字的执行时间, 则关键字会被中断.
注解
Robot Framework 2.8.6版本开始支持timeout参数.Python/Jython 2.5 或 IronPython中timeout不生效.
远程服务器的启停
在导入Remote库之前, 提供关键字的远程服务器必须先启动. 如果服务器在测试执行之前启动, 则可以像上面的例子一样使用普通的 Library 来设置. 此外, 服务器还可以通过其它关键字(例如, Process_ or SSH )来启动, 这种情况下需要使用 库导入关键字, 否则远程库将不可用.
远程服务器如何停止取决于它的实现方式. 典型的服务器支持以下方法:
- 不管使用什么库, 远程服务器应该提供 Stop Remote Server 关键字,这样可以很容易地在测试执行中停止服务.
- 远程服务器应该在XML-RPC接口中提供
stop_remote_server
方法. - 在运行服务器程序的终端(console)按下
Ctrl-C
可以停止服务. - 可以通过终止操作系统的进程(例如,
kill
)来停止服务. - Regardless of the library used, remote servers should provide StopRemote Server keyword that can be easily used by executed tests.
- Remote servers should have stop_remote_server method in theirXML-RPC interface.
- Hitting Ctrl-C on the console where the server is running shouldstop the server.
- The server process can be terminated using tools provided by theoperating system (e.g.
kill
).
注解
Stop Remote Server 关键字或 stop_remote_server 方法都不是必需的.
支持的参数和返回值类型
由于XML-RPC协议并不支持所有可能的对象类型, 所以在Remote库和远程服务器之间传递的值必须要转换为某种兼容的类型. 这种转换适用于关键字的参数传递(Remote库->远程服务器)以及返回值(远程服务器->Remote库).
Remote库和Python的远程服务器遵从下面的规则来处理Python值. 其它远程服务器的处理方式也是类似的.
- 字符串, 数字, 布尔值都无需修改, 直接传递.
- Python
None
转换为空字符串. - 所有的列表, 元组和其它可迭代对象(除了字符串和字典)都以列表(list)来传递, 其中的内容都是递归处理.
- 字典和其它映射(mappings)作为字典传递, 其中的键转换为字符串, 值按支持类型转换, 同样递归处理.
- 返回的字典转换为一种所谓的 可通过点号访问的字典, 这种字典使用 扩展变量语法 来访问键值, 如
${result.key}
. 嵌套的字典${root.child.leaf}
. - 如果字符串包含了XML中不能表示的ASCII字节(例如, 空字节), 则将以 Binary objects 传递, 内部使用的是XML-RPC base64数据类型. 接收到的Binary objects会自动转换回字符串.
- 其它类型转换为字符串.
注解
在Robot Framework 2.8.3版本之前, 只有列表, 元组和字典可以按上述规则处理.其它迭代器和映射对象并不支持. 此外, 支持binary是Robot Framework 2.8.4版本功能, 返回点号返回的字典是Robot Framework 2.9新增功能.
远程协议
本节介绍Remote库和远程服务器之间的通信协议. 这部分信息主要针对的是要创建远程服务的人. 现成的Python和Ruby服务器都可以用作示例.
该远程协议是基于 XML-RPC 实现的, XML-RPC是通过HTTP传递XML来实现的一个简单的远程过程调用(remote procedure call)协议.大部分主流的编程语言(Python, Java, C, Ruby, Perl, Javascript, PHP,…)都内置或者可通过扩展来支持XML-RPC.
必需的方法
一个远程服务器就是一个XML-RPC服务器, 其公共的接口提供了 动态库API 所要求的方法. 其中 get_keyword_names
和 run_keyword
是必须的, get_keyword_arguments
和 get_keyword_documentation
为推荐实现. 注意这些方法名现在还不支持使用驼峰命名法.
实际的关键字是如何实现的和Remote库并无关联. 远程服务器既可以仅充当一个真正测试库的包装器(wrapper), 就像提供的Python和Ruby服务器那样, 也可以自己实现关键字.
远程服务器可以在公共接口中额外提供 stopremote_server
方法, 以便停止服务. 最好还可以将此方法自动暴露为关键字 _Stop Remote Server,以便在测试用例中使用. 允许用户停止服务并不总是合适的, 所以服务器最好还要提供某种方法来控制此功能. 例如, 提供一个方法(并暴露为关键字), 返回 True
或者 False
来标示该服务器是否允许被终止. 这样外部的工具也有办法知道停止服务器是否成功.
提供的Python远程服务器可作为一个实现的参考.
获取远程关键字名称和其它信息
Remote库通过调用 get_keyword_names
方法来从远程服务器上获取其提供的关键字列表. 该方法必须将关键字名称以字符串的列表形式返回.
远程服务器可以, 也应该, 实现 get_keyword_arguments
和 get_keyword_documentation
方法来提供关于关键字更多的信息. 这两个方法都接受关键字的名称作为参数. 关键字的参数必须以字符串的列表返回, 其中格式和 动态库的定义 一样, 而关键字的文档则必须以 字符串 返回.
远程服务器还可以提供 general library documentation , 供文档生成工具 Libdoc_ 使用.
远程关键字的执行
当Remote库想要远程服务器执行某个关键字时, 调用远程服务器的的 run_keyword
方法, 并传入关键字的名字和一系列参数, 还可能有字典表示的 自由命名参数. 基础类型参数可以直接使用, 复杂的类型 被转换为支持的类型.
远程服务器的执行结果必须以字典形式返回, 其中包含的项参见下表. 注意, 其中只有 status
字段是必须的, 其它如果用不上的都可忽略.
Name | Explanation |
---|---|
status | 必填, 执行状态, PASS 或 FAIL . |
output | 可被写入日志文件的输出信息, 必须返回单个字符串, 但是其中可以包含很多内容, 还可以设置 日志级别.INFO First message\nHTML <b>2nd</b>\nWARNAnother message .还可以嵌入 时间戳 , 例如:INFO:1308435758660 Message with timestamp . |
return | 可能的返回值. |
error | 必须是 支持的类型 之一.可能的错误信息. 当执行出错是用到. |
traceback | 可能的 stack trace, 当执行出错时, 以DEBUG级别写入日志. |
continuable | 如果设置为 True , 或者任何在Python中视作 True 的值.则发生的错误视作 可继续的New in Robot Framework 2.8.4. |
fatal | 和 continuable 类似, 表示当前的错误是fatal.New in Robot Framework 2.8.4. |
参数语法
Remote库是一个 动态库API, 因此它和其它动态库一样, 遵从相同的规则, 处理不同的参数语法. 包括必填参数, 默认值, varargs, 以及 命名参数语法.
自由命名参数(**kwargs
)主要也和 其它动态库一样.
首先, get_keyword_arguments
需要返回参数列表的规范, 其中必须包含 **kwargs
, 这点和其它动态库是一样的. 主要的不同在于远程服务器的 run_keyword
方法必须包含一个可选的第3个参数, 用来接收用户指定的kwargs. 为了向后兼容, 这个参数必须设置为可选的(optional), 因为Remote库只在测试数据用到时才会传递kwargs到 run_keyword
方法.
实际上 run_keyword
和下面的Python和Java示例看上去差不多, 差别在于程序语言是怎么处理可选参数的.
- def run_keyword(name, args, kwargs=None):
- # ...
- public Map run_keyword(String name, List args) {
- // ...
- }
- public Map run_keyword(String name, List args, Map kwargs) {
- // ...
- }
注解
Remote library supports **kwargs
starting fromRobot Framework 2.8.3.