加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python 简单的接口测试框架

发布时间:2020-12-20 12:58:39 所属栏目:Python 来源:网络整理
导读:?什么是自动化 :就是写代码帮你测试,原来你测试都是手动点点点,现在你写代码来帮你点点点。 一.自动化框架 可以理解为工具的集合,把日常所需要实现功能的代码,模块进行封装起来结合其他的工具进行测试。得出结论报告。 二.做自动框架步骤: 1.读取excel

?什么是自动化:就是写代码帮你测试,原来你测试都是手动点点点,现在你写代码来帮你点点点。

一.自动化框架

可以理解为工具的集合,把日常所需要实现功能的代码,模块进行封装起来结合其他的工具进行测试。得出结论报告。

二.做自动框架步骤:

1.读取excel 获取用例,

2.解析用例

3.解析返回结果进行对比,检查是否通过还是失败

4.把返回的结果写入excel

5.生成报告,发邮件

三.搭建自动化框架

框架目录结构

?

excel用例表格:

import os,sys
BAE_PATH  = os.path.dirname(
os.path.dirname(os.path.abspath(__file__))
) #atp的目录
sys.path.insert(0,BAE_PATH)
from conf.setting import CASE_PATH
from core import case_operation,parse_param,parse_response
from core import tools
import glob
#glob文件路径查询
class RunCase:
    content = ‘‘‘
    各位好!
        本次测试结果:总共运行%s条用例,通过%s条,失败%s条。详细信息见附件。
    ‘‘‘
    def get_excel(self):
        #s=‘/Users/nhy/test*.xls‘
        for excel in glob.glob(os.path.join(CASE_PATH,test*.xls)):
            cases = case_operation.get_case(excel)#调用读取excel的函数
            results = self.send_requests(cases) #发送请求,并校验结果
            report_file_path = tools.write_res(excel,results)#写入结果
            all_count = len(cases) #总共多条用例
            fail_count = all_count - self.success_count
            content = self.content%(all_count,self.success_count,fail_count)
            tools.send_mail(content,report_file_path)
    def send_requests(self,cases):
        #    #[[url,get,data,check],[url,check]]
        self.success_count = 0
        results = []
        for case in cases:
            url,method,param,check = case #获取到每条用例的参数
            p = parse_param.ParseParam(param) #解析请求参数
            data = p.strToDict()#请求参数转成字典
            response = case_operation.send_request(url,data)#发请求
            #下面这2行代码是判断用例执行是否通过的
            p2 = parse_response.ResponseParse(response,check)
            status,msg = p2.check_res()#调用写好的校验结果方法,
            real_res = str(response)+n+msg #是把校验的信息和返回的json拼到一起
            results.append([real_res,status]) #这里面的小list是每一个用例运行的结果
            if status == 通过:
                self.success_count += 1 #统计成功的次数
        return results #返回运行的结果

    def main(self):
        print(开始测试.center(50,*))
        self.get_excel()
        print(测试结束.center(50,*))

if __name__ == __main__:
    run = RunCase()
    run.main()
start (程序入口)

用例读取,判断请求方式

import xlrd
from core.my_requests import MyRequest
def get_case(path):
    ‘‘‘
    :param path: excel测试用例
    :return: 二维数组,每一个里面是一条测试用例
    ‘‘‘
    all_case = []
    book = xlrd.open_workbook(path)
    sheet = book.sheet_by_index(0)
    for i in range(1,sheet.nrows):
        row_data = sheet.row_values(i)[4:8]
        all_case.append(row_data)
    #[[url,check]]
    return all_case

def send_request(url,headers=None):
    req = MyRequest(url,headers=headers)
    if method.upper()=="POST":
        res = req.post()
    elif method.upper() ==GET:
        res = req.get()
    else:
        res = {"data":"暂时不支持该方法!"}
    return res[data]
case_operation(用例读取)

文件配置

import requests
import nnlog
from conf.setting import LOG_PATH
import os
BAE_PATH  = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #atp的目录

