utp
接口测试大致分为两种:数据驱动和代码驱动
数据驱动:主要处理用例之间没有关联关系的用例集合,一般以(excel、yaml)文件形式存储用例
代码驱动:主要是处理用例之间存在关联关系的用例(如:抽奖,需要登录后才能操作,这里就需要先执行登录的用例获取登录的cookies再执行抽奖操作),一般以代码的形式存在
数据驱动代码如下:
搭建UTP自动化测试框架的步骤:
1.构建用例login.yaml

2.设计自动化测试用例模板
1.定义测试类(集成测试框架unittest.TestCase模块)使用unittest搭建测试用例集合
import ddt
@ddt.ddt  
class Login(unittest.TestCase):
            @ddt.data(r'login.yaml')#将用例中的数据放入data函数,ddt模块将输入传入datas变量中
            @ddt.unpack   #负责将login.yaml文件中的数据分组拆解到datas变量中
            def test_login(self,**datas):#字典类型的数据必须用**修饰变量名datas
                url = datas.get('url')#通过get方法获取参数url
                method = datas.get('method')
  check = datas.get('check')
                if str(method).upper()=='POST':
                    res = request.post(url,json=data).text
                else :
                    res = request.get(url,params=data).text
                #校验返回值对不对
     self.asserIn(check,res,msg='验证失败')
3.创建create_case()来根据测试用例模板生成测试用例脚本,存放到cases下面
4.创建run_all_case()执行所有用例脚本,并生成测试报告,返回测试报告信息
filename(用例文件名),successCount(用例通过条数),failCount(用例失败条数)
5.创建send_mail()来实现邮箱发送测试报告给领导
程序目录结构:

1.在data目录下新建yaml格式的测试数据:

2. 在conf下面用例脚本模板case_template.txt,具体内容如下:
#该用例模板是根据一个测试用例编写并测试通过的脚本改编而来,原理:通过给模板传入 类名,用例.yaml文件地址这两个参数生成具体的用例脚本文件(.py)
#-*-coding:utf-8-*-
import  unittest,ddt
import requests
@ddt.ddt
class %s(unittest.TestCase):
    @ddt.file_data(r'%s')
    @ddt.unpack
    def test_request(self,**datas):
        #获取所有参数
        url = datas.get('url')
        method = datas.get('method')
        isJSON = datas.get('isJson')
        detail = datas.get('detail','没有接口描述')
        data = datas.get('data',{})
        check = datas.get('check')
        headers = datas.get('headers',{})
        if str(method).upper() =='POST':
            if isJSON:
                res = requests.post(url=url,json=data,headers=headers).text
            else:
                res = requests.post(url=url, data=data, headers=headers).text
        elif str(method).upper() =='GET':
            res = requests.get(url=url, params=data, headers=headers).text
        for c in check:
            self.assertIn(c,res,c+'不在'+res+'里面')
3. 在conf/setting.py里面填写基础信息
#-*-coding:utf-8-*-
import os,nnlog
#根目录
BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
#用例脚本目录
CASE_PATH = os.path.join(BASE_PATH,'cases')
#用例脚本模板
CASE_TEMPLATE = os.path.join(BASE_PATH,'conf','case_template')
#测试用例数据存放目录
DATA_PATH = os.path.join(BASE_PATH,'data')
#测试报告存放目录
REPORT_PATH = os.path.join(BASE_PATH,'report')
#日志:记录程序进程信息
log = nnlog.Logger(os.path.join(BASE_PATH,'logs','utp.log'))
#邮箱信息
MAIL = {
    'user':'u****@163.com',
    'password':'*****',
    'host':'smtp.163.com'
}
TO =['10******3@qq.com']#收件人
CC =['10******3@qq.com']#抄送人
4.在lib/tools.py里面创建crete_py(),run_all_case(),send_mail()方法分别处理创建用例脚本、执行用例脚本、发送邮件。
#-*-coding:utf-8-*-
import time,yagmail
from conf import setting
from conf.setting import log
import  glob,os,unittest,BeautifulReport as br
def create_py():
    with open(setting.CASE_TEMPLATE,'r+',encoding='utf-8') as fr :
        #log.info("开始读取用例脚本模板。。。")
        #1.读取模板中的所有内容
        src_content = fr.read()
        #2.获取用例名,并作为测试的类名,和脚本的文件名:class Login:  login.py
        all_yaml = glob.glob(setting.DATA_PATH + os.sep+'*.yaml')
        if all_yaml:
            for file in all_yaml:
                class_name = str(os.path.split(file)[-1]).replace('.yaml','').title()
                py_content = src_content % (class_name,file)
                py_path = os.path.join(setting.CASE_PATH,class_name.lower()+'.py')
                open(py_path,'w+',encoding='utf-8').write(py_content)
        else:
            #log.error('测试用例不存在,请确认是否存在*.yaml')
            print('测试用例不存在,请确认是否存在*.yaml')
