天天看点

L03_HttpRunner的hook(钩子)机制:(setup/teardown)对请求和响应内容进行预处理

L03_HttpRunner的hook(钩子)机制:(setup/teardown)对请求和响应内容进行预处理

有些系统登录页面输入用户名和密码,出于安全考虑,提交前需要对密码进行额外处理,如图所示:

L03_HttpRunner的hook(钩子)机制:(setup/teardown)对请求和响应内容进行预处理

从源码来看,是在原始密码后添加了一个“Verydows”字符串,然后对这个新的字符串进行MD5哈希运算,得出的摘要字符串数据作为传输的密码内容使用。过程相当于:

原始密码 = 123456
字符串A = 原始密码 + “Verydows” = "123456Verydows"
新密码 = md5(字符串A) = md5("123456Verydows") = 200c6d94e583e62c6964de3acdc723e5

           

在编写测试用例的时候,把登录表单数据通过请求发给服务器,肯定不能直接写成原始密码方式,但如果把处理后的密码作为测试数据,这显然又不友好。

不友好用例: 密码使用处理后内容,不易读,且构造测试数据存在困难。

request:
      url: http://.......
      method: POST
      data:
        username: admin
        password: 200c6d94e583e62c6964de3acdc723e5
           

友好的用例格式:密码使用原始密码

request:
      url: http://.......
      method: POST
      data:
        username: admin
        password: 123456
           

问题的解决,这里提供两种方式:

  • 方式一:单独定义一个密码处理函数,在密码赋值时直接调用;
  • 方式二:通过钩子函数,提交前对请求数据进行二次加工和处理。

方式一:单独定义一个密码处理函数

在 debugtalk.py 文件中定义函数 get_md5_str(),将传入的密码进行 MD5 处理,执行后输出结果和我们抓包看到的处理后密码完全相同。

import hashlib


def get_md5_str(pwd):
    str_pwd = "%sVerydows" % pwd
    str_pwd_to_b = bytes(str_pwd, encoding='utf-8')
    str_md5 = hashlib.md5(str_pwd_to_b).hexdigest()
    return str_md5


if __name__ == "__main__":
    print(get_md5_str("123456"))


执行输出:
200c6d94e583e62c6964de3acdc723e5        
           

编写测试用例:

- config:
    name: 测试用例


- test:
    name: 测试步骤 - 打开登录页面
    variables:
      # 将原始密码提取为一个变量  
      p_pwd: 123456

    request:
      url: http://192.168.1.102/verydows/index.php?m=backend&c=main&a=login
      method: POST
      data:
        username: admin
        # 调用密码处理函数,将原始密码进行加工
        password: ${get_md5_str($p_pwd)}
    validata:
      - eq: [status_code, 200]
      - eq: [<iframe name="(.*)" id="main", main]
    
           

方式二:通过钩子函数对请求进行预处理

在 debugtalk.py 文件中定义两个函数:

  • 函数1:get_md5_str():将原始密码进行摘要处理
  • 函数2:set_req():将请求中的密码数据替换为前面处理好的摘要数值
import requests
import hashlib

# 将原始密码进行摘要处理
def get_md5_str(pwd):
    str_pwd = "%sVerydows" % pwd
    str_pwd_to_b = bytes(str_pwd, encoding='utf-8')
    str_md5 = hashlib.md5(str_pwd_to_b).hexdigest()
    return str_md5


# 将请求内容进行预处理
def set_req(req, pwd):
    # 将原始密码进行摘要处理
    new_pwd = get_md5_str(pwd)
    # 将请求中的原始密码替换为摘要密码
    req[data][password] = new_pwd
           

编写测试用例:

注意:

  • 在调用自定义函数时,需要传入 $request 参数,这是对当前测试步骤请求的封装的引用。有了这个参数,函数内就可以实现对请求的加工和处理了,相当于在向服务器发送前,改变了原来请求的内容。
  • 同理,如果在 teardown_hooks 钩子中传入 $response 参数,则可以对服务器的响应内容预先进行处理和调整。
- config:
    name: 测试用例


- test:
    name: 测试步骤 - 打开登录页面
    variables:
      p_pwd: 123456

    request:
      url: http://192.168.1.102/verydows/index.php?m=backend&c=main&a=login
      method: POST
      data:
        username: admin
        password: $p_pwd
    validata:
      - eq: [status_code, 200]
      - eq: [<iframe name="(.*)" id="main", main]
    
    setup_hooks:
      # 对请求头中的密码数据进行预处理  
      - ${set_req($request, $p_pwd)}
   
           

执行用例成功

L03_HttpRunner的hook(钩子)机制:(setup/teardown)对请求和响应内容进行预处理

继续阅读