欢迎光临
我们一直在努力

使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 44--将自动化测试结果自动推送至钉钉工作群聊

测试学习记录,仅供参考!

将钩子函数获取到的自动化测试统计结果发送到钉钉聊天群里面

1、烦请自行下载、注册钉钉(例:企业微信、飞书等等),创建一个聊天群;

2、在群设置里面添加一个聊天机器人(自行添加设置);

3、在机器人设置中获取到聊天群机器人的 'Webhook地址' 和 '加签签名' 字段信息;

        Webhook:–发送请求时需要把消息推送给Webhook接口地址

        加签:–钉钉安全设置三种方式之一,需要用到的是加签方式–拿到加签签名

生成签名计算在钉钉官方文档中是有的,可直接粘贴复制–自定义机器人接入-钉钉开发平台

4、拿到这两个字段之后就可以在代码中去发送请求,然后把测试结果推送到聊天群里;

生成加密密钥

5、在项目根目录 util_tools 软件包下新建一个名称为 dingRebot.py 的 Python 文件;

# 导包
import time
import urllib.parse
import hmac
import hashlib
import base64

# 生成加签密钥
def generate_sign():
# 通过 time.time() 获取时间戳–获取13位乘以1000–调用round函数保留整数–最后再转成字符串得到当前时间戳–返回给timestamp
timestamp = str(round(time.time() * 1000))
# 获取钉钉机器人里面的加签密钥–属于某个钉钉群里面的加签密钥
secret = 'SEC5bec56af5a1059e5e69b75250703dc53236c09e61501b356c3bf21c21b55b5e5'
# 转码成utf-8
secret_enc = secret.encode('utf-8')
# 组合当前时间戳和加签密钥
str_to_sign = f'{timestamp}\\n{secret}'
# 先打印查看得到的是什么
print(str_to_sign)

# 调用测试
print(generate_sign())

6、单独运行 dingRebot.py 文件查看结果;

1621578081
SEC5bec56af5a1059e5e69b75250703dc53236c09e61501b356c3bf21c21b55b5e5
None

进程已结束,退出代码为 0

7、优化 dingRebot.py 文件;

# 导包
import time
import urllib.parse
import hmac
import hashlib
import base64

# 生成加签密钥
def generate_sign():
# 通过 time.time() 获取时间戳–获取13位乘以1000–调用round函数保留整数–最后再转成字符串得到当前时间戳–返回给timestamp
timestamp = str(round(time.time() * 1000))
# 获取钉钉机器人里面的加签密钥–属于某个钉钉群里面的加签密钥
secret = 'SEC5bec56af5a1059e5e69b75250703dc53236c09e61501b356c3bf21c21b55b5e5'
# 转码成utf-8
secret_enc = secret.encode('utf-8')
# 组合当前时间戳和加签密钥
str_to_sign = f'{timestamp}\\n{secret}'
# 转成byte类型
str_to_sign_enc = str_to_sign.encode('utf-8')
# 先打印查看
print(str_to_sign_enc)

# 调用测试
print(generate_sign())

8、再次运行 dingRebot.py 文件查看结果;

        拿到这组数据之后,通过加密方式加密当前时间戳和密钥;

b'1621578081\\nSEC5bec56af5a1059e5e69b75250703dc53236c09e61501b356c3bf21c21b55b5e5'
None

进程已结束,退出代码为 0

9、优化 dingRebot.py 文件,进行初步加密;

        1)、hmac:调用加密模块;

        2)、hmac.new():直接点.调用 hmac.new() 方法;

        3)、hmac.new(secret_enc, str_to_sign_enc):传参;里面第一个参数传 secret_enc,第二个参数传 str_to_sign_enc;注意参数别传错了;

        4)、hmac.new(secret_enc, str_to_sign_enc, digestmod=hashlib.sha256):调用hashlib模块里面的一个内置方法 digestmod=hashlib.sha256()–直接点.调用时会带有括号,这里不需要直接去掉,调用函数名就行;

        5)、hmac.new(secret_enc, str_to_sign_enc, digestmod=hashlib.sha256).digest():调用digest()方法;

        6)、hmac_code = hmac.new(secret_enc, str_to_sign_enc, digestmod=hashlib.sha256).digest():返回;

# 导包
import time
import urllib.parse
import hmac
import hashlib
import base64

