在 HttpRunner 中,测试用例组织主要基于三个概念:
测试用例集(testsuite):对应一个文件夹,包含单个或多个测试用例(YAML/JSON)文件。
测试用例(testcase):对应一个 YAML/JSON 文件,包含单个或多个测试步骤。
测试步骤(teststep):对应 YAML/JSON 文件中的一个 test,描述单次接口测试的全部内容,包括发起接口请求、解析响应结果、校验结果等。
具体一点:
config:作为整个测试用例的全局配置项。
test:对应单个测试步骤(teststep),测试用例存在顺序关系,运行时将从前往后依次运行各个测试步骤。
1、创建测试用例
在config 模块设置全局配置,一般为用例名称设置、基础url设置和全局参数设置。
2、用例中的API调用和参数传递
在测试用例内部,HttpRunner 划分了两层变量空间作用域(context)。
config:作为整个测试用例的全局配置项,作用域为整个测试用例;
test:测试步骤的变量空间(context)会继承或覆盖 config 中定义的内容;
若某变量在 config 中定义了,在某 test 中没有定义,则该 test 会继承该变量
若某变量在 config 和某 test 中都定义了,则该 test 中使用自己定义的变量值
各个测试步骤(test)的变量空间相互独立,互不影响;
如需在多个测试步骤(test)中传递参数值,则需要使用 extract 关键字,并且只能从前往后传递。
extract:
支持多种提取方式:
响应结果为 JSON 结构,可采用.运算符的方式,例如headers.Content-Type、content.success;
响应结果为 text/html 结构,可采用正则表达式的方式,例如blog-motto">(.*)
API调用成功后,在validata中可以对response信息做断言校验。
validate:
支持两种格式:
{“comparator_name”: [check_item, expect_value]}
{“check”: check_item, “comparator”: comparator_name, “expect”: expect_value}
在yaml格式文件中,从response提取返回值也非常简便。可像extract提取参数那样,对返回值进行断言对比。
测试用例中可以引用其他测试用例,注意api换成testcase就可以。
示例如下:
config:
name: 新建用户
base_url: ${ENV(BASE_URL)}
teststeps:
- testcases:
name: 000 登录cmc成功
testcase: testcases/cmc/WpcTest/cmc_login.yml
- name: 001 添加用户成功
api: api/cmc/System_Manage/user_manage/cmc_user_add.yml
variables:
userId: "wpc02"
account: "wpc02"
name: "wpc02"
password: "LD9KcSQ1OOhzugl61qliMQ=="
sex: 'false'
phone: "010-1234567"
mobile: "18262****0"
email: "wpc***@qq.com"
company: "test"
remark: "this is a test"
validate:
- eq: [status_code, 200]
- eq: [content.success, true]
- eq: [content.message, 添加管理员成功]
3、测试用例设计
测试用例调用API实现具体功能,最好是参考前端页面操作时的API调用顺序,最大程度的模仿用户调用实际逻辑。
这一点,可以参考浏览器网络窗口的API调用顺序。
根据httprunner测试用例分层模型,测试用例之间应当是相互独立的,及执行一条用例不会影响其他用例的功能。
测试用例经验总结:
1、围绕业务逻辑,按照前端API调用顺序编写测试用例
2、保留最精简的功能实现流程,不做多余的API调用
3、创建的数据在用例执行结束要自动删除,避免影响下次执行
4、用例之间相互独立
4、测试集合
当测试用例数量比较多以后,为了方便管理和实现批量运行,通常需要使用测试用例集来对测试用例进行组织。
测试用例(testcase)应该是完整且独立的,每条测试用例应该是都可以独立运行的。
测试用例是测试步骤(teststep)的 有序 集合,每一个测试步骤对应一个 API 的请求描述。
测试用例集(testsuite)是测试用例的 无序 集合,集合中的测试用例应该都是相互独立,不存在先后依赖关系的;如果确实存在先后依赖关系,那就需要在测试用例中完成依赖的处理
每个测试用例集文件中,第一层级存在两类字段:
config: 测试用例集的总体配置参数
testcases: 值为字典结构(无序),key 为测试用例的名称,value 为测试用例的内容;在引用测试用例时也可以指定 variables,实现对引用测试用例中 variables 的覆盖。
参数化场景(parameters)
对于testcases或testsuite中实现的参数化场景,可通过 parameters 实现,描述形式如下所示。
config:
name: create users with parameters
variables:
device_sn: ${gen_random_string(15)}
base_url: "http://127.0.0.1:5000"
testcases:
create user $uid and check result for $device_sn.:
testcase: testcases/create_user.yml
variables:
uid: 1000
device_sn: TESTSUITE_XXX
parameters:
uid: [101, 102, 103]
device_sn: [TESTSUITE_X1, TESTSUITE_X2]
参数化后,parameters 中的变量将采用笛卡尔积组合形成参数列表,依次覆盖 variables 中的参数,驱动测试用例的运行。
csv文件驱动的参数化示例如下:
config:
name: 批量创建用户
base_url: ${ENV(BASE_URL)}
testcases:
- name: 001 创建用户
testcase: testcases/cmc/SystemManage/userManage/cmc_create_user.yml
parameters:
userId-account-name-password-sex-phone-mobile-email-company-remark: ${P(data/userinfo.csv)}
一点小建议:
在开发自动化测试工程之前,一定要约定好API、用例和测试合集的开发规范,变量的命名规则等。不守规矩的人写出来的用例可读性也很差,复用起来也比较麻烦,别问我怎么知道,说多了都是泪。
正文之外的补充:
在实际项目工作中发现,httprunner返回的部分空值参数显示为None,而我们的预期结果则是null。不知道这是不是httprunner的bug,目前我们通过修改httprunner代码来解决这一问题,具体步骤如下。
1、编辑parser.py
修改544行代码(httprunner升级后,代码位置可能有变动,但语句不变,修改为下图中示例)
if var_value is None:
args.append('null')
else:
args.append(var_value)