首页 > 其他分享 >三.接口自动化项目1

三.接口自动化项目1

时间:2024-03-09 21:14:18浏览次数:25  
标签:case 项目 excel self list 接口 file 自动化 import

一.接口自动化需求分析: 接口自动化测试用例: 1.用例写在excel表格里面,定义函数获取excel表格中数据并加入到用例列表 中进行返回 a.Excel表格中的数据只有url/请求方式、请求参数、headers、是否json、 预期结果才是有效数据 b.请求参数定义格式是"xxx=123,sss>456,phone=<phone>"这种的,需要 转换成字典的形式,并且<phone>需要进行参数化 c.headers请求头需要转换成字典   2.用例读取完成后,需要进行发送请求,需要构造一个请求的函数,请求成功后返 回请求结果json格式和字符串格式的结果     3.拿到请求结果后,需要对预期结果和实际结果进行比对,只要有一条数据不通过 就失败   4.最后进行串联整个流程 a.先读取测试用例文件大,获取所有测试用例excel文件 b.运行测试用例, 先根据excel文件获取到所有测试用例; 再循环测试用例并进行接口请求,获取到接口返回的结果; 然后根据结果返回的实际结果与预期结果进行比较,并把运行总条数、成功数、状态、失败原因放在列表中保存在response_list中; 最后把运行结果写入到excel表格中 c.最后发送接口测试用例运行结果报告邮件   二.进行接口自动化项目程序定义分类: 1.创建一个AutoTestProject文件夹后并在该文件夹下分别创建bin、case、config、lib、logs、report文件夹,bin目录做完程序的入口目录并在下面创建start.py文件;case目录用来存放结果自动化测试用例;config用来存放配置文件及自动化测试用例模板文件;lib文件夹下存放read_case.py、request.py、parse_response.py、utils.py等文件夹;logs文件夹用来存放日志的;report文件夹用来存放测试报告的

 2.在case文件目录下存放测试用例文件,测试用例以test开头和xls或xlsx结尾

 

3.config文件夹下定义配置相关内容及模板文件 setting.py文件
import os
import random
import string

import faker


# 发送邮件
EMAIL_INFO={
    "user":"[email protected]",
    "password":"HLXWWGTUWGNAAAEA",
    "host":"smtp.163.com",
}
# 邮件接收人
T0=["[email protected]"]
# 邮件抄送人
CC=['[email protected]']

# 接口请求url地址配置
host_map={
    "fat":"http://127.0.0.1:8787",
    "uat":"",
    "pro":""
}
default="fat"

HOST=host_map.get(default)

# 自动化项目父目录
BASE_PATH=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 测试用例目录
CASE_PATH=os.path.join(BASE_PATH,'case')
# 日志文件目录
LOG_PATH=os.path.join(BASE_PATH,"logs",'atp.log')
# 测试报告目录
REPORT_PATH=os.path.join(BASE_PATH,'report')

# faker.Faker生成数据进行参数化
f=faker.Faker(locale="zh-CN")

"""
进行参数化的字典,后续有字段数值需要进行参数化的时候只需要在这里进行维护
"""
def getPassword():
    """
    生成随机密码的
    :return:
    """
    a=random.sample(string.digits,2)
    b=random.sample(string.ascii_uppercase,2)
    c=random.sample(string.ascii_lowercase,2)
    d=random.sample("@#$%^&*",2)
    s=a+b+c+d
    # 数据清洗或打乱
    random.shuffle(s)
    return "".join(s)

func_map={
    "<phone>":f.phone_number,
    "<id_card>":f.ssn,
    "<email>":f.email,
    "<name>":f.name,
    "<addr>":f.address,
    "<password>":getPassword
}

import nnlog
LOG=nnlog.Logger(LOG_PATH)
View Code 4.lib文件下定义utils.py进行发邮件、获取字典中的值、写报告功能;read_case.py定义获取用例列表;request.py定义发送请求;parse_response.py定义结果比对 A.utils.py
from xlutils import copy
import os
import random
import string
import time
import traceback

import yagmail

from config.setting import REPORT_PATH,LOG,EMAIL_INFO,T0,CC
import jsonpath
import xlrd


def get_value(d,k):
    # 通过jsonpath.jsonpath来取字典中key所对应的值
    result=jsonpath.jsonpath(d,'$..%s'%k)
    # 如果取到了返回第一个值,否则返回空字符串
    if result:
        return result[0]
    return ''

"""
result_list=[
    [{"code":0,"msg":"成功"},"通过"],
    [{"code":0,"msg":"成功"},"失败"],
]
"""