# 生成加签密钥
def generate_sign():
# 通过 time.time() 获取时间戳–获取13位乘以1000–调用round函数保留整数–最后再转成字符串得到当前时间戳–返回给timestamp
timestamp = str(round(time.time() * 1000))
# 获取钉钉机器人里面的加签密钥–属于某个钉钉群里面的加签密钥
secret = 'SEC5bec56af5a1059e5e69b75250703dc53236c09e61501b356c3bf21c21b55b5e5'
# 转码成utf-8
secret_enc = secret.encode('utf-8')
# 组合当前时间戳和加签密钥
str_to_sign = f'{timestamp}\\n{secret}'
# 转成byte类型
str_to_sign_enc = str_to_sign.encode('utf-8')
# 通过加密方式加密当前时间戳和密钥–初步加密
hmac_code = hmac.new(secret_enc, str_to_sign_enc, digestmod=hashlib.sha256).digest()
# 打印查看得到的初步加密方式
print(hmac_code)

# 调用测试
print(generate_sign())

10、运行 dingRebot.py 文件查看初步加密;

b'\\x6a0\\xf0\\xcbc_\\xfb\\x86\\x16RS\\x07kJ\\x1fs5\\x17\\xdc\\xb7\\xdb\\xf0OJ7\\xa1\\xf7\\xdcb\\xa9\\xf1('
None

进程已结束,退出代码为 0

11、进一步加密,得到最终的一个签名;

        1)、urllib.parse:调用 urllib.parse 方法;

        2)、urllib.parse.quote_plus():调用 quote_plus() 方法;

        3)、urllib.parse.quote_plus(base64):调用 base64 模块里面的方法;

        4)、urllib.parse.quote_plus(base64.b64encode()):encode转码decode解码,注意两者区别别弄错了;

        5)、sign = urllib.parse.quote_plus(base64.b64encode(hmac_code)):把 hmac_code 传进来并返回;

# 导包
import time
import urllib.parse
import hmac
import hashlib
import base64

# 生成加签密钥
def generate_sign():
# 通过 time.time() 获取时间戳–获取13位乘以1000–调用round函数保留整数–最后再转成字符串得到当前时间戳–返回给timestamp
timestamp = str(round(time.time() * 1000))
# 获取钉钉机器人里面的加签密钥–属于某个钉钉群里面的加签密钥
secret = 'SEC5bec56af5a1059e5e69b75250703dc53236c09e61501b356c3bf21c21b55b5e5'
# 转码成utf-8
secret_enc = secret.encode('utf-8')
# 组合当前时间戳和加签密钥
str_to_sign = f'{timestamp}\\n{secret}'
# 转成byte类型
str_to_sign_enc = str_to_sign.encode('utf-8')
# 通过加密方式加密当前时间戳和密钥–初步加密
hmac_code = hmac.new(secret_enc, str_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
# 打印查看得到的最终签名
print(sign)

# 调用测试
print(generate_sign())

12、运行 dingRebot.py 文件查看得到的最终签名;

dWmAZkP%5BUU5cgCckTfOs95qydXYF6BXRDmlH6sHSHT8%6D
None

进程已结束,退出代码为 0

13、通过时间戳和机器人的签名,然后通过加密的方式得到最终签名;

        最后把结果给返回出去;返回两个参数,一个是 timestamp(后面需要用到时间戳),第二个是 sign 签名;

# 导包
import time
import urllib.parse
import hmac
import hashlib
import base64

# 生成加签密钥
def generate_sign():
# 通过 time.time() 获取时间戳–获取13位乘以1000–调用round函数保留整数–最后再转成字符串得到当前时间戳–返回给timestamp
timestamp = str(round(time.time() * 1000))
# 获取钉钉机器人里面的加签密钥–属于某个钉钉群里面的加签密钥
secret = 'SEC5bec56af5a1059e5e69b75250703dc53236c09e61501b356c3bf21c21b55b5e5'
# 转码成utf-8
secret_enc = secret.encode('utf-8')
# 组合当前时间戳和加签密钥
str_to_sign = f'{timestamp}\\n{secret}'
# 转成byte类型
str_to_sign_enc = str_to_sign.encode('utf-8')
# 通过加密方式加密当前时间戳和密钥–初步加密
hmac_code = hmac.new(secret_enc, str_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))

return timestamp, sign

# 调用测试
print(generate_sign())

发起机器人信息请求

14、签名方法编写完成之后,继续写发送机器人消息方法;

# 导包
import time
import urllib.parse
import hmac
import hashlib
import base64
import requests

