文章详情页 您现在的位置是:网站首页>文章详情

关于自动化测试-httprunner

图片丢失 jeeyshe 发表于:2019年6月27日 20:40 分类:【日常笔记 646次阅读

HttpRunner 是一款面向 HTTP(S) 协议的通用测试框架,只需编写维护一份 YAML/JSON 脚本,即可实现自动化测试、性能测试、线上监控、持续集成等多种测试需求。HttpRunner 特点在于,每个测试用例都是一份yaml(json文件),因此项目中可能有一堆yaml文件,最后可以输出一个基于html的测试报告。

项目组织结构:

典型的项目结构有两种,一种为简单结构, 一种为分层结构

(1)简单组织结构

$ tree demo -a
demo
├── .env
├── debugtalk.py
├── reports
├── testcase1.yml
└── testcase2.json

适用于小型项目,测试较少的情况
- YAML/JSON(必须):测试用例文件,存储接口测试相关信息
- debugtalk.py(可选):存储项目中逻辑运算辅助函数 该文件存在时,将作为项目根目录定位标记,其所在目录即被视为项目工程根目录 该文件不存在时,运行测试的所在路径(CWD)将被视为项目工程根目录
- 测试用例文件中的相对路径(例如.csv)均需基于项目工程根目录
- .env(可选):存储项目环境变量,通常用于存储项目敏感信息
- .csv(可选):项目数据文件,用于进行数据驱动
reports:默认生成测试报告的存储文件夹

(2)分层结构 

$ tree demo -a
demo
├── .env
├── api
│   └── user.yml
├── debugtalk.py
├── reports
│   └── 1535713039.html
├── testcases
│   ├── login.yml
│   └── logout.yml
└── testsuites
    └── login_and_logout.yml

适用于大型、复杂项目
- debugtalk.py:该文件所在目录将作为项目工程的根目录,api 文件夹都必须与其放置在相同目录
- api 文件夹:存储接口定义描述
- reports 文件夹:存储 HTML 测试报告
- testcases 文件夹(非必须):存储测试用例,文件夹也可以使用其它名称
- testsuite 文件夹(非必须):测试测试场景,文件夹也可以使用其它名称

测试用例数据结构

testcase_struct.png

测试用例集(testsuite):对应一个文件夹,包含单个或多个测试用例(YAML/JSON)文件
测试用例(testcase):对应一个 YAML/JSON 文件,包含单个或多个测试步骤
测试步骤(teststep):对应 YAML/JSON 文件中的一个 test,描述单次接口测试的全部内容,包括发起接口请求、解析响应结果、校验结果

(一)testcase数据结构

//  这个list相当于一个`testsuite`或`testcase`
[
  {
    "config": {...}
  },
  {
    "test": {...}    // 这个test就是一个`teststep`
  },
  {
    "test": {...}
  }
]

(二)config数据结构

"config": {
    "name": "testcase description",    // `必填`,测试用例的名称,测试报告会以此作为标题
    "parameters": [    // 非必填,全局参数,作用域为整个testcase
        {"user_agent": ["iOS/10.1", "iOS/10.2", "iOS/10.3"]},
        {"app_version": "${P(app_version.csv)}"},
        {"os_platform": "${get_os_platform()}"}
    ],
    "variables": [    // 非必填,全局变量,作用域为整个testcase
        {"user_agent": "iOS/10.3"},
        {"device_sn": "${gen_random_string(15)}"},
        {"os_platform": "ios"}
    ],
    "request": {    // 非必填,请求配置
        "base_url": "http://127.0.0.1:5000",
        "headers": {
            "Content-Type": "application/json",
            "device_sn": "$device_sn"
        }
    },
    "output": [    // 非必填,输出项,会在命令行输出的全局变量或结果
        "token"
    ]
}

(三)teststep数据结构