def write_excel(file_name,result_list):

    """
    result_list存放用例执行结果["参数","执行结果","原因","状态"]
    :param file_name:
    :param result_list:
    :return:
    """
    LOG.debug("现在开始写报告了:文件名是%s,内容是%s"%(file_name,result_list))
    book=xlrd.open_workbook(file_name)
    newbook=copy.copy(book)
    try:
        sheet=newbook.get_sheet(0)
    except Exception as e:
        print("无法打开excel=============",file_name)
    for row,result in enumerate(result_list,1):
        for col ,value in enumerate(result[1:],7):
            sheet.write(row,col,value)
        sheet.write(row,3,result[0])
    file_name=os.path.split(file_name)[-1].replace("xlsx","xls")
    new_file_name=time.strftime("%Y%m%d%H%M%S")+"_"+file_name
    case_file=os.path.join(REPORT_PATH,new_file_name)
    newbook.save(case_file)
    LOG.debug("报告生成完成,文件名是%s"%(case_file))
    return case_file


def send_email(all_count,pass_count,file_name):
    LOG.debug("开始发送报告了,文件名是%s"%file_name)
    content='''
各位好:
    本次接口自动化测试结果如下,总共运行%s条用例,通过%s条,失败【%s】条。
    详情请查看附件。
    '''%(all_count,pass_count,(all_count-pass_count))

    subject='%s-接口测试报告'%time.strftime("%Y-%m-%d %H%M%S")

    email=yagmail.SMTP(**EMAIL_INFO,encoding="GBK")

    try:
        email.send(to=T0,cc=CC,subject=subject,contents=content,attachments=file_name)
    except Exception as e:
        LOG.error("发送报告失败,具体失败原因是%s"%traceback.format_exc())
    else:
        LOG.debug("报告发送成功")
View Code B.read_case.py
import nnlog
import traceback
import xlrd
from config.setting import LOG_PATH,func_map
import jsonpath

log=nnlog.Logger(LOG_PATH)

# "$..key"是进行模糊查询
# jsonpath.jsonpath(d,"$..key")
# faker模板的使用

class ParamDeal():

    def read_excel(self,file_path):
        # case_list存放测试用例
        case_list=[]
        try:
            # 打开excel
            book=xlrd.open_workbook(file_path)
            sheet=book.sheet_by_index(0)
            # 从
            for row in range(1,sheet.nrows):
                # 只取有用的那几行
                line=sheet.row_values(row)[1:7]

                # 把参数先进行替换
                line[2]=self.replace_param(line[2])

                # 将header转换成字典
                line[3]=self.replace_param(line[3])
                # 再把参数进行转换成字典
                line[2]=self.str_to_dict(line[2])

                line[3]=self.str_to_dict(line[3])
                case_list.append(line)
        except Exception as e:
            log.error("读取文件出错,文件名是:%s"%file_path)
            log.error("具体的错误信息是%s"%traceback.format_exc())
        return case_list

    def replace_param(self,s):
        """
        进行参数替换
        :param s:
        :return:
        """
        for func_name,func in func_map.items():
            if func_name in s:
                result=func()
                s=s.replace(func_name,result)
        return s

    def str_to_dict(self,s):
        """
        字符串转换成字典,如果是空字符串直接返回空字典
        :param s:
        :return:
        """
        d={}
        # 判断参数是否为空
        if s.strip():
            # 字符串通过逗号进行分割后通过等号进行分割后再转换成字典
            for i in s.split(","):
                k,v=i.split("=")
                d[k]=v
        return d
View Code

C.request.py

import traceback

import requests
from config import setting
from urllib.parse import  urljoin
import nnlog


log=nnlog.Logger(setting.LOG_PATH)
class MyRequest:
    def __init__(self,url,method,data=None,headers=None,is_json='否'):
        # 拼接url,通过urljoin进行拼装url
        self.url=urljoin(setting.HOST,url)
        self.data=data
        self.headers=headers
        self.is_json=is_json
        self.method=method.lower()
        self.req()

    def req(self):
        try:
            if self.is_json=='是':
                response= requests.request(self.method,self.url,params=self.data,json=self.data,headers=self.headers).json()
            else:
                response= requests.request(self.method,self.url,params=self.data,data=self.data,headers=self.headers).json()
        except Exception as e:
            log.error("请求%s的时候出错了,请求参数是%s,错误信息是%s"%(self.url,self.data,traceback.format_exc()))
            self.result={"msg":"请求接口出错了","error_msg":traceback.format_exc()}
            self.text='{"msg":"请求接口出错了","error_msg":%s}'%(traceback.format_exc())
        else:
            self.result=response
            self.text=str(response)
