httprunner4学习总结6 – 手动编写测试用例

1、pytest格式测试用例基本内容

import pytest
from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
from lib.common.config_operate import read_ini_config
from testcases.remote_expert.test_001_banner import (
    TestCaseTest001Banner as Banner001,
)
from testcases.remote_expert.test_003_banner import (
    TestCaseTest003Banner as Banner003,
)


@pytest.mark.skipif(
    read_ini_config("Header", "accept-language") == "zh-CN", reason="仅适用于地球外的测试环境"
)
class TestCaseTest002Banner(HttpRunner):

    config = (
        Config("开启和关闭banner成功")
        # 这里可以替换需要配置的参数,当调用用例的时候可以使用 with_variables()重写参数的值
        .variables(
            **{
                "xx": "xx",
                "yy": "yy",
            }
        )
        .base_url("${read_ini_config(Host, rem_host_001)}")
        .verify(False)
        .export("code")
    )

    teststeps = [
        # 测试步骤1
        Step(
            RunTestCase("前置1:添加一条banner数据")
            .setup_hook("${setup_clean_data()}")  # 调用用例前执行测试前置
            .with_variables(  # 更新用例里面的字段值
                **{
                    "xx": "yy",
                }
            )
            .call(Banner001)  # 调用用例
            .teardown_hook("${teardown_clean_data()}")  # 测试后置
            .export("xx")  # 导出某个值,供下面的步骤使用。这个值来自于本条用例响应内容with_jmespath()
        ),
        Step(RunTestCase("前置2:获取banner页第一行数据ID").call(Banner003).export("id")),
        Step(
            RunRequest("步骤1:关闭 banner ")
            .with_variables(**{"xx": "as"})
            .setup_hook("${setup_clean_data()}")
            .post(
                "/xxxapp/xxxv1/xxxStatus"
            )
            .with_headers(
                **{
                    "accept-language": "${read_ini_config(Header, accept-language)}",
                    "autel-token": "${get_login_info(expert_001, token)}",
                }
            )
            .with_json({"id": "$id", "displayStatus": False})
            .extract()
            .with_jmespath("body.code", "code")
            .validate()
            .assert_equal("status_code", 200)
            .assert_equal("body.code", "200")
            .assert_equal("body.message", "success")
            .assert_equal("body.data", True)
        ),
    ]


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

2、测试用例增强(参考后面的示例)

  • variables 变量

变量优先级:step variables > session variables(runtestcase时带的变量) > parameter variables > config variables

  • extract 参数提取
  • debugtalk.py 自定义函数
  • parameterize 参数化数据驱动
  • hook 机制
  • validate 结果校验

3、完整的 pytest 格式的测试用例

# demo_banner_test.py

import pytest
from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase
from testcases.pytest测试用例示例.test_001_banner import (
    TestCaseTest001Banner as Banner001,
)
from testcases.pytest测试用例示例.test_003_banner import (
    TestCaseTest003Banner as Banner003,
)
from httprunner import Parameters
from lib.common.config_operate import read_ini_config