"test": {
    "name": "get token with $user_agent, $os_platform, $app_version",    // `必填`,测试步骤名称
    "request": {    // `必填`,测试步骤request信息
        "url": "/api/get-token",
        "method": "POST",
        "headers": {
            "app_version": "$app_version",
            "os_platform": "$os_platform",
            "user_agent": "$user_agent"
        },
        "json": {
            "sign": "${get_sign($user_agent, $device_sn, $os_platform, $app_version)}"
        },
        "extract": [    // 从当前请求结果获取参数保存,给下面的测试步骤使用
            {"token": "content.token"}
        ],
        "validate": [    // 对当前测试结果的校验
            {"eq": ["status_code", 200]},
            {"eq": ["headers.Content-Type", "application/json"]},
            {"eq": ["content.success", true]}
        ],
        "setup_hooks": [],
        "teardown_hooks": []
    }
}
  • extrac 参数提取方式
    响应结果为 JSON 结构,可采用.运算符的方式,例如headers.Content-Type、content.success;
    响应结果为 text/html 结构,可采用正则表达式的方式,例如blog-motto\">(.*)

补充说明
  • 全局变量,全局参数作用域为testcase和teststep,teststep可以覆盖testcase

  • 各个teststep之间的变量空间相互独立

  • 不同的teststep之间如果需要传递变量,可使用extract

快速上手

(一)安装

pip install httprunner


要使用最新开发版,则直接去github仓库下载
安装完成之后系统会多出几个命令,记住核心命令:hrun

(二)快速创建项目

hrun --startproject <project_name>

(三)快速创建测试用例

测试用例的编写有两种方式:(1)解析response,然后自己手动编写。(2)使用接口测试工具导出.har文件,再用httprunner的har2case快速生成yaml/json文件。这里介绍第二种方式。例如,chrom浏览器访问任意页面,打开控制台,右键选择保存为har

har2case  xxx.har -2y    // 转换为yaml格式,不加-2y参数则转换为json格式

(四)运行测试

hrun filepath/testcase.yml    # `对单个测试例子运行`
hrun testcases_folder_path    # `运行整个项目`

(五)测试报告

默认会在reports/下保存为<时间戳>.html文件

高级特性

hook机制

hook 机制存在于testcase和teststep两个层面,又分别提供setup_hooks和teardown_hooks, 分别在请求发出之前或者之后调用

  • setup_hooks: 可用于参数准备,加密,对request预处理等。

  • teardown_hooks: 可用于进行处理结果,之后在进行验证,全局参数提取等操作

项目的测试用例结构关系

测试用例结构.png

同时,强调如下几点核心概念:
(1)测试用例(testcase)应该是完整且独立的,每条测试用例应该是都可以独立运行的
(2)测试用例是测试步骤(teststep)的 有序 集合,每一个测试步骤对应一个 API 的请求描述
(3)测试用例集(testsuite)是测试用例的 无序 集合,集合中的测试用例应该都是相互独立,不存在先后依赖关系的;如果确实存在先后依赖关系,那就需要在测试用例中完成依赖的处理
例如:
testcase1 依赖于 testcase2,那么就可以在测试步骤(teststep12)中对 testcase2 进行引用,然后 testcase1 就是完整且可独立运行的;
在 testsuite 中,testcase1 与 testcase2 相互独立,运行顺序就不再有先后依赖关系了。

接口描述和引用

为了更好地对接口描述进行管理,推荐使用独立的文件对接口描述进行存储,即每个文件对应一个接口描述。
接口定义描述的主要内容包括:name、variables、request、base_url、validate 等,形式如下:

name: get headers
base_url: http://httpbin.org
variables:
    expected_status_code: 200
request:
    url: /headers
    method: GET
validate:
    - eq: ["status_code", $expected_status_code]
    - eq: [content.headers.Host, "httpbin.org"]


有了接口的定义描述后,我们编写测试场景时就可以直接引用接口定义了。
在测试步骤(teststep)中,可通过 api 字段引用接口定义,引用方式为对应 API 文件的路径,绝对路径或相对路径均可。推荐使用相对路径,路径基准为项目根目录,即 debugtalk.py 所在的目录路径。