#执行测试用例脚本
def run_all_case(project_name):
    test_suite = unittest.TestSuite()#定义测试集合
    #使用unittest框架中defaultTestLoader模块扫描测试用例脚本
    all_py = unittest.defaultTestLoader.discover(setting.CASE_PATH,'*.py')
    #log.info('扫描测试用例脚本,已完成')
    #将测试用例脚本添加到测试集合中
    [test_suite.addTest(case) for case in all_py]
    report = br.BeautifulReport(test_suite)
    # title = '%s_测试报告'%time.strftime('%Y%m%d%H%M%S')
    title = '%s_测试报告' %(project_name+'_'+time.strftime('%Y%m%d%H%M%S'))
    #log.info('生成测试报告')
    report.report(project_name,title,setting.REPORT_PATH)
    #返回报告的信息,以便发送测试报告
    return  report.filename,report.success_count,report.failure_count
def send_mail(fileName,successCount,failCount):
    msg = '''
               各位好,
                   本次运行%s条用例,通过%s条,失败%s条,详细信息见附件。
           ''' % (successCount+failCount, successCount, failCount)
    try:
        mail = yagmail.SMTP(**setting.MAIL)
    except Exception as e :
        #log.error('邮箱登录异常:%s'%e)
        print('邮箱登录异常:%s'%e)
    else:
        mail.send(to=setting.TO,subject=str(fileName).strip('.html'),contents=msg,attachments=setting.REPORT_PATH+os.sep+fileName)
5. 创建启动脚本
#-*-coding:utf-8-*-
import sys, os
#将启动脚本添加到环境变量中否则脚本引用报错
sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from lib import tools
#生成测试用例python脚本
tools.create_py()
#执行测试用例python脚本
projectName,successCount,failCount=tools.run_all_case('学付宝项目测试用例')
#发送测试报告
tools.send_mail(projectName,successCount,failCount)
代码驱动代码如下:
这里可以通过对比一下数据驱动和代码驱动的结构看一下,整体结构没有啥变化只是用例脚本(Choujiang.py)需要手动编写,而不是像数据驱动那样由模板自动生成脚本(login.py);所以只需要编写单个测试用例脚本然后放到cases文件夹下,之后运行start.py就可以执行用例生成测试报告。

具体代码如下:

