python根据excel生成web报表_Python+requests+excel+unittest+DDT接口,自动驱动数据并生成HTML报表(优化版),pythonrequestsexcelun...

本文章内容是基于上海-悠悠的版本,进行了优化,增加了部分内容,详细请查阅下文。

1、原文链接

2、修改前后框架区别

修改前:

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L05vYW1hTmVsc29u,size_16,color_FFFFFF,t_70

修改后:

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L05vYW1hTmVsc29u,size_16,color_FFFFFF,t_70

3、主要修改内容

增加:token关联(token获取和保存)

增加:cookie关联(cookie获取和保存)

增加:发送邮件(使用SMTP)

修改:HTML报告模板中的样式和ddt用例的标题

增加:logo日志

4、详细修改内容说明

4.1、增加token关联

4.1.1、token获取get_token.py

import json

import requests

from common.operation_json import OperetionJson

class OperationHeader:

def __init__(self, response):

# self.response = json.loads(response)

self.response = response

def get_response_token(self):

'''

获取登录返回的token

'''

token = {"data":{"token":self.response['data']['token']}}

#token = {"token": self.response['data']['token']}

return token

def write_token(self):

op_json = OperetionJson()

op_json.write_data(self.get_response_token())

def get_response_msg(self):

reponse_msg = {"msg":self.response['msg']}

#print("reponse_msg:", reponse_msg)

return reponse_msg

4.1.2、token保存operation_json.py

#coding:utf-8

import json

class OperetionJson:

def __init__(self,file_path=None):

if file_path == None:

self.file_path = '../case/cookie.json'

else:

self.file_path = file_path

self.data = self.read_data()

#读取json文件

def read_data(self):

with open(self.file_path, 'r', encoding='utf-8') as fp:

data1 = fp.read()

if len(data1) > 0:

data = json.loads(data1)

else:

data = {}

return data

#根据关键字获取数据

def get_data(self,id):

print(type(self.data))

return self.data[id]

#写json

def write_data(self,data):

with open('../case/token.json','w') as fp:

fp.truncate() # 先清空之前的数据,再写入,这样每次登录的token都是不一样的

fp.write(json.dumps(data))

4.1.3、token的读取base_api.py

在原代码中加入token的读取,即把token加入到heasers中

# 请求头部headers

try:

headers = eval(testdata["headers"])

if testdata["token"] == "yes":

op_json = OperetionJson("../case/token.json")

token = op_json.get_data('data')

headers = dict(headers, **token)

print("请求头部:", headers)

log.info("请求头部:", headers)

except:

headers = None

4.2、增加cookie关联

实现逻辑和获取token一模一样

4.2.1、cookie获取get_token.py

直接在获取token的get_token.py中加入,而这里的token格式需要根据自己的业务修改

def get_response_cookie(self):

cookie1 = requests.utils.dict_from_cookiejar(self.response.cookies)

cookie = {"data":{"gfsessionid":cookie1["gfsessionid"]}}

# {"data": {"token": self.response['data']['token']}}

print("cookie:", cookie)

return cookie

def write_cookie(self):

op = OperetionJson()

op.write_mydata(self.get_response_cookie())

4.2.2、cookie保存operation_json.py

直接在operation_json.py中加入

def write_mydata(self,data):

with open('../case/cookie.json','w') as fp:

fp.truncate() # 先清空之前的数据,再写入,这样每次登录的token都是不一样的

fp.write(json.dumps(data))

4.2.3、cookie的读取base_api.py

直接在base_api.py中加入

try:

headers = eval(testdata["headers"])

if testdata["cookie"] == "yes":

op_json = OperetionJson("../case/cookie.json")

token1 = op_json.get_data('data')

headers = dict(headers, **token1)

print("请求头部:", headers)

log.info("请求头部:", headers)

except:

headers = None

4.3、增加邮件服务

4.3.1、邮件服务封装send_mail.py

#coding=utf-8

from email.mime.text import MIMEText

import time

import smtplib

import getpass

from email.mime.multipart import MIMEMultipart

from email.mime.text import MIMEText

from email.mime.base import MIMEBase

from email import encoders

import email

import os

def sendmain(file_path,mail_to = 'xxxxx@126.com'):

mail_from = 'yyyyy@126.com'

f = open(file_path,'rb')

mail_body=f.read()

f.close()

#msg = email.MIMEMultipart.MIMEMultipart()

msg = MIMEMultipart()

# 构造MIMEBase对象做为文件附件内容并附加到根容器