- test:
    name: get token (setup)
    api: api/get_token.yml        # 此处引用接口描述
    variables:
        user_agent: 'iOS/10.3'
        device_sn: $device_sn
        os_platform: 'ios'
        app_version: '2.8.6'
    extract:
        - session_token: content.token
    validate:
        - eq: ["status_code", 200]
        - len_eq: ["content.token", 16]


参数化接口描述:

  • 描述:用def字段给他起了个名

- api:
    def: api_v1_Find_Nodes($cluster_name, $ip, $port, $username, $password, $pub_key)
    request:
        url: /qdata/cluster/find/nodes
        method: POST
        headers:
            Content-Type: application/json
            x-access-token: ${get_token_for_env()}
        json:
            cluster_name: $cluster_name
            ip: $ip
            port: $port
            username: $username
            password: $password
            pub_key: $pub_key

     validate:
        - eq: [headers.Content-Type, "application/json"]
        - eq: ["status_code", 200] # HTTP标准返回码
        - eq: ["content.error_code", 0]    # 自定义的返回码


  • 引用: 直接用的描述时def名字而不是文件名

- test:
    name: Find Nodes
    api: api_v1_Find_Nodes($cluster_name, $ip, $port, $username, $password, $pub_key)
    variables:
        - rac_info:
    teardown_hooks:
        - ${check_ipmi_auth($response)}
    extract:
        - nodes: content.data.nodes

测试用例的引用

在测试步骤(teststep)中,可通过 testcase 字段引用其它测试用例,引用方式为对应测试用例文件的路径,绝对路径或相对路径均可。推荐使用相对路径,路径基准为项目根目录,即 debugtalk.py 所在的目录路径。

- test:
    name: setup and reset all (override) for $device_sn.
    testcase: testcases/setup.yml
    output:
        - session_token


自动化测试的12个认识误区

以下引用自网络,但是我找不见原文了,作者看见请联系我,我坚决尊重你的劳动成果!

1、自动化的软件测试与手工的软件测试过程一样

自动化测试所需要的技巧与手工测试所需要的技巧是不一样的。 
通常,你的项目经理会被那些测试工具销售们迷惑,认为自动化的软件测试就是简单地按一个录制的按钮,产生测试脚本。而事实上并没有那么简单。 
区分自动化测试所需要的技巧与手工测试所需要的技巧是非常重要的。最重要的是,自动化测试工程师需要掌握软件开发技巧,没有接受任何培训的手工测试人员,或者没有编程背景的手工测试人员,在实施自动化测试时会碰到很多困难。

2、自动化测试一定会马上大量减少测试人员数量

自动化测试不会马上大量减少测试人员数量。因为开展自动化测试初期需要投入一定的人力进行自动化测试脚本开发,并逐渐将自动化测试脚本用于日常的测试中,逐步减少手工测试人员从事重复劳动的时间和人数。为了缩短自动化测试脚本的开发时间,可以考虑将自动化测试脚本的开发工作借助外包的力量来早日实现大规模的自动化测试。

3、测试自动化就是录制和回放

仅仅录制得到的不是有效的自动化脚本。 
很多项目经理仍然把测试自动化等同于使用录制回放工具。而事实上,录制得到的脚本通常是不可重用的脚本,脚本中充满了硬编码的值,这些值应该被参数化,否则脚本仅仅适用于一个测试情况,脚本还应该加入条件判断、循环等结构,以便增强测试脚本的灵活性。

4、自动化测试找不到bug

自动化测试不直接找bug,而是通过解放有经验的测试工程师的生产力,让其从重复的回归测试中解放出来,从事新的测试方法和测试手段的研究。通过自动化测试解放出测试人员的时间和精力来间接地找到更多、更深层次的新bug,将产品质量再提高一个档次。

5、自动化测试工具是“万能”的

很多人一听到自动化测试,就认为自动化测试工具可以完成一切测试工作,从测试计划到测试执行再到测试结果分析,都不需要任何人工干预。显然,这是一种理想状态,现实中还没有哪个测试工具有这个能力,并且将来也不会有。在现实中有关的测试设计、测试案例,以及一些关键的测试任务还是需要人工参与的,即自动化测试是对手工测试的辅助和补充,它永远也不可能完全取代手工测试。