具体代码如下:
#-*-coding:utf-8-*-
import random,unittest,datetime,requests,time
from lib.db import MyDb,r
from conf import setting
class Choujiang(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.my_db = MyDb(**setting.MYSQL_INFO)
cls.base_url = setting.BASE_URL
cls.username ='BET'+str(datetime.datetime.now().second)+str(datetime.datetime.now().minute)
cls.passwd = 'aA1****'
print("注册用户:"+cls.username)
#注册
def register(self):
url = self.base_url+'api/user/user_reg'
pwd = 'aA****'
data = {'username':self.username,'pwd':self.passwd,'cpwd':self.passwd}
res = requests.post(url,data=data).json()
print(res)
print('注册的结果')
self.assertEqual(res.get('error_code'),1000,msg='注册没成功')
#登录
def login(self):
url = self.base_url+'api/user/login'
data = {'username':self.username,'passwd':self.passwd}
res = requests.post(url,data).json()
userId = res.get('login_info').get('userId')
self.assertIn('sign',str(res),msg='登录没有成功,实际结果是%s'%res)
sign = res.get('login_info').get('sign')
print('登录的结果')
return userId,sign
#抽奖,需要获取登录用户的sign 和 userid
def choice(self,userid,sign):
url = self.base_url+'api/product/choice'
data = {'userid':userid,'sign':sign}
res = requests.get(url,params=data).json()
self.assertIn('product_name',str(res),msg='抽奖失败,实际结果是%s'%res)
print('抽奖的结果')
# 添加商品
#添加商品
def goods_add(self, userid, sign):
sql = 'update app_myuser set is_admin =1 where username ="%s"' % self.username
self.my_db.other_sql(sql)
url = self.base_url + '/api/product/add'
# file = open('web.txt','w+',encoding='utf-8')
data = {'userid': userid, 'sign': sign, 'name': "香蕉 " + str(random.randint(0, 200)),
'file': r"C:\Users\k\Desktop\testTP.jpg"}
res = requests.post(url, data=data).json()
print(res)
self.assertIn('product_name', str(res), msg='商品添加失败,实际结果是%s' % res)
print('商品添加的结果')
#清理测试数据
@classmethod
def tearDownClass(cls):
sql = 'DELETE from app_myuser where username ="%s"'%cls.username
cls.my_db.other_sql(sql)
redis_key = 'choujiang:%s'%cls.username
r.set(redis_key,0)#把抽奖数设为0
print('收尾工作') def test_main(self):
self.register()
userid,sign = self.login()
self.choice(userid,sign)
# self.goods_add(userid,sign) # unittest.main()
utp的更多相关文章
- 使用lua给wireshark编写uTP的Dissector
		lonelycastle做uTP的实验,使用wireshark捕包,但是最初没有找到wireshark下的uTP的dissector,每次都需要比对文档,这样做实验理解报文含义,效率非常低.作为程 ... 
- 接口自动化(atp,utp)
		atp:数据驱动 utp:代码驱动 pip install -r file.txt #安装文件里面有的模块 pip freeze > file.txt #导出你已经安装好的第三方模块 
- 网线/双绞线上各标识CAT, AWG, PR, UTP/STP/FTP/SFTP的含义
		CAT5, CAT5e, CAT6 表示网线类别, 常见的有 CAT5, CAT5e, CAT6分别表示五类, 超五类, 六类网线 24AWG, 26AWG American Wire Gauge是美 ... 
- 文件参数化-utp框架之根据yaml文件自动生成python文件+utp运行用例
		根据yaml文件自动生成python文件 utp框架: bin目录:存放执行文件(run.py) cases目录:存放生成的用例的python文件(该目录下的文件为根据data目录下的测试用例生成的p ... 
- python自动化学习笔记11-自动化测试UTP框架
		前面基本的unittest及ddt已经学过了,现在我们系统把这些知识结合起来,写一个简单的UTP自动化测试框架: 我们先来建基础目录,首先新建一个项目,项目下建父目录UTP,conf目录,用来存放配置 ... 
- TCP 和 UDP 的区别---还有一个UTP一
		面试的时候会经常问到这些问题,所以要对比了解一下他们之间的差别,能讲出个所以然来.多积累多总结,懵逼中... TCP 和 UDP TCP与UDP基本区别 : 1.基于连接与无连接 2.TCP要求系统资 ... 
- 前端学HTTP之网络基础
		× 目录 [1]网络 [2]OSI [3]TCP/IP 前面的话 HTTP协议对于前端工程师是非常重要的.我们在浏览网站时,访问的每一个WEB页面都需要使用HTTP协议实现.如果不了解HTTP协议,就 ... 
- 关于如何使用sourcetree将本地项目提交到远端github总结?
		使用sourcetree将本地项目提交到github里,目前来说还是很流行的,我也是听说好玩,所以来琢磨了一下,从环境搭建到配置好,差不多用了一下午加一晚上的时间,有点虐心,好吧,废话不多说,介绍一下 ... 
- FREEBSD手工配置网络
		在FreeBSD系统中,网络能力十分重要,对于一个标准的FreeBSD系统,至少要有一个网络界面以便与其他计算机通信.最常见的网络界面为以太网卡.此外FreeBSD也支持Token Ring和FDDI ... 
随机推荐
- PHP字符串的处理(一)-字符串初识和比较
			在PHP中,字符和字节一样,共有256种不同字符的可能性,PHP对Unicode没有本地支持,一个GB2312编码的汉字占2字节,一个UTF-8编码的汉字占3字节字符串看作字符集和时,并不是真正的数组 ... 
- CNN感受野计算
			无痛理解CNN中的感受野receptive field CNN中感受野的计算 从直观上讲,感受野就是视觉感受区域的大小.在卷积神经网络中,感受野的定义是决定某一层输出结果中一个元素所对应的输入层的区域 ... 
- jaxb 专题一(JAXB 实现java对象与xml之间互相转换)
			首先熟悉一下JAXB实现对象与xml互转时常用的一些注解使用: 1.@XmlRootElement,用于类级别的注解,对应xml的跟元素.通过name属性定义这个根节点的名称. 2.@XmlAcces ... 
- RTMP_EnableWrite(rtmp)
			发布流关键函数: RTMP_EnableWrite(rtmp); 将rtmp设置可写状态,会发出publish指令,否则是play指令: 
- 各大IT/IC公司offer比较 
			1:本人西电通院2013届毕业硕士,根据今年找工作的情况以及身边同学的汇总,总结各大公司的待遇如下,吐血奉献给各位学弟学妹,公司比较全,你想去的公司不在这里面,基本上是无名小公司了:但无名小公司有时也 ... 
- Redis搭建(一):单实例
			环境:CentOS6.4 + redis3.2.4 一.安装 cd /opt tar -zxf redis-3.2.4.tar.gz make make install PREFIX=/usr/loc ... 
- Enumeration & Structures & Protocl & Extension
			[Enumeration and Structures] 1.使用toRaw.fromRaw方法可以在原始值之间.注意enum的定义中使用了case.另外要注意switch中的枚举值. 2.struc ... 
- Resin 的watchdog(看门狗)介绍和resin负载均衡实现
			为了稳定和安全,Resin使用一个独立的watchdog进程来启动和监视Resin服务器.watchdog连续你检测Resin服务器的状态,如果其没有反应或者迟钝,将会重启Resin服务器进程.大多数 ... 
- libevent源码深度剖析五
			libevent源码深度剖析五 ——libevent的核心:事件event 张亮 对事件处理流程有了高层的认识后,本节将详细介绍libevent的核心结构event,以及libevent对event的 ... 
- FastDFS和apache/nginx整合
			因为FastDFS默认自带的http服务器性能不好, 所以一般建议用外置的apache或者nginx 来解决http下载,以应付大并发的情况 注意nginx扩展模块只支持GET和HEAD模式获取文件, ... 
