HttpRunner2.X 版本和 3.X 版本的区别到底有哪些?(吐血总结!)

Posted 上海-悠悠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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.XHttpRunner 3.X
python用例框架unittestpytest(v5.4.3)
录制.harhar2case支持har2case支持
用例文件格式YAML/JSONYAML/JSON/Pytest
HTTP(S)请求库requestsrequests
用例分层三层:API/TestCase/TestSuite弱化了API层,去掉分层机制
参数化parameters2.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”长度小于或等于
containscheck_value 包含 expect_value
contained_byexpect_value 包含check_value
type_matchtype类型匹配
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 2.x实战教程点我 ->立即报名

httprunner 3.x实战教程网易云课程地址


httprunner 3.x实战教程点我 ->立即报名

以上是关于HttpRunner2.X 版本和 3.X 版本的区别到底有哪些?(吐血总结!)的主要内容,如果未能解决你的问题,请参考以下文章

01-Httprunner-简介安装及基本使用

httprunner 3.X学习

优化httprunner2.x测试报告

HttpRunner2.X开源接口测试框架学习:yaml格式测试用例编写

httprunner 2.x学习4-测试用例分层

httprunner 2.x学习18 - 报告validate显示LazyString($msg)问题解决