HttpRunner2.X 版本和 3.X 版本的区别到底有哪些?(吐血总结!)
前言
HttpRunner 的版本截止到目前已经更新到3.1.5了,那么很多初学者都有这样的疑问:
HttpRunner2.X 版本和 3.X 版本的区别到底有哪些?
到底要不要学2.X 版本,还是直接入手3.X 版本呢?
设计理念上的差异
HttpRunner 每一次大版本的更新,都会有设计理念上的大的改变,可以从官方文档上了解到.
HttpRunner 2.X
HttpRunner 是一款面向 HTTP(S) 协议的通用测试框架,只需编写维护一份 YAML/JSON 脚本,即可实现自动化测试、性能测试、线上监控、持续集成等多种测试需求。
设计理念
- 充分复用优秀的开源项目,不追求重复造轮子,而是将强大的轮子组装成战车
- 遵循 约定大于配置 的准则,在框架功能中融入自动化测试最佳工程实践
- 追求投入产出比,一份投入即可实现多种测试需求
从 2.0 版本开始,HttpRunner 采用了分层机制,同时,强调如下几点核心概念:
- 测试用例(testcase)应该是完整且独立的,每条测试用例应该是都可以独立运行的
- 测试用例是测试步骤(teststep)的 有序 集合,每一个测试步骤对应一个 API 的请求描述
- 测试用例集(testsuite)是测试用例的 无序 集合,集合中的测试用例应该都是相互独立,不存在先后依赖关系的;如果确实存在先后依赖关系,那就需要在测试用例中完成依赖的处理
2.X 版本的亮点功能在于用例的分层机制,重复的接口请求可以写到单独API层,用例去调用API,层级结构非常清晰,每个层级做好自己的事情。
HttpRunner 3.X
HttpRunner v3.x 支持3种用例格式:pytest、YAML和JSON。
设计理念
- 约定优于配置
- 投入产出比很重要
- 拥抱开源,依赖requests ,pytest ,pydantic ,allure 和 locust
pytest、YAML和JSON格式的测试用例完全等价,包含的信息内容也完全相同。
- 对于有python基础的,建议以pytest格式而不是以前的YAML / JSON格式编写和维护测试用例。
- 对于新手来说,推荐使用 JSON 格式,虽然描述形式上稍显累赘,但是不容易出错(大多编辑器都具有 JSON 格式的检测功能);
同时,HttpRunner 也内置了 JSON 格式正确性检测和样式美化功能,详情可查看《Validate & Prettify》 。 - 对于熟悉 YAML 格式的人来说,编写维护 YAML 格式的测试用例会更简洁,但前提是要保证 YAML 格式没有语法错误。
HttpRunner v3.x开始,HttpRunner 作者建议大家回到代码上,鼓励大家去写python代码了(可能认为代码还是很重要),用pycharm等编辑器可以自动补齐语法,编写效率更高。
对于有一些代码基础的同学来说,还是很高效的,毕竟还是有很多小伙伴不习惯与yaml格式,总是在语法上犯错,导致编写脚本效率很低。
对比差异
2.x 版本和3.x版本功能上对比差异
功能点 | HttpRunner 2.X | HttpRunner 3.X |
---|---|---|
python用例框架 | unittest | pytest(v5.4.3) |
录制.har | har2case支持 | har2case支持 |
用例文件格式 | YAML/JSON | YAML/JSON/Pytest |
HTTP(S)请求库 | requests | requests |
用例分层 | 三层:API/TestCase/TestSuite | 弱化了API层,去掉分层机制 |
参数化parameters | 2.x版本在TestSuites层实现,TestCase不支持 | 3.x版本TestCase中实现 |
extract提取变量 | 支持content.x.x格式/re正则/jsonpath | 只支持jmespath表达式 |
返回html格式 | re正则提取 | 不支持re正则提取 |
文件上传 | upload关键字支持 | upload关键字支持 |
validate校验 | comparator 校验一样 | comparator 校验一样 |
comparator | 支持debugytalk.py 自定义 | 不支持自定义 |
hook机制 | 支持 | 支持 |
debugtalk.py辅助函数 | 支持 | 支持 |
测试报告 | 自带html报告 | 不自带报告了 |
extent report | 支持 | 不支持 |
Allure | 不支持 | 支持 |
Locust | 支持 | 支持 |
CLI命令行运行 | 支持 | 支持 |
学习难度 | 低难度 | 偏中高级 |
稳定性 | 高 | 偏中 |
作者版本维护 | 不维护 | 继续维护 |
底层框架区别
HttpRunner 2.X 是基于 Python 的 Unittest 框架运行用例,
HttpRunner 3.X 是基于 Python 的 Pytest 框架运行用例,支持了 Pytest 框架,运行用例性能会得到很大的提升。
既然支持了 Pytest,意味着 Pytest 的一些插件都可以用了,比如 Allure 插件,也可以在 conftest 中写一些钩子函数,自己开发插件了,扩展性得到很大的提升!
用例格式区别
HttpRunner 2.X 支持yaml 和 json格式,json和yaml是可以互相转换,以yaml为例
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
config:
name: logincase
variables: {}
teststeps:
-
name: login case1
request:
url: http://127.0.0.1:8000/api/v1/login/
method: POST
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
json:
username: test
password: 123456
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, application/json]
- eq: [content.msg, login success!]
- eq: [content.code, 0]
HttpRunner 3.x 除了支持yaml和json格式,还可以支持pytest格式用例。
yaml格式跟2.x版本是一样的,可以直接运行上面的yaml格式,会生成一个pytest格式用例
# NOTE: Generated By HttpRunner v3.1.5
# FROM: testcase\login.yml
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
class TestCaseLogin(HttpRunner):
config = Config("logincase")
teststeps = [
Step(
RunRequest("login case1")
.post("http://127.0.0.1:8000/api/v1/login")
.with_json({"username": "test", "password": "123456"})
.validate()
.assert_equal("status_code", 200)
.assert_equal("body.msg", "login success!")
.assert_equal("body.code", 0)
.assert_equal("body.username", "test")
.assert_length_equal("body.token", 40)
),
]
if __name__ == "__main__":
TestCaseLogin().test_start()
extract 提取与validate校验
HttpRunner 3.x 只支持 jmespath 提取接口返回的json数据格式,jmespath是类似于jsonpath的提取表达式
jmespath 提取示例,访问/api/test/demo接口,接口返回如下
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
{
"code":0,
"msg":"成功success!",
"data":[
{
"age":20,
"create_time":"2019-09-15",
"id":1,
"mail":"283340479@qq.com",
"name":"yoyo",
"sex":"M"
},
{
"age":21,
"create_time":"2019-09-16",
"id":2,
"mail":"123445@qq.com",
"name":"yoyo111",
"sex":"M"
}
]
}
需求:
- 1.提取code值,校验结果为:0
- 2.msg值,校验结果:成功success!
- 3.提取data数据,校验结果长度是:2
- 4.提取data数据中第一条数据,校验name的值:yoyo
- 5.提取data数据中name的值为yoyo的邮箱,并校验结果是:283340479@qq.com
- 6.提取data数据组中,年龄大于20的结果,并校验结果的数量是:1
httprunner3.x 对应的 py 代码
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
class TestCaseTestDemo(HttpRunner):
config = Config("test demo").base_url("http://127.0.0.1:8000")
teststeps = [
Step(
RunRequest("step login")
.get("/api/test/demo")
.validate()
.assert_equal("status_code", 200)
.assert_equal("body.code", 0)
.assert_equal("body.msg", "成功success!")
.assert_equal("body.length(data)", 2)
.assert_equal("body.data[0].name", "yoyo")
.assert_equal("body.data[?name=='yoyo'].mail", ["283340479@qq.com"])
.assert_equal("body.data[?name=='yoyo'].mail|[0]", "283340479@qq.com")
.assert_equal("body.length(data[?age>`20`])", 1)
),
]
if __name__ == "__main__":
TestCaseTestDemo().test_start()
不得不说jmespath在提取json方面是非常强大的,httprunner2.x是可以支持jsonpath表达式的
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
extract:
code: $.code
validate:
- eq: [status_code, 200]
- eq: [headers.Content-Type, application/json]
- eq: [$.code, 0]
- eq: ["$code", 0]
但是2.5.7版本有个小bug,一直没修复,详情参考https://www.cnblogs.com/yoyoketang/p/14884606.html
返回html提取
httprunner3.x是不支持html解析的,可以看到源码里面此功能还没开发完善.
class StepRequestExtraction(object):
def __init__(self, step_context: TStep):
self.__step_context = step_context
def with_jmespath(self, jmes_path: Text, var_name: Text) -> "StepRequestExtraction":
self.__step_context.extract[var_name] = jmes_path
return self
# def with_regex(self):
# # TODO: extract response html with regex
# pass
#
# def with_jsonpath(self):
# # TODO: extract response json with jsonpath
# pass
有些接口返回的并不是json格式,如果返回html格式, 那就没法提取了,httprunner2.x 可以支持正则表达式提取,这点还是很好的
config:
name: logincase
variables: {}
teststeps:
-
name: test demo case1
request:
url: https://www.cnblogs.com/yoyoketang/
method: GET
headers:
User-Agent: Fiddler
Content-Type: application/json
verify: false
extract:
title: '<title>(.+?)</title>'
validate:
- eq: [status_code, 200]
- eq: ['<title>(.+?)</title>', 上海-悠悠 - 博客园]
comparator 校验方式
httprunner2.x 和 httprunner3.x 支持的 comparator 校验方式是一样的
comparator | 缩写 | 功能 |
---|---|---|
equal | "eq", "equals", "equal" | 相等 |
less_than | "lt", "less_than" | 小于 |
less_or_equals | "le", "less_or_equals" | 小于或等于 |
greater_than | "gt", "greater_than" | 大于 |
greater_or_equals | "ge", "greater_or_equals" | 大于或等于 |
not_equal | "ne", "not_equal" | 不等于 |
string_equals | "str_eq", "string_equals" | 转字符串相等 |
length_equal | "len_eq", "length_equal" | 长度相等 |
length_greater_than | "len_gt","length_greater_than" | 长度大于 |
length_greater_or_equals | "len_ge","length_greater_or_equals" | 长度大于或等于 |
length_less_than | "len_lt", "length_less_than" | 长度小于 |
length_less_or_equals | ""len_le", "length_less_or_equals" | 长度小于或等于 |
contains | check_value 包含 expect_value | |
contained_by | expect_value 包含check_value | |
type_match | type类型匹配 | |
regex_match | 正则匹配re.match(expect_value, check_value) | |
startswith | 字符串以xx开头 | |
endswith | 字符串以xx结尾 |
yaml 中可以写2种格式校验
- {"comparator_name": [check_value, expect_value]}
- {"check": check_value, "comparator": comparator_name, "expect": expect_value}
httprunner3.x 并不支持自己定义的校验方式,httprunner2.x可以支持自定义校验,如
# debugtalk.py
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
# 获取data数据,断言每个数据的age字段大于等于expect_age
def all_age_great(data, expect_age):
""" all age great then expect_age
"""
for info in data:
assert info.get('age') >= expect_age
于是 yaml 用例可以这样写
# 作者-上海悠悠 QQ交流群:717225969
# blog地址 https://www.cnblogs.com/yoyoketang/
config:
name: test_demo
base_url: http://127.0.0.1:8000
variables: {}
teststeps:
-
name: test_demo case1
request:
url: /api/test/demo
method: GET
headers:
Content-Type: application/json
User-Agent: python-requests/2.18.4
validate:
- check: content.data
comparator: all_age_great
expect: 18
- all_age_great: [content.data, 18]
测试报告差异
httprunner3.x 运行用例是pytest框架,也就是意味着可以支持强大的Allure报告了
httprunner 2.x 运行用例是unittest框架,会自带一个简单的测试报告
也可以支持自己扩展一个extent report报告模板
版本稳定性与学习成本
稳定性:
httprunner2.x 版本更新到2.5.7了,虽然有一些小BUG,整体上还是很稳定的,目前也很多公司在用了,已经有看得到的成果,稳定性较强!
缺点是作者不继续维护2.x版本了
httprunner3.x 版本更新到3.1.5了,最近的一次更新是在2021年6月27,距离上一次更新差不多1年了,版本改动也很小,更新的频率放慢了很多。
学习成本:
httprunner2.x 支持yaml/json格式的用例,意味着我们只需学一个yaml(或json)文件就能写接口自动化了,初学者可以很快的掌握。
httprunner3.x 支持yaml/json/pytest格式的用例,多了一个pytest格式的用例,那么意味着学习成本会增多了,初学者掌握的难度较大,适合之前就已经有学过pytest的同学。
还有其它细节上的区别,就不一一总结了,如果有同学能补充的可以留言!
网易云课程
httprunner 2.x实战教程网易云课程地址
httprunner 3.x实战教程网易云课程地址