python接口测试框架实战与自动化进阶


 

一、从接口自动化框架设计到开发

1、如何设计一个接口自动化测试框架

 

 

2、python操作excel获得内容 

 安装依赖:

pip install xlwt  # 用于写Excel文件
pip install xlrd  # 用于读取Excel文件

Python对Excel的读写主要有xlrd、xlwt、xlutils、openpyxl、xlsxwriter几种:

  1. xlrd主要是用来读取excel文件
  2. xlwt主要是用来写excel文件
  3. xlutils结合xlrd可以达到修改excel文件目的
  4. openpyxl可以对excel文件进行读写操作
  5. xlsxwriter可以写excel文件并加上图表

 1)python 对Excel文件的基本操作:

# -*- coding: utf-8 -*-
import xlrd
import xlwt
from datetime import date,datetime

def read_excel():
    # 打开文件
    workbook = xlrd.open_workbook(r'F:\demo.xlsx')
    # 获取所有sheet
    workbook.sheet_names() # [u'sheet1', u'sheet2']
    sheet2_name = workbook.sheet_names()[1]

    # 根据sheet索引或者名称获取sheet内容
    sheet2 = workbook.sheet_by_index(1) # sheet索引从0开始
    sheet2 = workbook.sheet_by_name('sheet2')

    # sheet的名称,行数,列数
    sheet2.name,sheet2.nrows,sheet2.ncols

    # 获取整行和整列的值(数组)
    rows = sheet2.row_values(3) # 获取第四行内容
    cols = sheet2.col_values(2) # 获取第三列内容
    print rows
    print cols

    # 获取单元格内容
    sheet2.cell(1,0).value.encode('utf-8')
    sheet2.cell_value(1,0).encode('utf-8')
    sheet2.row(1)[0].value.encode('utf-8')
    
    # 获取单元格内容的数据类型
    sheet2.cell(1,0).ctype

if __name__ == '__main__':
    read_excel()

 

demo:

 封装获取excel表数据相关操作:

import xlrd


class OperationExcel:
    def __init__(self,file_name=None,sheet_id=None):
        if file_name:
            self.file_name = file_name
            self.sheet_id = sheet_id
        else:
            self.file_name = '../media/excel_dir/case1.xls'
            self.sheet_id = 0
        self.data = self.get_data()

    # 获取sheets内容
    def get_data(self):
        data = xlrd.open_workbook(self.file_name)  # 打开excel文件
        tables = data.sheets()[self.sheet_id] # 获取excel文件内容句柄,sheet对象
        return tables

    # 获取单元格行数
    def get_lines(self):
        return self.data.nrows

    # 获取某一单元格的内容
    def get_cell_value(self,row,col):
        return self.data.cell_value(row,col)


if __name__ == '__main__':
    opers = OperationExcel()

 

3、操作json文件

在目录中找到json文件,通过代码操作,获取json文件内指定的数据:

import json

class OperationJson:
    def __init__(self,file_name = None):
        if file_name:
            self.file_name = file_name
        else:
            self.file_name = '../media/json_dir/cookie.json'
        self.data = self.read_data()

    # 读取json文件的数据
    def read_data(self):
        with open(self.file_name) as fp:
            data = json.load(fp)
            return data

    # 根据关键字获取数据
    def get_data(self,key):
        return self.data[key]


if __name__ == '__main__':
    opjson = OperationJson()

 

4、封装获取常量方法

 

class global_var:
    #case_id
    Id = '0'   # id
    request_name = '1'  # 模块
    url = '2'   # url
    run = '3'  # 是否运行
    request_way = '4'   # 请求类型
    header = '5'   # 是否携带header
    case_depend = '6'  # case依赖 ...
    data_depend = '7'
    field_depend = '8'
    data = '9'
    expect = '10'
    result = '11'
#获取caseid
def get_id():
    return global_var.Id

#获取url
def get_url():
    return global_var.url

def get_run():
    return global_var.run

def get_run_way():
    return global_var.request_way

def get_header():
    return global_var.header

def get_case_depend():
    return global_var.case_depend

def get_data_depend():
    return global_var.data_depend

def get_field_depend():
    return global_var.field_depend

def get_data():
    return global_var.data