# 生成加签密钥
def generate_sign():
# 通过 time.time() 获取时间戳–获取13位乘以1000–调用round函数保留整数–最后再转成字符串得到当前时间戳–返回给timestamp
timestamp = str(round(time.time() * 1000))
# 获取钉钉机器人里面的加签密钥–属于某个钉钉群里面的加签密钥
secret = 'SEC5bec56af5a1059e5e69b75250703dc53236c09e61501b356c3bf21c21b55b5e5'
# 转码成utf-8
secret_enc = secret.encode('utf-8')
# 组合当前时间戳和加签密钥
str_to_sign = f'{timestamp}\\n{secret}'
# 转成byte类型
str_to_sign_enc = str_to_sign.encode('utf-8')
# 通过加密方式加密当前时间戳和密钥–初步加密
hmac_code = hmac.new(secret_enc, str_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))

return timestamp, sign

# 发送钉钉群消息
def send_dd_msg(content_str, at_all=True):
"""
:param content_str: 发送的内容
:param at_all: 是否@全员,默认为True
:return:
"""
# 调用generate_sign()方法–用两个参数去接受调用generate_sign()方法返回函数的结果
timestamp, sign = generate_sign()
# 参照官方文档组成一个完整的url地址–通过‘&’符号去拼接已经复制好的 Webhook、时间戳、签名
url = f'https://oapi.dingtalk.com/robot/send?access_token=db50eb02dea33ed5ef5e5cfc2cc9f50d737f0ac2c636e9b329e511c365d5ae55&timestamp={timestamp}&sign={sign}'
# 请求头(参考钉钉开放接口官方文档)–这里是一个 json 提交格式
headers = {'Content-Type': 'application/json;charset=UTF-8'}
# 入参–消息类型msgtype:文本text–第二个又是嵌套字典text发送内容:要传进来的参数content–下一个参数名是'at'是否发送全员提醒
data = {
'msgtype': 'text',
'text': {'content': content_str},
'at': {'isAtAll': at_all}
}
# 发起请求,引入requests模块–使用post请求方式,传已经拼接完成的url,用json格式提交入参data,再把请求头headers传给它–返回出去
res = requests.post(url=url, json=data, headers=headers)
# 返回文本信息res.text
return res.text

# 调用发送消息方法
print(send_dd_msg('这是一个测试消息:123'))

15、运行一下,查看能否成功发送出消息;

{"errcode":0,"errmsg":"ok"}

进程已结束,退出代码为 0

        1)、可以查看到发送的测试消息是提醒全部人员;

        2)、设置 at_all=False 参数为False;

# 调用发送消息方法
print(send_dd_msg('这是一个测试消息:123', at_all=False))

# 运行dingRebot.py文件结果
{"errcode":0,"errmsg":"ok"}

进程已结束,退出代码为 0

        3)、再次发送执行,可以看到只是发送一条普通消息,不进行全员提醒;

把加签签名、url 地址写到配置文件中

16、把加签签名、url 地址写到配置文件中去(后续需要再其他的钉钉群里发送消息,直接修改'地址'和'加签'信息即可)

17、优化项目根目录 configs 软件包下 setting.py 文件–(把'加签签名'和'url 地址'放在setting.py文件中)

# 导包
import os
import sys

DIR_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(DIR_PATH)

# 显示等待时间设置,默认为10秒
WAIT_TIME = 10

# 设置浏览器
browser_type = 'edge'
# browser_type = 'chrome'

# 消息是否发送–True是发送,False是不发送
is_dd_msg = False
# 自定义机器人签名
secret = 'SEC5bec56af5a1059e5e69b75250703dc53236c09e61501b356c3bf21c21b55b5e5'
# URL地址
webhook = ('https://oapi.dingtalk.com/robot/send?access_token=db50eb05dea33ed5ef5e5cfc2cc9f50d737f0ac2c636e9b329e511c365d5ae55')

# 文件路径
FILE_PATH = {
'log': os.path.join(DIR_PATH, 'log'),
'screenshot': os.path.join(DIR_PATH, 'screenshot'),
'ini': os.path.join(DIR_PATH, 'config', 'config.ini')
}

18、优化项目根目录 util_tools 软件包下 dingRebot.py 文件;通过配置文件调用;

# 导包
import time
import urllib.parse
import hmac
import hashlib
import base64
import requests
from config import setting

