httprunner实操

httprunner使用第二弹

一、内部变量解析

  • 每个testcase httprunner 的子类
  • 必须有两个类的属性:cofing和teststeps。
  • 单个teststeps列表中单个Step内部通过链式调用(RunRequest().get().with_params().with_header().with_cookies().validate().assert_equal())
  • config:配置测试用例设置,包括url、验证、变量、导出。
  • teststeps:teststeps列表(list[Step]),每个步骤对应一个API请求,也可以调用另一个testcase。此外,还支持variables/extract/validate/hooks机制来创建极其复杂的测试场景。
  • 链调用:可以看到一个case的请求,经过了各个环节的调用,这也是httprunner3.X版本一大亮点。

二、测试用例-config

  • name(必填)
    • 用例名称,将显示再执行日志和测试报告中
  • base_url(选填)
    • 比如你的这套测试用例在测试环境和预发布环境都要使用,那么久可以把基础地址(比如:http://172.16.1.100:8083),设置进去。在后面的teststep中,只需要写上接口的相对路径就好了(比如/get)。这样,切换运行环境,只用修改base_url即可。

image

  • variables(选填)

    • 变量,这里可以存放一些公共的变量,可以在测试用例里引用。(比如我们接口中有个传参是不变的,比如用户名username,而且后面的每个Step都会用到这个传参,那么username就可以放在config的公共变量里)
    • 注意:Step里的变量优先级比config里的变量要高,如果有两个同名的变量,那么引用的时候,是有限引用步骤里的变量。
  • verify(选填)

    • 用来决定是否验证服务器TLS证书的开关。通常设置为False,当请求https请求时,就会跳过验证。
    • 如果你运行时发现抛错SSLError,可以检查下是不是verify没传,或者设置了True。
  • export(选填)

    • 导出的变量,主要用于Step之间参数的传递。

    image

    • 在config中配置export‘foo3’这个变量。
    • 在第一个Step中,.extract() 提取了"body.args.foo2"给变量“foo3”。
    • 在第二个Step中,引用变量"foo3"。

三、测试用例-teststeps-RunRequest

  • 测试用用例分层:

    • 一个testcasse里(就是一个pytest格式的python文件)可以有一个或者多个测试步骤,就是teststeps[]列表里的Step。(可以理解为:每一个Step就可以类比成pytest框架下的def test_xxx()的用例函数)。在Step里通常会请求API完成测试,也可以调用其它测试用例来完成更多的请求。
    • 测试用例(testcase)应该时完整且独立的,每条测试用例应该时可以独立运行的
    • 测试用例是测试步骤(teststep)的有序集合
    • 测试用力集(testsuite)是测试用例的无序集合,集合中的测试用例应该互相独立,不存在先后依赖关系;如果确实存在先后依赖关系,那就需要在测试用例中完成依赖的处理
  • teststeps-RunRequest

    • RunRequest的作用就是在测试步骤中请求API,并且可以对API的响应结果进行提取、断言。
    • RunRequest(name)

    • RunRequest(测试步骤1)。RunRequest的参数名用于指定teststep名称,它将显示在执行日志和测试报告中。

    • with_variables
    • 用于存放变量,但是这是Step步骤里的变量,不同的Step的变量是互相独立的。所以对于多个Step都要使用的变量,我们可以放到congfig的变量中去。
    • 如果config和Step里有重名的变量,那么当你引用这个变量的时候,Step变量会覆盖config变量。
    • method(url)
    • 这里就是指定API的方法了,常用的get、post等等。
    • 如果在config里设置了基础url,那么步骤里的url就只能设置相对路径了。
    • with_params
    • 测接口不都得要传参么,对于params类型的传参,就放这就行了,key-value键值对的形式。
    • with_headers
    • 有header要带上的就放这里。
    • with_cookies
    • 需要带cookie的,可以用.with_cookies方法。
    • with_data
    • 对于body类型的传参,可以用.with_data。
    • with_json
    • 如果是json类型的body请求体,可以用.with_json。
    • extract
    • 做提取操作,使用.with_jmespath(jmes_path: Text, var_name: Text)。
    • 这里是采用了JMESPath语言,JMESPath是JSON的查询语言,可以便捷的提取json中你需要的元素。
    • 第一个参数是你的目标元素的jmespath表达式,第二个元素则是用来存放这个元素的变量,供有需要的引用。
    • validate
    • 验证接口返回是否符合预期。
    • 可以使用assert_XXX(jmes_path: Text, expected_value: Any)来进行提取和验证。

四、测试用例-teststeps-RunTestCase

  • 通过RunTestCase对其他测试用例进行调用,并且还可以导出用例中你所需要的变量,来满足后续用例的的运行。

    • RunTestCase(name)
    • 这个参数呢还是一个名称,毕竟RunTestCase还是一个Step,这个名称同样会在日志和报告中显示。
    • with_variables
    • 这个变量跟RunRequest里的用法一样。
    • call
    • 这里就是指定你要引用的testcase类名称了。

    image

    • 导入的testcase需要起个别名,不能已test开头,会被系统识别成一个testcase
    • export
    • 可以指定要导出的变量,以供后续Step引用。
    • 可以看的.export()内部是一个列表[],这里可以用来导出多个变量。

五、用例引用、变量传递

  • testcase引用&变量传递

  • 当第二个接口的入参是第一个接口的返回值,此时两个接口之间就有了依赖关系。

  • 实操:在写第二个接口的时候,去引用第一个接口用例,并且把第一个用例变量导出来,第二个用例传参的时候使用。

  • ---操作传参---

https://www.cnblogs.com/may18/category/1810026.html

踩过的坑。

传参实操:

1.当前请求使用变量

在Config()之后使用.variables(**{"变量名称":"变量值",})的格式设置变量

或者在用例内部RunRequest() 之后,使用.with_variables(**{"变量名称":"变量值", } )的格式设置变量。

重点:变量名称必须全部小写。

  1. 2引用:使用时以 引用名称:"$变量名称" 的格式直接引用接口

2.提取响应值为下一个请求的参数

2.1首先要在全局变量config 中,设置.export(*["token"])这个全局变量

2.2在断言之前,使用以下代码,提取token的值赋值给"token"这个全局变量。

.extract()
.with_jmespath("body.data.token", "token")

2.2在同一个testcase中,登录之后的的接口,都可通过引用的方式,直接使用token。

六、实操演练


#### 在同一个文件中==变量传递实操演练——代码详情


from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase


class TestCaseOlnyLogin(HttpRunner):

    config = (
        Config("登录")
        .variables(
            **{
                "agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36",
                "type": "application/json;charset=UTF-8",   # 定义全局变量
            }
        )
        .base_url("http://172.16.1.100:8083")
        .verify(False)
        .export(*["token"])    # 此处定义要导出的token
              )

    teststeps = [
        Step(
            RunRequest("登录接口")
                .post("/v1/api/login")

                .with_headers(
                **{
                    "Authorization": "Bearer null",
                    "User-Agent": "$agent",
                    "Content-Type": "$type",
                }
            )
                .with_json(
                {
                    "username": "zhangsan",
                    "password": "YWJjMTIzIUAj",
                    "image_code_id": "c2c28c83-3d8f-4d7c-b62e-1cc93c73322b",
                    "image_code": "uqh5",
                }
            )
                .extract()    # 提取响应值
                .with_jmespath("body.data.token", "token")   # 提取token值,赋值给全局变量
                .validate()
                .assert_equal("body.data.username", "zhangsan")
        ),
        Step(
            RunRequest("条件查询:水利场景")
            .get("/v1/organizer/question/ctflist")
            .with_params(
                **{
                    "page": "1",
                    "pageSize": "10",
                    "keyword": "水利发电场景",
                    "_t": "1647930450442",
                }
            )
            .with_headers(
                **{
                    "Authorization": "Bearer "+"$token",  # 使用全局变量token
                    "User-Agent": "$agent",
                }
            )
            .validate()
            .assert_equal("status_code", 200)
            .assert_equal('headers."Content-Type"', "application/json")
            .assert_equal("body.code", 200)
        ),
    ]


if __name__ == "__main__":
    TestCaseOlnyLogin().test_start()
### 在不同文件中==变量传递实操演练——代码详情之 被提取者

from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase


class TestCaseOlnyLogin(HttpRunner):

    config = (
        Config("登录")
        .variables()
        .base_url("http://172.16.1.100:8083")
        .verify(False)
        .export(*["token"])                # 此处定义要导出的token(等待下一个接口调用)
              )

    teststeps = [
        Step(
            RunRequest("登录接口")
            .post("/v1/api/login")
            .with_headers(
                **{
                    "Authorization": "Bearer null",
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36",
                }
            )
            .with_json(
                {
                    "username": "zhangsan",
                    "password": "YWJjMTIzIUAj",
                    "image_code_id": "c2c28c83-3d8f-4d7c-b62e-1cc93c73322b",
                    "image_code": "uqh5",
                }
            )
            .extract()  # 提取响应值
            .with_jmespath("body.data.token", "token")           # 提取token值,赋值给全局变量
            .validate()
            .assert_equal("body.data.username", "zhangsan")
        ),

    ]


if __name__ == "__main__":
    TestCaseOlnyLogin().test_start()
### 在不同文件中==变量传递实操演练——代码详情之 提取者

import sys

import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
print(sys.path)                    # 把根目录放入系统路径,方便包与包之间传递数据



from test_login.api.olny_login_test import TestCaseOlnyLogin

from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase   # 要导入你需要调取变量所属的类

class TestCaseHome(HttpRunner):

    config =(
        Config("首页数据")
        .variables()
        .base_url("http://172.16.1.100:8083")
        .verify(False)
    )


    teststeps = [
        Step(
            RunTestCase("获取首页数据_引用token")       # 如果需要使用其它文件的变量,需要单独设置一个步骤来获取(RunTestCase)
            .with_variables()
            .call(TestCaseOlnyLogin)                 # 使用call 引入 已经导过包的 有所需变量的类
            .export(*["token"])                      # 将类里需要提取的变量导出
        ),
        Step(
            RunRequest("获取首页数据_引用token")
                .post("/v1/organizer/home")
                .with_headers(
                **{
                    "Authorization": "Bearer "+"$token",  # 使用已经提取的变量
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36",
                }
            )
                .with_data("")
                .validate()
                .assert_equal("status_code", 200)
                .assert_equal('headers."Content-Type"', "application/json")
                .assert_equal("body.code", 200)
        ),

    ]


if __name__ == "__main__":
    TestCaseHome().test_start()

完结。

posted @ 2022-03-25 18:24  nida  阅读(284)  评论(0)    收藏  举报