View Code

D.parse_response.py

from lib.utils import get_value
from config.setting import LOG_PATH
import nnlog

log=nnlog.Logger(LOG_PATH)

class ParseResponse:

    fuhao=['!=','>=','<=','>','<','=']

    def __init__(self,check_str,response):
        self.check_str=check_str
        self.response=response
        self.reason="都通过了"
        self.status='通过'
        self.check_response()

    def check_response(self):
        """
        预期结果格式是:yuqijieguo="status=1,score>60,age!=15"
        :return:
        """
        if self.check_str.strip():
            for s in self.check_str.split(","):
                for f in self.fuhao:
                    if f in s:
                        # 分割取出预期结果中的key
                        key, value = s.split(f)
                        # 取到实际结果
                        shijijieguo = get_value(self.response, key)
                        # 如果是实际结果类型是字符串的话,实际结果和预期结果都转换成字符串进行比较
                        if type(shijijieguo) == str:
                            shijijieguo = "'%s'" % (shijijieguo)
                            value = "'%s'" % (value)

                        # 转换成字符串进行eval运行
                        f = "==" if f == "=" else f
                        code = "%s %s %s" % (shijijieguo, f, value)
                        tag=eval(code)
                        # 判断tag不是true时表示有预期结果与实际结果对比是失败的
                        if tag!=True:
                            self.reason='key是%s,运算的代码是%s'%(key,code)
                            log.debug(self.reason)
                            self.status='失败'
                            return False
                        break
        return True
View Code 5.bin文件下定义start.py文件是程序主入口;duoxiancheng.py是文件程序多线程运行入口 A. start.py
#! /usr/bin python
#-*- encoding=utf-8 -*-

from lib.read_case import ParamDeal
from lib.request import MyRequest
from lib.parse_response import get_value,ParseResponse
from lib.utils import send_email,write_excel
import os
from config.setting import CASE_PATH


class CaseRun:
    all_count=0
    pass_count=0
    def get_case(self):
        # 获取excel测试用例文件
        excel_list=[]
        for file in os.listdir(CASE_PATH):
            if file.startswith("test") and (file.endswith('.xls') or file.endswith(".xlsx")):
                abs_path = os.path.join(CASE_PATH, file)
                excel_list.append(abs_path)
        return excel_list

    def run_case(self,file_name):
        read_case_obj=ParamDeal()
        # 根据excel文件获取其中的测试用例
        case_list=read_case_obj.read_excel(file_name)

        # response_list用于存放所有的结果
        response_list=[]

        # 循环用例列表进行发送请求
        for case in case_list:
            # 统计用例的总个数,循环一次,用例加一条
            self.all_count+=1
            # 发送接口请求
            req_obj=MyRequest(*case[:5])

            # 校验结果

            response_obj=ParseResponse(case[-1],req_obj.result)

            if response_obj.status=='通过':
                # 统计用例执行个数
                self.pass_count+=1
            response_list.append([str(req_obj.data),req_obj.text,response_obj.status,response_obj.reason])
        return  write_excel(file_name,response_list)



    def main(self):
        report_list=[]
        excel_list=self.get_case()
        for excel in excel_list:
            report_name=self.run_case(excel)
            report_list.append(report_name)

        send_email(self.all_count,self.pass_count,report_list)

if __name__=="__main__":
    c=CaseRun()
    c.main()
View Code

B. duoxiancheng.py

import os,sys
sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from lib.read_case import ParamDeal
from lib.request import MyRequest
from lib.parse_response import get_value,ParseResponse
from lib.utils import send_email,write_excel

from config.setting import CASE_PATH
import threading