# 生成加签密钥
def generate_sign():
# 通过 time.time() 获取时间戳–获取13位乘以1000–调用round函数保留整数–最后再转成字符串得到当前时间戳–返回给timestamp
timestamp = str(round(time.time() * 1000))
# 获取钉钉机器人里面的加签密钥–属于某个钉钉群里面的加签密钥–通过配置文件调用
secret = setting.secret
# 转码成utf-8
secret_enc = secret.encode('utf-8')
# 组合当前时间戳和加签密钥
str_to_sign = f'{timestamp}\\n{secret}'
# 转成byte类型
str_to_sign_enc = str_to_sign.encode('utf-8')
# 通过加密方式加密当前时间戳和密钥–初步加密
hmac_code = hmac.new(secret_enc, str_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))

return timestamp, sign

# 发送钉钉群消息
def send_dd_msg(content_str, at_all=True):
"""
:param content_str: 发送的内容
:param at_all: 是否@全员,默认为True
:return:
"""
# 调用generate_sign()方法–用两个参数去接受调用generate_sign()方法返回函数的结果
timestamp, sign = generate_sign()
# 参照官方文档组成一个完整的url地址–通过‘&’符号去拼接已经复制好的 Webhook、时间戳、签名–通过配置文件调用
url = f'{setting.webhook}&timestamp={timestamp}&sign={sign}'
# 请求头(参考钉钉开放接口官方文档)–这里是一个 json 提交格式
headers = {'Content-Type': 'application/json;charset=UTF-8'}
# 入参–消息类型msgtype:文本text–第二个又是嵌套字典text发送内容:要传进来的参数content–下一个参数名是'at'是否发送全员提醒
data = {
'msgtype': 'text',
'text': {'content': content_str},
'at': {'isAtAll': at_all}
}
# 发起请求,引入requests模块–使用post请求方式,传已经拼接完成的url,用json格式提交入参data,再把请求头headers传给它–返回出去
res = requests.post(url=url, json=data, headers=headers)
# 返回文本信息res.text
return res.text

19、优化项目根目录下 conftest.py 文件–发送自动化测试结果信息;

# 导包
import time
import pytest
from util_tools.connectMysql import ConnectMysql
from util_tools.dingRebot import send_dd_msg
from util_tools.logs_util.recordlog import logs
from config.setting import is_dd_msg

# 添加后置应用–数据清理
@pytest.fixture(scope='session', autouse=True)
def data_cleaning():
"""测试结束后清理测试数据"""
# 初始化连接数据库对象
conn = ConnectMysql()
yield
logs.info('正在清理测试数据…')
# 删除语句(注册成功用户)–若有别的可以继续写
sql = 'delete from ecs_users where user_name="test06"'
# 调用删除语句
conn.delete(sql)

def pytest_terminal_summary(terminalreporter, exitstatus, config):
"""
pytest预定义钩子函数,用于自动收集测试用例执行结果
:param terminalreporter: 报告汇总,内部使用的终端测试报告器对象,用于输出内容
:param exitstatus: 返回码退出状态:0-用例全部通过;1-有用例失败;2-还没执行,在收集用例就失败了;3、4-其他报错;5-收集到0条用例
:param config: pytest全局config配置对象
:return:
"""
# 调用里面的内置方法,最后把收集统计到的测试用例总数量返回出去给一个变量(把所有测试用例收集完之后才去统计)
total = terminalreporter._numcollected
# 通过数
passed = len(terminalreporter.stats.get('passed', []))
# 失败数
failed = len(terminalreporter.stats.get('failed', []))
# 错误数
error = len(terminalreporter.stats.get('error', []))
# 跳过数
skipped = len(terminalreporter.stats.get('skipped', []))
# 执行总时长–调用内置函数round()
duration = round(time.time() – terminalreporter._sessionstarttime, 2)

# 定义一个字符串
summary = f"""
自动化测试结果,通知如下,具体执行结果如下:
测试用例总合计数:{total}
测试执行通过数:{passed}
测试执行失败数:{failed}
错误数量:{error}
跳过执行测试用例数量:{skipped}
执行测试用例总耗时:{duration}秒
"""
print(summary)
# 判断is_dd_msg值
if is_dd_msg:
# 发送消息
send_dd_msg(summary)

20、运行主函数 run.py 文件;

未完待续。。。

赞(0)
未经允许不得转载:171主机测评 » 使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 44--将自动化测试结果自动推送至钉钉工作群聊
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址