@pytest.mark.skipif(
    read_ini_config("Header", "accept-language") == "zh-CN", reason="仅适用于地球外的测试环境"
)
class TestCaseTest002Banner(HttpRunner):
    # 变量_全局变量:字段取值参数化
    @pytest.mark.parametrize(
        "param",
        Parameters(
            {
                "title": "${get_user_id(10)}",
                "user": ["user1", "user2"],
                "title-user": [("demo4", "4"), ("demo5", "5"), ("dmeo6", "6")],
            }
        ),
    )
    def test_start(self, param):
        super().test_start(param)

    config = (
        Config("开启和关闭banner成功")
        # 变量_全局变量:这里可以替换需要配置的参数,当调用用例的时候可以使用 with_variables()重写参数的值。这里是这条测试用例的全局变量。优先级没有测试步骤里面的高
        .variables(
            **{
                "xx": "xx",
                "yy": "yy",
            }
        )
        .base_url("${read_ini_config(Host, rem_host_001)}")
        .verify(False)
        # 变量_局部变量:该用例被调用时传递出去的变量,可供其他脚本使用
        .export("code")
    )

    teststeps = [
        # 测试步骤1
        Step(
            RunTestCase("前置1:添加一条banner数据")
            .setup_hook("${setup_clean_data()}")  # 调用用例前执行测试前置
            # 变量_局部变量:更新某个 step 里面的字段值
            .with_variables(
                **{
                    "xx": "yy",
                }
            )
            .call(Banner001)  # 调用用例
            .teardown_hook("${teardown_clean_data()}")  # 测试后置
            # 变量_局部变量:导出某个值,供下面的步骤使用。这个值来自于本条用例响应内容with_jmespath()
            .export("xx")
        ),
        Step(RunTestCase("前置2:获取banner页第一行数据ID").call(Banner003).export("id")),
        Step(
            RunRequest("步骤1:关闭 banner ")
            .with_variables(**{"xx": "as"})
            # hook_测试前:测试前的清理操作
            .setup_hook("${setup_clean_data1()}")
            .setup_hook("${setup_clean_data2()}")
            .setup_hook("${setup_clean_data3()}")
            .post(
                "/xxx-app/xxx/operaxxx"
            )
            .with_headers(
                **{
                    "accept-language": "${read_ini_config(Header, accept-language)}",
                    "autel-token": "${get_login_info(expert_001, token)}",
                }
            )
            # 变量_引用:使用 ${id} 或者 $id,一般使用 ${id}
            .with_json({"id": "$id", "displayStatus": False})
            # hook_测试后:测试数据清理
            .teardown_hook("${teardown_clean_data4()}")
            .teardown_hook("${teardown_clean_data5()}")
            # 变量_局部变量:提取响应的参数值
            .extract()
            .with_jmespath("body.code", "code")
            # 校验
            .validate()
            .assert_equal('headers."Content-Type"', "application/json")
            .assert_equal("status_code", 200)
            .assert_equal("body.code", "200")
            .assert_equal("body.message", "success")
            .assert_contains("body.data.records[0].name", "接口自动化")
        ),
    ]




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

4、完整 yaml 格式的测试用例

config:
  name: "demo with complex mechanisms"
  verify: False
  base_url: "https://postman-echo.com"
  headers:
    X-Request-Timestamp: "165460624942"
  parameters:
    user_agent: [ "iOS/10.1", "iOS/10.2" ]
    username-password: ${parameterize($file)}
  parameters_setting:
    strategies:
      user_agent:
        name: "user-identity"
        pick_order: "sequential"
      username-password:
        name: "user-info"
        pick_order: "random"
    limit: 6
  think_time:
    strategy: random_percentage
    setting:
      max_percentage: 1.5
      min_percentage: 1
    limit: 4
  variables:
    app_version: v1
    user_agent: iOS/10.3
    file: examples/hrp/account.csv
  websocket:
    reconnection_times: 5
    reconnection_interval: 2000
  export: ["app_version"]
  weight: 10

teststeps:
  -
    name: get with params
    variables:
      foo1: ${ENV(USERNAME)}
      foo2: bar21
      sum_v: "${sum_two_int(1, 2)}"
    request:
      method: GET
      url: $base_url/get
      params:
        foo1: $foo1
        foo2: $foo2
        sum_v: $sum_v
    extract:
      foo3: "body.args.foo2"
    validate:
      - eq: ["status_code", 200]
      - eq: ["body.args.foo1", "debugtalk"]
      - eq: ["body.args.sum_v", "3"]
      - eq: ["body.args.foo2", "bar21"]
  -
    name: post raw text
    variables:
      foo1: "bar12"
      foo3: "bar32"
    request:
      method: POST
      url: $base_url/post
      headers:
        Content-Type: "text/plain"
      body: "This is expected to be sent back as part of response body: $foo1-$foo2-$foo3."
    validate:
      - eq: ["status_code", 200]
      - eq: ["body.data", "This is expected to be sent back as part of response body: bar12-$expect_foo2-bar32."]
  -
    name: post form data
    variables:
      foo2: bar23
    request:
      method: POST
      url: $base_url/post
      headers:
        Content-Type: "application/x-www-form-urlencoded"
      body: "foo1=$foo1&foo2=$foo2&foo3=$foo3"
    validate:
      - eq: ["status_code", 200]
      - eq: ["body.form.foo1", "$expect_foo1"]
      - eq: ["body.form.foo2", "bar23"]
      - eq: ["body.form.foo3", "bar21"]

5、编写gotest测试用例

暂不投入

6、编写json测试用例

暂不投入

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿_焦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值