接口测试大致分为两种:数据驱动和代码驱动

数据驱动:主要处理用例之间没有关联关系的用例集合,一般以(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的更多相关文章

  1. 使用lua给wireshark编写uTP的Dissector

      lonelycastle做uTP的实验,使用wireshark捕包,但是最初没有找到wireshark下的uTP的dissector,每次都需要比对文档,这样做实验理解报文含义,效率非常低.作为程 ...

  2. 接口自动化(atp,utp)

    atp:数据驱动 utp:代码驱动 pip install -r file.txt #安装文件里面有的模块 pip freeze > file.txt #导出你已经安装好的第三方模块

  3. 网线/双绞线上各标识CAT, AWG, PR, UTP/STP/FTP/SFTP的含义

    CAT5, CAT5e, CAT6 表示网线类别, 常见的有 CAT5, CAT5e, CAT6分别表示五类, 超五类, 六类网线 24AWG, 26AWG American Wire Gauge是美 ...

  4. 文件参数化-utp框架之根据yaml文件自动生成python文件+utp运行用例

    根据yaml文件自动生成python文件 utp框架: bin目录:存放执行文件(run.py) cases目录:存放生成的用例的python文件(该目录下的文件为根据data目录下的测试用例生成的p ...

  5. python自动化学习笔记11-自动化测试UTP框架

    前面基本的unittest及ddt已经学过了,现在我们系统把这些知识结合起来,写一个简单的UTP自动化测试框架: 我们先来建基础目录,首先新建一个项目,项目下建父目录UTP,conf目录,用来存放配置 ...

  6. TCP 和 UDP 的区别---还有一个UTP一

    面试的时候会经常问到这些问题,所以要对比了解一下他们之间的差别,能讲出个所以然来.多积累多总结,懵逼中... TCP 和 UDP TCP与UDP基本区别 : 1.基于连接与无连接 2.TCP要求系统资 ...

  7. 前端学HTTP之网络基础

    × 目录 [1]网络 [2]OSI [3]TCP/IP 前面的话 HTTP协议对于前端工程师是非常重要的.我们在浏览网站时,访问的每一个WEB页面都需要使用HTTP协议实现.如果不了解HTTP协议,就 ...

  8. 关于如何使用sourcetree将本地项目提交到远端github总结?

    使用sourcetree将本地项目提交到github里,目前来说还是很流行的,我也是听说好玩,所以来琢磨了一下,从环境搭建到配置好,差不多用了一下午加一晚上的时间,有点虐心,好吧,废话不多说,介绍一下 ...

  9. FREEBSD手工配置网络

    在FreeBSD系统中,网络能力十分重要,对于一个标准的FreeBSD系统,至少要有一个网络界面以便与其他计算机通信.最常见的网络界面为以太网卡.此外FreeBSD也支持Token Ring和FDDI ...

随机推荐

  1. 第十九章 MySQL Cluster(待续)

    ··········

  2. 1.2celery的安装

    我们可以使用python的包管理器pip来安装: pip install -U Celery 也可从官方直接下载安装包:https://pypi.python.org/pypi/celery/ tar ...

  3. Setting up logs in NetBackup

    For a given issue, it may be necessary to gather multiple logs.  This MUST cover the time the issue ...

  4. vue简单路由(二)

    在实际项目中我们会碰到多层嵌套的组件组合而成,但是我们如何实现嵌套路由呢?因此我们需要在 VueRouter 的参数中使用 children 配置,这样就可以很好的实现路由嵌套. index.html ...

  5. YII 模型关联之 一对一

    需求,一个用户对应一个用户信息表,  这两者之间的关系就是一对一 //首先查找出一个用户出来 $user=Users::find()->'])->one(); //然后查询, 第一个参数是 ...

  6. laravel中的文件上传到本地+七牛云上传

    首先在filesystems.php 配置好上传的文件的目录起名为upload 在Storage/目录下面 目录下面的app/upload 如果没有这个文件会自动创建 这里的名字upload名字是跟控 ...

  7. linux上搭建图片服务器

    之前写过一个搭建图片服务器的随笔:https://www.cnblogs.com/xujingyang/p/7163290.html   ,现在回头看看,我去,感觉写的好乱,现在再整一个吧.o(╯□╰ ...

  8. 获取文件的后缀名。phpinfo

    1: function get_extension($file){ //strrchr 返回 .jpg substr :1 是从1开始. substr(strrchr($file,'.'),1) } ...

  9. SpringBoot16 MockMvc的使用、JsonPath的使用、请求参数问题、JsonView、分页查询参数、JsonProperty

    1 MockMvc的使用 利用MockMvc可以快速实现MVC测试 坑01:利用MockMvc进行测试时应用上下文路径是不包含在请求路径中的 1.1 创建一个SpringBoot项目 项目脚手架 1. ...

  10. opennebula 镜像池

    { "IMAGE_POOL": { "IMAGE": [ { ", ", ", "TEMPLATE": { & ...