contype = 'application/octet-stream'

maintype, subtype = contype.split('/', 1)

## 读入文件内容并格式化

data = open(file_path, 'rb')

#file_msg = email.MIMEBase.MIMEBase(maintype, subtype)

file_msg = MIMEBase(maintype, subtype)

file_msg.set_payload(data.read( ))

data.close( )

#email.Encoders.encode_base64(file_msg)

encoders.encode_base64(file_msg)

## 设置附件头

basename = os.path.basename(file_path)

file_msg.add_header('Content-Disposition',

'attachment', filename = basename)

msg.attach(file_msg)

print(u'msg 附件添加成功')

msg1 = MIMEText(mail_body,_subtype='html',_charset='utf-8')

msg.attach(msg1)

if isinstance(mail_to,str):

msg['To'] = mail_to

else:

msg['To'] = ','.join(mail_to)

msg['From'] = mail_from

msg['Subject'] = u'xxxxxxxxx接口自动化测试' # 邮件标题

msg['date']=time.strftime('%Y-%m-%d-%H_%M_%S')

print(msg['date'])

smtp = smtplib.SMTP()

smtp.connect('smtp.126.com')

smtp.login('yyyyyy@126.com','aaaaaaaaaa') # 这里的密码是邮件第三方客户端认证密码

smtp.sendmail(mail_from, mail_to, msg.as_string())

smtp.quit()

print('email has send out !')

'''

if __name__=='__main__':

sendmain('../report/2017-08-18-10_18_57_result.html')

'''

4.3.2、邮件调用run_this.py

直接在主函数入口中调用

sendmain(htmlreport, mail_to=['hhhhhhhh@126.com', 'jjjjjj@126.com', 'uuuuuu@126.com']) #多个收件人的话,直接在列表中,用,号隔开即可

4.4、修改html报告模板

4.4.1、修改报告中用例的标题,修改ddt源码

①原报告用例的标题:

因为使用ddt,所以ddt格式中用例标题是test_api_数字开头的用例名称,如果要自定义需要修改ddt源码

def mk_test_name(name, value, index=0):

"""

Generate a new name for a test case.

It will take the original test name and append an ordinal index and a

string representation of the value, and convert the result into a valid

python identifier by replacing extraneous characters with ``_``.

We avoid doing str(value) if dealing with non-trivial values.

The problem is possible different names with different runs, e.g.

different order of dictionary keys (see PYTHONHASHSEED) or dealing

with mock objects.

Trivial scalar values are passed as is.

A "trivial" value is a plain scalar, or a tuple or list consisting

only of trivial values.

"""

# Add zeros before index to keep order

index = "{0:0{1}}".format(index + 1, index_len, )

if not is_trivial(value) and type(value) is not dict: # 增加的地方,增加value的字典判断

return "{0}_{1}_{2}".format(name, index, value.name) # 修改的地方,增加返回的值

if type(value) is dict: # 增加的地方

try: # 增加的地方

value = value["name"] + "_" + value["function"] # 增加的地方,name和function必须是execl用例中整正存在的表头,这里我是把两个表头合并了(name是我表格中接口的名称,function是表格中接口的功能描述)

except: # 增加的地方

return "{0}_{1}".format(name.index) # 增加的地方

try:

value = str(value)

except UnicodeEncodeError:

# fallback for python2

value = value.encode('ascii', 'backslashreplace')

test_name = "{0}_{1}_{2}".format(name, index, value) # 修改的地方

return re.sub(r'\W|^(?=\d)', '_', test_name)

4.4.2、增加用例执行人

在HTMLTestRunner.py中加入如下,即获取当前用例执行的负载机的用户名

DEFAULT_TESTER = getpass.getuser()

4.5、增加log日志

4.5.1、在框架入口中直接加入run_this.py

# LOG日志记录

logging.basicConfig(level=logging.DEBUG,

format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',

datefmt='%a, %d %b %Y %H:%M:%S',

filename=log_path + '/' + now + r"result.log",

filemode='w')

logger = logging.getLogger()

logger.info(all_case)

4.5.2、在其它模块中直接使用即可

log = logging.getLogger()

log.info("请求头部:", headers)

5、其它截图

log截图:

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L05vYW1hTmVsc29u,size_16,color_FFFFFF,t_70

测试报告:

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L05vYW1hTmVsc29u,size_16,color_FFFFFF,t_70

邮件:

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L05vYW1hTmVsc29u,size_16,color_FFFFFF,t_70

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值