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

一.自动化框架

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

二.做自动框架步骤:

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_countcontent = 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,get,data,check]]self.success_count = 0results = []for case in cases:url,method,param,check = case #获取到每条用例的参数p = parse_param.ParseParam(param) #解析请求参数data = p.strToDict()#请求参数转成字典response = case_operation.send_request(url,method,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,get,data,check],[url,get,data,check]]return all_casedef send_request(url,method,data,headers=None):req = MyRequest(url,data,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':'xxxx@qq.com','password':'sdfsdf','host':'smtp.qq.com','smtp_ssl':True,#发件箱是qq邮箱的话,改成True
}TO = ['511402865@qq.com','496647026@qq.com','649623416@qq.com','ray-zuo@qq.com']

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 = urlself.data = dataself.headers = headersself.file = filedef 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代表返回的jsonexcept Exception as e:res = {"staus":2,"data":req.text} #2代表返回不是jsonlog_str = 'url: %s 请求方式:post  data:%s ,返回数据:%s'%(self.url,self.data,res)self.write_log(log_str)return resdef get(self):try:req = requests.get(self.url,params=self.data,headers=self.headers,timeout=self.time_out)except Exception as e:res = {"status":0,"data":e.args}  #0代表请求失败else:try:res = {"status":1,"data":req.json()} #1代表返回的jsonexcept Exception as e:res = {"staus":2,"data":req.text} #2代表返回不是jsonlog_str = 'url: %s get请求 data:%s ,返回数据:%s'%(self.url,self.data,res)self.write_log(log_str)return res@classmethoddef 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 = paramself.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 resdef 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 410881199011212121def cur_time(self):return int(time.time())def order_id(self):#从数据库里面获取passdef session_id(self):#从redis里面获取的passdef 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 = tempdata[key] = valuereturn dataif __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 = responseself.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)breakreturn format_list#1.检查点解析完成def get_real_value(self,key):#从字典里面获取key对应的valueres = jsonpath.jsonpath(self.response,'$..%s'%key)#$..%s这个是jsonpath这个模块的用法if res:return res[0]return '找不到该key【%s】'%key#2.取得实际的值def operation_check(self,real,seq,hope):#根据运算符判断结果(实际结果,运算符,预期结果)msg = "判断信息:%s %s %s "%(real,seq,hope)real = str(real)#为了保持类型一致if seq=='=':status = real == hopeelif seq=='!=':status = real != hopeelif seq =='in':status = real in hopeelif seq =='notin':status = real not in hopeelse:status,msg = self.num_check(real,seq,hope)return status,msgdef num_check(self,real,seq,hope):#判断数值类型的msg = "判断信息:%s %s %s "%(real,seq,hope)try:real=float(real)hope=float(hope)except Exception as e:msg = "比较时出错,大小比较只能是数字类型!" \"%s %s %s"%(real,seq,hope)status = Falseelse:if seq=='>':status = real > hopeelif seq =='<':status = real < hopeelif seq == '<=':status  = real <= hopeelse:status = real >= hopereturn status,msgdef check_res(self):#校验所有的检查点check_list = self.format_check()all_msg=''for check in check_list:#循环所有的检查点key,seq,hope = checkreal = self.get_real_value(key)status,msg = self.operation_check(real,seq,hope)all_msg = all_msg+msg+'\n' #累加提示信息if status:passelse:return '失败',all_msgreturn '通过',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/测试用例.xlsabs_path = os.path.join(setting.REPORT_PATH,today)#拼成当天的绝对路径if os.path.exists(abs_path):passelse: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 = ressheet.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] #只获取到filenamecur_time = datetime.datetime.today().strftime('%H%M%S') #获取到当天时分秒new_file_name = cur_time+'_'+file_name #165530_测试用例.xlsreal_path = os.path.join(cur_date_dir,new_file_name)#拼路径
    new_book.save(real_path)return real_pathdef 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

转载于:https://www.cnblogs.com/test49355--/p/11221537.html

