使用 Python 开发 Robot Framework 测试库
测试库的核心作用
Robot Framework 本身不直接提供测试功能,其实际的自动化能力依赖于外部测试库。这些库通过关键字驱动的方式与测试用例交互,实现具体的操作逻辑。
支持的开发语言
- 框架基于 Python 实现,因此原生支持使用 Python 编写扩展库。
- 若运行在 Jython(Python 运行于 JVM 上)环境中,则可用 Java 实现测试库。
- 还可通过 C 语言结合 Python 的 C API 来构建高性能或底层操作的库。
三种测试库接口类型
静态接口
最常见且易于理解的形式。将类或模块中的方法直接映射为关键字,方法名决定关键字名称,参数一一对应。执行时自动识别并调用。
动态接口
允许在运行时动态确定支持的关键字。需实现两个核心方法:get_keyword_names 返回所有可用关键字名列表,run_keyword 负责执行指定关键字。适用于需要按配置或环境加载不同行为的场景。
混合接口
结合静态和动态特性。除具备静态方法外,额外实现 get_keyword_names 方法以显式声明当前类暴露哪些关键字。其余调用机制与静态库一致,适合大型库中只公开部分功能的情况。
定义测试库的基本结构
命名规则
测试库文件以 .py 结尾,推荐类名与文件名相同。当两者一致时,在 Robot 中导入可省略模块名;否则必须显式指定"模块.类"全路径。若名称过长,可通过 WITH NAME 设置别名简化引用。
构造函数传参
仅类形式的库支持初始化参数传递。模块无法接收外部参数。构造器可包含默认值、可变参数等 Python 标准特性,便于灵活配置实例行为。参数可通过变量从测试数据中传入。
作用域控制
通过类属性 ROBOT_LIBRARY_SCOPE 控制实例生命周期:
- TEST CASE:每个测试用例创建新实例(默认)。
- TEST SUITE:每个测试套件共享一个实例。
- GLOBAL:全局唯一实例,跨所有套件复用。
版本声明
通过 ROBOT_LIBRARY_VERSION 属性设置库版本号。若未定义,则尝试读取 __version__ 属性作为替代。这两个属性都应定义为类或模块级常量。
示例:基础库结构
class CounterLibrary:
ROBOT_LIBRARY_SCOPE = 'TEST SUITE'
__version__ = '1.0'
def __init__(self):
self._count = 0
def increment(self):
self._count += 1
print(f"Current count: {self._count}")
def reset_counter(self):
self._count = 0
关键字定义与参数处理
关键字命名匹配规则
Robot 框架对关键字名称不区分大小写,并忽略空格和下划线差异。例如,方法名 loginUser、login_user 或 Login User 在测试中均可匹配。
固定参数关键字
方法参数数量即为关键字所需参数数。调用时必须提供正确个数的参数。
默认参数支持
可在方法定义中使用默认值参数,使部分参数可选:
def create_user(self, username, role='guest'):
print(f"Creating user {username} with role {role}")
可变参数支持
利用 Python 的 *args 语法接收任意数量的位置参数:
def log_messages(self, *msgs):
for msg in msgs:
print(f"[LOG] {msg}")
def connect(self, host, port=80, *aliases):
print(f"Connecting to {host}:{port}, aliases={list(aliases)}")
参数类型转换
所有传入参数最初为字符串类型。如需其他类型,应在方法内部进行显式转换:
def connect_to_server(self, address, port=8080):
port = int(port) # 字符串转整型
print(f"Connecting to {address}:{port}")
与框架通信机制
状态反馈
方法正常返回表示关键字成功(PASS),抛出异常则标记为失败(FAIL)。异常信息会显示在日志和报告中。堆栈跟踪默认隐藏,可通过设置日志级别为 DEBUG 查看。
终止测试运行
在异常对象上添加属性 ROBOT_EXIT_ON_FAILURE = True,可使整个测试流程在该错误后立即停止。
继续执行失败用例
设置异常的 ROBOT_CONTINUE_ON_FAILURE = True 属性,即使当前关键字失败,后续步骤仍将继续执行。
日志输出控制
标准输出内容默认记录为 INFO 级别日志。可通过前缀指定日志级别:
*TRACE*:追踪信息*DEBUG*:调试信息*INFO*:普通信息(默认)*WARN*:警告信息,单独归类显示*HTML*:支持 HTML 格式的富文本输出
警告信息用途
用于提示非致命但需关注的问题,例如配置不推荐、性能瓶颈等,帮助用户优化使用方式。
富文本日志输出
使用 *HTML* 前缀可在日志中嵌入格式化内容,如加粗、链接、图片等:
print("*HTML* Login success: <a href='/logs'>View details</a>")
print("*HTML* <img src='screenshot.png' width='300'/>")
返回值处理
通过 return 语句返回结果,供测试数据中的变量捕获:
- 单个值赋给标量变量(如 ${result})
- 多个值可返回元组或列表,解包至多个变量或存入列表变量
def get_user_info(self):
return "alice", "admin"
def fetch_items(self):
return ["item1", "item2", "item3"]
完整示例:多功能测试库
class UtilityLibrary:
ROBOT_LIBRARY_SCOPE = 'GLOBAL'
ROBOT_LIBRARY_VERSION = '2.1'
def __init__(self):
pass
def show_logs(self):
print("This is an info message.")
print("*WARN* Configuration outdated.")
print("*DEBUG* Internal state checked.")
print("*HTML* Visit <a href='https://example.com'>website</a>")
def calculate_sum(self, *numbers):
total = sum(int(n) for n in numbers)
return total
def divide(self, a, b):
try:
result = float(a) / float(b)
return round(result, 2)
except ZeroDivisionError as e:
e.ROBOT_CONTINUE_ON_FAILURE = True
raise e