LOG_PATH = os.path.join(BAE_PATH,logs) #log目录
CASE_PATH = os.path.join(BAE_PATH,cases) #case目录
REPORT_PATH = os.path.join(BAE_PATH,report) #report目录
CORE_PATH = os.path.join(BAE_PATH,core) #core目录
MAIL_INFO = {
    user:[email?protected],password:sdfsdf,host:smtp.qq.com,smtp_ssl:True,#发件箱是qq邮箱的话,改成True
}

TO = [[email?protected],[email?protected],[email?protected],[email?protected]]
setting

URL获取参数进行解析

import requests
import nnlog
import os
from conf.setting import LOG_PATH
class MyRequest:
    log_file_name  = os.path.join(LOG_PATH,MyRequest.log)#日子文件名
    time_out = 10 #请求超时时间
    def __init__(self,url,data=None,headers=None,file=None):
        self.url = url
        self.data = data
        self.headers = headers
        self.file = file
    def post(self):
        try:
            req = requests.post(self.url,data=self.data,headers=self.headers,files=self.file,timeout=self.time_out)
        except Exception as e:
            res = {"status":0,"data":e.args}  #0代表请求失败
        else:
            try:
               res = {"status":1,"data":req.json()} #1代表返回的json
            except Exception as e:
                res = {"staus":2,"data":req.text} #2代表返回不是json
        log_str = url: %s 请求方式:post  data:%s,返回数据:%s%(self.url,self.data,res)
        self.write_log(log_str)
        return res
    def get(self):
        try:
            req = requests.get(self.url,params=self.data,headers=self.headers,"data":req.json()} #1代表返回的json

            except Exception as e:
                res = {"staus":2,"data":req.text} #2代表返回不是json
        log_str = url: %s get请求 data:%s,res)
        self.write_log(log_str)
        return res

    @classmethod
    def write_log(cls,content):
        log = nnlog.Logger(cls.log_file_name)
        log.debug(content)
my_requests

?解析请求数据

import random
import string
import time
class ParseParam:
    #这个类是用来解析请求参数的
    func_map = [phone,email,id_card,cur_time,money]
    #映射函数的
    def __init__(self,param):
        self.param = param
        self.parse()
    def phone(self):
        phone_starts = [134,181,138,177,150,132,188,186,189,130,170,153,155]
        start = random.choice(phone_starts)
        end = str(random.randint(0,99999999))
        res = start+ end.zfill(8)
        return res
    def email(self):
        email_end=[163.com,qq.com,126.com,sina.com]
        end = random.choice(email_end)
        start_str=ATP_test_
        email_start = ‘‘.join(random.sample(string.ascii_letters+string.digits,6))
        return start_str+email_start+@+end
    ‘‘‘def id_card(self):
        #这个产生身份证号的
        return 410881199011212121
    def cur_time(self):
        return int(time.time())
    def order_id(self):
        #从数据库里面获取
        pass
    def session_id(self):
        #从redis里面获取的
        pass
    def money(self):
        return 10000
    ‘‘‘
    def parse(self):
        for func in self.func_map:
            temp = str(getattr(self,func)()) #手机号
            self.param = self.param.replace(<%s>%func,temp)
    def strToDict(self):
        #这个函数是把请求参数转成字典的
        data ={}
        pl = self.param.split(,)
        for p in pl:
            temp = p.split(=)
            if len(temp)>1:
                key,value = temp
                data[key] = value
        return data

if __name__ == __main__:
    param = username=niuhanyang             ,phone=<phone>,email=<email>             ,id_card=<id_card>,start_time=             <cur_time>,balan=<money>
    p = ParseParam(param)
    data = p.strToDict()
    print(data)
‘‘‘print(p.phone())
    # res = getattr(p,‘money‘) #获取一个对象里面的属性(方法、变量)


    # # print(res())
    # import os,requests
    # res = hasattr(requests,‘get‘)#判断某个模块、类下面有没有某个方法或者变量
    # print(res)
用例的支持参数化,支持以下参数化:
<phone>   自动产生手机号
<id_card>  身份证号
<email>    邮箱
<cur_time>  当前时间戳
‘‘‘
parse_param

校验检查点