6、自动化测试工具容易使用

对于这一点,很多测试工程师有同样的错误观点,认为测试工具可以简单地通过捕获(录制)客户端操作生成脚本,且脚本不加编辑就可用于回放使用。事实上,自动化测试不是那么简单的,捕获的操作是否正确,以及脚本编辑是否合理都会影响测试结果。因此,自动化测试需要更多的技能,也需要更多的培训。

7、自动化能提供百分百的测试覆盖率

并非所有内容都可以被自动化地测试到。不可能覆盖所有可能的输入,所有可能的组合和路径。 
自动化测试可以增加测试的广度和深度,但是仍然无法达到100%的测试覆盖率,因为没有足够的时间或资源。

8、忘记了测试的最终目标:找到BUG

在自动化测试中,同样要注意把边界值分析、等价类分析、基于风险的测试方法、挑选最合适的测试用例等技术应用起来。 
通常在自动化测试过程中,我们都忙着搭建自动化框架和编写测试脚本,但是我们往往忘记了测试的本来目的:找bug。 
项目经理可能雇佣了最好的自动化开发人员来搭建框架,使用了最新最好的自动化开发技术,创建了成千上万的自动化测试脚本。但是如果BUG仍然被遗漏了,那些本该被自动化测试脚本捕捉到的BUG,结果没有被捕捉到,那么你的自动化测试仍然会被认为是失败的。

9、所有测试用例都可以自动化

不是所有的测试用例和测试步骤都可以转化为自动化测试。在自动化测试投入较多的行业,领先企业的自动化测试率有的能达到80%左右,但仍有20%左右的测试用例需要手工来进行。在国外,通常从开发第一版测试用例时,就同步进行自动化测试脚本的开发,所以自动化测试率普遍比中国企业高。

10、只有性能测试才需要自动化

自动化测试不光进行性能测试,更被大量应用于功能测试验证,在国外超过半数的自动化测试脚本都是用于功能验证测试的。

11、测试工具可适用于所有的测试

每种自动化测试工具都有它的应用范围和可用对象,所以不能认为一种自动化测试工具能够满足所有测试的需求。针对不同的测试目的和测试对象,应该选择合适的测试工具来对它进行测试。在很多情况下,需要利用多种测试工具或者开发自动化测试框架才能达到自动化测试的目的。商业和开源的测试工具能够用来进行自动化测试,但是我们需要根据自身产品的特点,开发自动化测试框架,在框架中提供常用的测试用例,加快测试速度,达到测试用例复用,这是今后测试自动化发展的道路。

12、自动化测试能发现大量新缺陷

发现更多的新缺陷应该是手工测试的主要目的,不能期望自动化测试去发现更多新缺陷。事实上,自动化测试主要用于发现原来的缺陷。自动化测试用于回归测试,而大量的新业务测试更多地还是依赖手工测试。 
除了以上列举的常见误区外,还有其他不同的认识误区。自动化测试认识误区的产生,归根到底最本质的原因是由于对自动化测试不现实的期望,也就是期望过高造成的。 
如果没有建立一个正确的软件测试自动化的观念,认为测试自动化可以完全代替手工测试,或者认为测试自动化可以发现大量新缺陷,或者不愿在初期投入比较大的开支等,则自动化测试一定会让我们大失所望。



版权声明 本文属于本站  原创作品,文章版权归本站及作者所有,请尊重作者的创作成果,转载、引用自觉附上本文永久地址: https://www.lujianxin.com/x/art/yhczlf2sbpoe

文章评论区

作者名片

图片丢失
  • 作者昵称:jeeyshe
  • 原创文章:15篇
  • 转载文章:3篇
  • 加入本站:155天

站点信息

  • 运行天数:156天
  • 累计访问:17162人次
  • 今日访问:111人次
  • 原创文章:18篇
  • 转载文章:4篇
  • 微信公众号:第一时间获取更新信息