• 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:UserskDesktop	estTP.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()
    
     
  • 相关阅读:
    Hdu1711 Number Sequence--Kmp模板题
    Trie入门--Poj3630 Phone List,查单词,HDU1251 统计前缀,PKU2503 Babelfish
    高次幂的组合数表示形式
    BZOJ1697 [Usaco2007 Feb] Cow Sorting牛排序
    1025 [SCOI2009]游戏(置换群,DP)
    Poj1721 Cards
    [Poi2003]Shuffle
    poj 3128 Leonardo's Notebook(置换的幂)
    POJ3734 Block母函数入门
    重心拉格朗日插值法
  • 原文地址:https://www.cnblogs.com/Noul/p/9961029.html
Copyright © 2020-2023  润新知