def get_expect():
    return global_var.expect

def get_result():
    return global_var.result

def get_header_value():
    return global_var.header

 

 5、封装获取接口数据

  • 上面通过封装excel表,提供了python excel表相关的操作:operation_excel.py 文件
  • 同时提供了关键字查询json文件数据的相关操作:operation_json.py 文件
  • 另外配置了excel表中各列的序号,现在我们来设计接口数据封装:data_config.py

  我们的目的是拿到excel表中,每个指定的单元格的数据:

  1. 通过 data_config.py内部的封装操作,拿到excel表的各列序号 ;
  2. 通过operation_excel.py内部封装的get_cell_value() 方法拿到指定单元格的数据,前提需传入行参数 ; 
  3. 通过operation_json.py内部封装的get_data方法,可以拿到json格式的请求数据

 通过上面的操作,我们只需要传入行参数,即第几行,并指定调用对应方法,就是获取想要获取到的单元格数据,实现代码如下:

from util.operation_excel import OperationExcel
from . import data_config
from util.operation_json import OperationJson
class GetData:  # 获取数据
    def __init__(self):
        self.opera_excel = OperationExcel() # 实例化 OperationExcel ,默认操作的excel表:../media/excel_dir/case1.xls

    # 获取excel行数,就是我们的case个数
    def get_case_lines(self):
        return self.opera_excel.get_lines()

    #获取是否执行 yes or no
    def get_is_run(self,row):
        flag = None
        col = int(data_config.get_run()) #第col列
        run_model = self.opera_excel.get_cell_value(row,col) # 拿到row col 指定的单元格数据
        if run_model == 'yes':
            flag = True
        else:
            flag = False
        return flag

    #是否携带header
    def is_header(self,row):
        col = int(data_config.get_header())
        header = self.opera_excel.get_cell_value(row,col)
        if header != '':
            return header
        else:  # 没有携带header
            return None

    #获取请求方式 get or post
    def get_request_method(self,row):
        col = int(data_config.get_run_way())
        request_method = self.opera_excel.get_cell_value(row,col)
        return request_method

    #获取url
    def get_request_url(self,row):
        col = int(data_config.get_url())
        url = self.opera_excel.get_cell_value(row,col)
        return url

    #获取请求数据 request_data
    def get_request_data(self,row):
        col = int(data_config.get_data())
        data = self.opera_excel.get_cell_value(row,col)
        if data == '':
            return None
        return data

    #通过获取关键字拿到data数据(是个字段) ,存于json文件中
    def get_data_for_json(self,row):
        opera_json = OperationJson()
        request_data = opera_json.get_data(self.get_request_data(row))
        return request_data

    #获取预期结果
    def get_expcet_data(self,row):
        col = int(data_config.get_expect())
        expect = self.opera_excel.get_cell_value(row,col)
        if expect == '':
            return None
        return expect

 

6、 post、get基类的封装

import requests
import json
class RunMethod:
    def post_main(self,url,data,header=None):
        res = None
        if header != None:    
            res = requests.post(url=url,data=data,headers=header)
        else:
            res = requests.post(url=url,data=data)
        return res.json()

    def get_main(self,url,data=None,header=None):
        res = None
        if header != None:    
            res = requests.get(url=url,data=data,headers=header,verify=False)
        else:
            res = requests.get(url=url,data=data,verify=False)
        return res.json()

    def run_main(self,method,url,data=None,header=None):
        res = None
        if method == 'Post':
            res = self.post_main(url,data,header)
        else:
            res = self.get_main(url,data,header)
        return json.dumps(res,ensure_ascii=False)

 

 7、主程序封装,程序启动在此文件启动

from base.runmethod import RunMethod
from data.get_data import GetData
from util.operation_json import OperationJson
class RunTest:
    def __init__(self):
        self.run_method = RunMethod() # 实现get/post方法的类实例
        self.data = GetData() # 获取excel表数据的类实例

    #程序执行的
    def go_on_run(self):
        res = None

        rows_count = self.data.get_case_lines() # case个数
        for i in range(1,rows_count):
            is_run = self.data.get_is_run(i) # 是否run ,excel表中查询
            if is_run:
                url = self.data.get_request_url(i)
                method = self.data.get_request_method(i)
                request_data = self.data.get_data_for_json(i)
                print("request_data:",request_data)
                header = self.data.is_header(i)

                res = self.run_method.run_main(method,url,request_data,header)


            print(res)
            return res

