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)}
执行用例成功