class CaseRun:
    all_count=0
    pass_count=0
    report_list = []
    def get_case(self):
        # 获取excel测试用例文件
        excel_list=[]
        for file in os.listdir(CASE_PATH):
            if file.startswith("test") and (file.endswith('.xls') or file.endswith(".xlsx")):
                abs_path = os.path.join(CASE_PATH, file)
                excel_list.append(abs_path)
        return excel_list

    def run_case(self,file_name):
        read_case_obj=ParamDeal()
        # 根据excel文件获取其中的测试用例
        case_list=read_case_obj.read_excel(file_name)
        # response_list用于存放所有的结果
        response_list=[]

        # 循环用例列表进行发送请求
        for case in case_list:
            # 统计用例的总个数,循环一次,用例加一条
            self.all_count+=1
            # 发送接口请求
            req_obj=MyRequest(*case[:5])
            # 校验结果
            response_obj=ParseResponse(case[-1],req_obj.result)

            if response_obj.status=='通过':
                # 统计用例执行个数
                self.pass_count+=1
            response_list.append([str(req_obj.data),req_obj.text,response_obj.status,response_obj.reason])
        report_name=  write_excel(file_name,response_list)
        self.report_list.append(report_name)



    def main(self):
        """
        启动多线程运行
        :return:
        """
        excel_list=self.get_case()
        for excel in excel_list:
            t=threading.Thread(target=self.run_case,args=(excel,))
            t.start()
        while threading.active_count()!=1:
            pass

        send_email(self.all_count,self.pass_count,self.report_list)

if __name__ == '__main__':
    c=CaseRun()
    c.main()
View Code

 

标签:case,项目,excel,self,list,接口,file,自动化,import
From: https://www.cnblogs.com/zongchen/p/18063300

相关文章

  • 一.postman进行接口测试
    1.先进行接口调试并进行参数 2.进行添加接口预期结果校验 3.进行保存接口 4.启动runner  5.执行接口用例 6.查看执行结果 ......
  • 搭建一个Java项目可直接拿去使用的通用工具类
    1、通用枚举类importlombok.Getter;/***@Description状态码定义约束,共6位数,前三位代表服务,后3位代表接口*比如商品服务210,购物车是220、用户服务230,403代表权限**/publicenumBizCodeEnum{/***短链分组*/GROUP_REPEAT(23001,"分组名......
  • 下载Project 2021专业版项目管理软件
    Project2021专业版是微软公司推出的一款功能强大的项目管理软件,可以帮助用户有效地规划、执行和控制项目。主要功能:项目计划:Project2021专业版可以帮助用户创建详细的项目计划,包括任务列表、时间表、资源分配等。资源管理:Project2021专业版可以帮助用户有效地管......
  • java8特性-函数式接口
    什么是函数式接口?只包含一个抽象方法的接口,称为函数式接口检验方法:  Java内置的4大核心函数式接口消费型接口Consumer<T>voidaccept(Tt)供给型接口Supplier<T>Tget()函数型接口Function(T,R)Rapply(Tt)断定型接口Predicate<T>booleantest(Tt)......
  • delphi 判断类是否实现接口,获取类实现的接口
    判断类是否实现接口,获取类实现的接口代码typeICeShi=interface['{37CABB9D-CAA2-4589-A0C8-5AA1424E525B}']functionToPrint:string;end;TCeShi=class(TInterfacedObject,ICeShi)functionToPrint:string;end;procedureTForm1.Button1Cli......
  • Linux/macOS 查看网络接口
    Linux$nmclidevicestatusDEVICETYPESTATECONNECTIONenp0s5ethernetconnectedWiredconnection1docker0bridgeconnected(externally)docker0loloopbackunmanaged......
  • python+pytest接口自动化之测试函数、测试类/测试方法的封装
    前言今天呢,笔者想和大家聊聊python+pytest接口自动化中将代码进行封装,只有将测试代码进行封装,才能被测试框架识别执行。例如单个接口的请求代码如下:importrequestsheaders={"user-agent":"Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,l......
  • 如何从0开始做自动化测试?
    自动化测试是使用软件工具在应用程序上自动运行测试的过程,无需任何人为干预。这可以通过减少手动测试的需要来保存时间并提高软件开发过程的效率。由于人为错误或不一致性,手动测试可能容易出错,这可能导致错误未被检测到。自动化测试通过提供一致和可靠的方法来测试应用程序,从而消......
  • app自动化测试环境安装和原理解析
    1.移动测试的基本介绍定义:测试手机程序:appApp程序测试点:功能测试安装卸载测试升级测试兼容性测试不同的手机的系统使用测试环境不同androidios其他:基于Android二次开发系统华为:鸿蒙系统小米:澎湃系统网络切换网络终端使用中来电,短信横竖屏切换健壮性......
  • 淘宝订单AP I淘宝订单数据接口 获取商品订单列表 获取商品订单详情
    淘宝订单API是淘宝开放平台提供的一组接口,允许开发者获取淘宝或天猫的订单数据,包括订单列表和订单详情。要使用这些API,你需要遵循一定的步骤来获取并接入这些接口。以下是获取淘宝订单数据的基本步骤:注册并创建应用首先,你需要在淘宝开放平台注册账号,并创建一个应用。创建应用......