import jsonpath
class ResponseParse:
    seqs = [!=,>=,<=,=,<,>,in,notin]
    #定义支持的运算符
    def __init__(self,response,check):
        self.response = response
        self.check = check
    #进行解析 校验结果,预期结果
    def format_check(self):
        #格式化检查信息,分别列出key 运算符 实际结果
        #会返回 [[‘error_code‘,‘=‘,‘0‘],[‘name‘,‘!=‘,‘xxx‘]]
        format_list = []
        check_list = self.check.split(,)
        for s in check_list:
            for seq in self.seqs:
                if seq in s:
                    if len(s.split(seq))>1:
                        key,value = s.split(seq)
                        temp = [key,seq,value]
                        format_list.append(temp)
                        break
        return format_list
    #1.检查点解析完成

    def get_real_value(self,key):
        #从字典里面获取key对应的value
        res = jsonpath.jsonpath(self.response,$..%s%key)
        #$..%s这个是jsonpath这个模块的用法
        if res:
            return res[0]
        return 找不到该key【%s】%key
    #2.取得实际的值

    def operation_check(self,real,hope):
        #根据运算符判断结果(实际结果,运算符,预期结果)
        msg = "判断信息:%s %s %s "%(real,hope)
        real = str(real)#为了保持类型一致
        if seq===:
            status = real == hope
        elif seq==!=:
            status = real != hope
        elif seq ==in:
            status = real in hope
        elif seq ==notin:
            status = real not in hope
        else:
            status,msg = self.num_check(real,hope)
        return status,msg

    def num_check(self,hope):
        #判断数值类型的
        msg = "判断信息:%s %s %s "%(real,hope)
        try:
            real=float(real)
            hope=float(hope)
        except Exception as e:
            msg = "比较时出错,大小比较只能是数字类型!"                   "%s %s %s"%(real,hope)
            status = False
        else:
            if seq==>:
                status = real > hope
            elif seq ==<:
                status = real < hope
            elif seq == <=:
                status  = real <= hope
            else:
                status = real >= hope
        return status,msg

    def check_res(self):
        #校验所有的检查点
        check_list = self.format_check()
        all_msg=‘‘
        for check in check_list:#循环所有的检查点
            key,hope = check
            real = self.get_real_value(key)
            status,msg = self.operation_check(real,hope)
            all_msg = all_msg+msg+n #累加提示信息
            if status:
                pass
            else:
                return 失败,all_msg
        return 通过,all_msg
parse_response

产生excel文件写入校验结果

import xlrd
from xlutils.copy import copy
import os
import datetime
from conf import setting
import yagmail
def make_today_dir():
    #创建当天的文件夹,返回绝对路径
    today = str(datetime.date.today())
    #c:/xxx/xxx/atp/report/2018-11-24/测试用例.xls
    abs_path = os.path.join(setting.REPORT_PATH,today)
    #拼成当天的绝对路径
    if os.path.exists(abs_path):
        pass
    else:
        os.mkdir(abs_path)

    return abs_path
def write_res(case_path,case_res):
    #c:/xxx/xxx/atp/cases/测试用例.xls
    #[ [‘{"xdfsdf}‘,‘通过‘],[‘{"xdfsdf}‘,‘失败‘] ]
    book = xlrd.open_workbook(case_path)
    new_book = copy(book)
    sheet = new_book.get_sheet(0)
    for row,res in enumerate(case_res,1):
        response,status = res
        sheet.write(row,8,response)
        sheet.write(row,9,status)
        #写第8列和第9列
    cur_date_dir = make_today_dir()#创建当前文件夹,并且返回绝对路径
    file_name = os.path.split(case_path)[-1] #只获取到filename
    cur_time = datetime.datetime.today().strftime(%H%M%S) #获取到当天时分秒
    new_file_name = cur_time+_+file_name #165530_测试用例.xls
    real_path = os.path.join(cur_date_dir,new_file_name)#拼路径
    new_book.save(real_path)
    return real_path

def send_mail(content,file_path=None):
    #发邮件,传入邮件正文和附件
    m = yagmail.SMTP(**setting.MAIL_INFO,)
    subject = 接口测试报告_%s%str(datetime.datetime.today())
    m.send(subject=subject,to=setting.TO,contents=content,attachments=file_path)
tools

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读