if __name__ == '__main__':
    run = RunTest()
    run.go_on_run()

 8、通过预期结果判断case是否执行成功

 在common_uil.py中新建类:CommonUtil,

 定义 is_contain() 方法,用于判断 预测结果 跟实际结果是否一致 ,若一致 测试通过;如不一致 测试失败

class CommonUtil:
    def is_contain(self,str_one,str_two):
        '''
        判断一个字符串是否在另外一个字符串中
        str_one:查找的字符串
        str_two:被查找的字符串
        '''
        flag = None
        if str_one in str_two:
            flag = True
        else:
            flag = False
        return flag

 

9、将测试结果写入到excel表中 

 1)在operation_excel.py文件的OperationExcel类中添加新方法:write_value() , 用于将数据写入到Excel表中:

    def write_value(self, row, col, value):
        '''
        写入excel数据
        需要值:row,col,value
        '''
        read_data = xlrd.open_workbook(self.file_name) # 打开excel文件
        write_data = copy(read_data)     # 拿到excel内容句柄
        sheet_data = write_data.get_sheet(0)  # 复制文件,让xlutils相关处理
        sheet_data.write(row, col, value)   # 将数据写入到ex文件的指定单元格中
        write_data.save(self.file_name)   # 保存

 

 2)在get_data.py文件中的GetData类,添加write_result() 方法,用于调用 1)中的write_value方法,将数据写入到excel表中:

# 调用excel write方法,将测试结果写入到excel表中
    def write_result(self,row,value):
        col = int(data_config.get_result())
        self.opera_excel.write_value(row,col,value)

 

3)最后在run_test.py中的主程序中,进行判断:预测结果跟实际结果是否一致?一致则测试通过,不一致则测试失败:

 if self.com_util.is_contain(expect,res):
     self.data.write_result(i, 'pass')
 else:
     self.data.write_result(i, 'fail')

 

10、python email :发送邮件

import smtplib
from email.mime.text import MIMEText
from email.header import Header

class SendEmail:
    def __init__(self,receivers = None):
        self.mail_host = "smtp.163.com"  # 设置服务器
        self.mail_user = "13*****657@163.com"  # 用户名
        self.mail_pass = "******"  # 密令/密码

        self.sender = '13******657@163.com'
        if receivers:
            self.receivers = receivers
        else:
            self.receivers = ['8******9@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱

    def email_init(self,content,):
        message = MIMEText(content, _subtype='plain', _charset='utf-8')  # 邮件内容
        subject = '接口自动化测试报告'
        message['Subject'] = Header(subject, 'utf-8')  # 邮件主题
        message['From'] = self.sender  # 发送人,必填,邮箱格式
        message['To'] = ";".join(self.receivers)  # 收件人,必填,邮箱格式

        server = smtplib.SMTP()
        server.connect(self.mail_host, 25)  # 连接服务器
        server.login(self.mail_user, self.mail_pass)  # 登录
        try:
            server.sendmail(self.sender, self.receivers, message.as_string())
            print('发送成功')
        except smtplib.SMTPException as e:
            print("Error: 无法发送邮件")
        server.close()

    def send_email(self,pass_list,fail_list):
        pass_num = float(len(pass_list)) # 成功个数
        fail_num = float(len(fail_list))  # 失败个数
        count_num = pass_num + fail_num  # 总数

        pass_result = "%.2f%%" % (pass_num / count_num * 100)  # 成功率
        fail_result = "%.2f%%" % (fail_num / count_num * 100)  # 失败率
        content = "此次一共运行接口个数为%s个,通过个数为%s个,失败个数为%s,通过率为%s,失败率为%s" %(count_num,pass_num,fail_num,pass_result,fail_result )
        self.email_init(content)

if __name__ == "__main__":
    send_email = SendEmail()
    send_email.send_email([1,3,5,7],[2,4,6])
python email

 

posted on 2018-10-18 02:14  Eric_nan  阅读(699)  评论(0编辑  收藏  举报