python 简单的接口测试框架相关推荐

  1. python简单的接口测试实例

    L 本篇文章给大家讲解下用python实现接口测试,结合unitest测试框架,下面给大家讲一下简单的接口测试实例! 一.大致的思路是如此,画了下思维导图,大家可以看下: 二.下面应用两个比较常用的h ...

  2. 搭一个简单的接口测试框架

    一.自动化框架 可以理解为工具的集合,把日常所需要实现功能的代码,模块进行封装起来结合其他的工具进行测试.得出结论报告. 二.做自动框架步骤: 1.读取excel 获取用例, 2.解析用例 3.解析返 ...

  3. Python简单的接口测试

    1:发送get请求 import requests,json url = 'http://www.baidu.com' req=requests.get(url)#发送get请求 print(req. ...

  4. python接口测试框架实战与自动化进阶(三)

    python接口测试框架实战与自动化进阶 一.持续集成 1.持续集成环境搭建 1)安装Jenkins 官网下载后直接安装:https://jenkins.io/ 终端直接安装及启动:java -jar ...

  5. python数据接口设计_基于python的接口测试框架设计(一)连接数据库

    基于python的接口测试框架设计(一)连接数据库 首先是连接数据库的操作,最好是单独写在一个模块里, 然后便于方便的调用,基于把connection连接放在__init__()方法里 然后分别定义D ...

  6. 三百行python代码的项目_300行Python代码打造实用接口测试框架

    在刚开始实现ApiTestEngine的时候,卡斯(kasi)提议做一个Java版的.对于这样的建议,我当然是拒绝的,瞬即回复了他,"人生苦短,回头是岸啊". 当然,我没好意思跟他 ...

  7. python接口测试框架选择之pytest+yaml+Allure

    前言 2021年,部门的测试组尝试着用jmeter做简单的接口测试,使用工具就需要遵守工具的很多规则,并且jmeter对需要写辅助测试代码的场景不友好.2022年,改为用python写接口测试.在经过 ...

  8. 震惊!python类型的自动化测试框架原来这么简单!

    我是黄财财,励志成为打拳届最会测试的大肚腩少年的我,和哈皮群友聊了一天,发现很多群友不知道从什么方向去做自动化软件测试,所以大致写了这篇文章,希望对大家有所帮助. 大家如果想和我的哈皮群友讨论怎么学p ...

  9. python:web后台框架简单实现

    python:web后台框架 目录 简介:BS开发和http协议 WSGI概述 类flask框架简单实现 response使用及wsgify装饰器 路由 模板原理 jinjia2模板技术 模块化,ja ...

  10. python协程框架_[记录]python的简单协程框架(回调+时间循环+select)

    # -*- coding: utf-8 -*- # @Time : 2018/12/15 18:55 # @File : coroutine.py #一个简单的 Coroutine 框架 import ...

最新文章

  1. 【Python培训基础知识】单例模式
  2. 全面梳理百度世界大会:量产L4乘用车和两款音箱 还有挖掘机技术
  3. 日历控件的android代码,Android日历控件PickTime代码实例
  4. 6.6.1 CPropertySheet类
  5. mysql数据库使用命令导入sql文件
  6. hosts多个ip对应一个主机名_一个简单的Web应用程序,用作连接到ssh服务器的ssh客户端...
  7. 二叉排序树的删除+图解
  8. [NOI2019]回家路线
  9. (操作系统题目题型总结)第五章:设备管理
  10. 基于分位数回归的动态CoVaR计算 案例与代码
  11. pythonmain是什么_Python - __name__=='__main__'是干啥的,以及python -m与python的区别
  12. oracle的成本核算,Oracle11gR2全表扫描成本计算(工作量模式-workload)
  13. Linux系统下挂载Windows分区的方法和技巧
  14. 这本记述40年前历史的游戏书,预言的却是当下的事
  15. 1_11_4 23 python基础学习
  16. 只用一个div画一个小米logo
  17. Java循环控制语句
  18. 每日格言积累及总结——更新中
  19. 全国OSTA计算机高新技术SQLSever数据库四级证书--考证复习知识点集合(附下载地址)
  20. Important Programming Concepts (Even on Embedded Systems) Part V: State Machines

热门文章

  1. c语言闰年题目程序,浙大版《C语言程序设计(第3版)》题目集 练习3-5 输出闰年...
  2. era5数据内容说明_接口测试:A04_HttpRunner通用_02_提取数据_01_extract关键字
  3. 查看docker run启动参数命令 runlike
  4. 陕西一本大学计算机专业排名2015,陕西计算机专业大学排名
  5. 基于Java的在线购书系统
  6. 图(一):图的邻接表表示
  7. Java实现斐波那契数列的两种方法
  8. 设计模式之GOF23备忘录模式
  9. mysql查看表注释和字段注释
  10. JDBC学习(四、DAO思想和重构设计上)