精华内容
下载资源
问答
  • pytest接口自动化-源码
    千次阅读
    2020-04-29 15:11:30

    “”"
    加我微信:hz223336,领取神级接口自动化框架讲解视频和pytest单元测试框架实战
    框架介绍
    采用最新pytest单元测试、框架功能最强大、框架行业最新最火(gitee搜索第一)、框架通用95%的公司、企业直接落地,万年老道深入讲解等等,带你走向接口自动化王者巅峰之路
    框架结构:Python+requests+pytest+log+allure+yaml+mysql+git+jenkins+钉钉群发送报告

    解决痛点:
    单接口、多接口封装合并出来
    yaml处理多接口动态传参
    多种格式请求体封装
    一键环境切换
    登录token和session全局调用处理
    多角色api灵活切换
    token和session超时失效处理
    数据清理(接口或SQL)
    框架通用95%的公司
    企业直接落地使用

    最重要的:只需封装一次api,其他的工作交给功能测试或不懂代码的人来做

    我们的目标:
    就是功能越强大,让脚本越简单越好,不然别人没法投入
    在企业核心人员维护框架和应用,业务人员可以写脚本,扩大脚本业务数量
    1000人的群里有全国各处的测试经理,测试主管,帮忙互相内推,在群里解答问题"""

    更多相关内容
  • 相关视频涉及Python自动化测试、selenium、appium、jmeter、python、robotframework等。
  • 软件测试/requests+Pytest接口自动化测试实战(一)___相关视频涉及Python自动化测试、selenium、appium、jmeter、python、robotframework等。
  • requests+Pytest接口自动化测试实战(五)___相关视频系列涉及Python自动化测试、selenium、appium、jmeter、python、robotframework等。
  • 一,出接口自动化测试方案。收集整理接口文档。 二,搭建自动化测试demo,优化完善架构目录。 三,框架接入流水线与编写case同时进行。 四,持续维护。 项目目录结构。 实操过程中遇到的问题及解决方案。 1,登录...

    一,出接口自动化测试方案。收集整理接口文档。
    二,搭建自动化测试demo,优化完善架构目录。
    三,框架接入流水线与编写case同时进行。
    四,持续维护。

    项目目录结构。

    实操过程中遇到的问题及解决方案。

    1,登录问题
    正常登录流程,先get请求login的url获取,csrf_token,及其他的所需要的信息,用于前端加密,前端加密算法,是用csrf_token, 盐,输入的密码等算出来一个值,去post请求登录接口。
    解决方案:
    使用python的第三方包《pyduktape》,来直接操作js文件,将所需要的参数,传递给js进行加密后将结果返回来,然后模拟登录。
    在这里插入图片描述

    2,设置全局登录cookies

    需求:设置一个已登录client,能够全局使用,每条用例可直接去请求。
    解决方案:
    使用conftest.py@pytest.fixture(scope="session")
    在这里插入图片描述
    3,关于参数化的思考
    解决方案:
    1,单接口参数:@pytest.mark.parametrize
    2,接口之间参数传递:@pytest.fixture(scope="function")
    3,接口之间的依赖:@pytest.mark.dependency() 处理的场景是,b接口依赖于a接口的成功,此方法实现的是,a接口失败,b接口自动跳过,不去执行。
    4,可以操作数据库,来获取b接口依赖a接口的值。
    5,如果登录的cookies是全局的,可以将a获取到的值存到cookies对象中去,用@pytest.mark.run(order=1)来控制顺序,或者使用@pytest.mark.dependency()失败后自动跳过,b接口可以从cookies的对象中取出a的返回值,进行使用后,将属性删除。
    在这里插入图片描述
    发现的问题
    1,dependency与parametrize不能一起用 否则dependency依赖的接口会跳过

    展开全文
  • requests+Pytest接口自动化测试实战(三)___相关视频系列涉及Python自动化测试、selenium、appium、jmeter、python、robotframework等。
  • requests+Pytest接口自动化测试实战(四)___相关视频系列涉及Python自动化测试、selenium、appium、jmeter、python、robotframework等。
  • pytest-接口自动化实战

    2021-04-28 13:00:26
    if 'json' in one: os.remove(f'../report/tmp/{one}') except:#规避第一次运行,没有生成tmp文件夹 print('pytest---是第一次运行') yield #这个作用域操作后的--动作 print('---自动化测试执行完成,现在进行数据...

    1.业务层

    #封装店铺的类
    from configs.config import HOST
    import requests
    from lib.apiLib.login import Login
    class Shop:
        def __init__(self,inToken):
            self.headers = {'Authorization':inToken}#身份信息校验--鉴权
        #1- 列出店铺
        def shop_list(self,inData):
            url = f'{HOST}/shopping/myShop'#url
            #2- body
            payload = inData
            resp = requests.get(url,params=payload,headers = self.headers)
            return resp.json()#请求的响应数据
        #2- 编辑接口里的一个图片上传接口
        def file_upload(self,fileName,fileDir):
            '''
            :param fileName: 文件名
            :param fileDir: 文件路径
            :return: 图片的信息
            '''
            #请求的要素:  url , headers-token ,请求体:文件名,文件对象,文件类型
            file_url = f'{HOST}/file'
            file_body = {'file':(fileName,open(fileDir,'rb'),'image/png')}#请求体文件(文件名,文件对象,文件类型)
            resp = requests.post(file_url,headers=self.headers,files = file_body)
            return resp.json()['data']['realFileName']#图片信息
    
        #3- 编辑店铺
        def shop_update(self,inData,shopId,imageInfo):
            '''
            :param inData: 用例数据---用例数据
            :param shopId: 商铺id---动态获取---shop_list去获取(前置)
            :param imageInfo: 图片信息---动态获取
            :return:
            '''
            inData['id'] = shopId#更新用例传入的数据id
            inData['image_path'] = imageInfo  # ['data']['realFileName']#图片信息
            inData['image'] = f"{HOST}/file/getImgStream?fileName={imageInfo}"
            payload = inData
            url = f'{HOST}/shopping/updatemyshop'
            resp = requests.post(url,data=payload,headers = self.headers)
            return resp.json()
    

    2.conftest.py

    import pytest
    
    '''
    scope:
        1- 默认是function   只要是函数级别都会调用下面的代码
        2- class 类级别  每一个运行一次下面的代码
        3- session  整个包作用域只运行一次
        4- moudle  整个py文件(模块)作用域只运行一次
    autouse  是否自动调用
    '''
    import os
    @pytest.fixture(scope='session',autouse=True)
    def clear_report():#前置操作---这个作用域---操作前的动作
        print('---现在我们开始自动化测试--环境初始化操作---')
        # 本地运行处理历史数据
        try:
            for one in os.listdir('../report/tmp'):#os.listdir('../report/tmp')列出路径下所有的文件
                if 'json' in one:
                    os.remove(f'../report/tmp/{one}')
        except:#规避第一次运行,没有生成tmp文件夹
            print('pytest---是第一次运行')
    
        yield #这个作用域操作后的--动作
        print('---自动化测试执行完成,现在进行数据清除操作---')
    
    
    #2- 店铺更新接口的初始化操作
    '''
    需求参数:shopID    imageInfo
    前置动作:
        1- 登录
        2- 列出店铺
    初始化操作是否自动调用:手动调用---哪里需要在哪里调用
    '''
    from lib.apiLib.login import Login
    from lib.apiLib.shop import Shop
    @pytest.fixture(scope='function')
    def shop_update_init():
        #1- 登录
        token = Login().login({'username': 'sq0777', 'password': 'xintian'}, getToken=True)
        #2- 列出店铺
        shop = Shop(token)#创建实例
        shopID=shop.shop_list({"page":1,"limit":20})['data']['records'][0]['id']
        #3- 获取图片信息
        imageInfo = shop.file_upload('123.png','../data/123.png')
        # print(shopID)
        # print(imageInfo)
        return shopID,imageInfo#返回值
        #3- 文件上接口调用获取imageInfo
    
    
    @pytest.fixture(scope='module',autouse=True)
    def login_init():#前置操作---这个作用域---操作前的动作
        print('---现在我们开始自动化测试--登录操作---')
        # 本地运行处理历史数据
        token = Login().login({'username': 'sq0777', 'password': 'xintian'}, getToken=True)
        return token
    
    @pytest.fixture(scope='function')
    def shop_xt():#前置操作---这个作用域---操作前的动作
        print('---useFixture---')
    

    3.test_shop.py

    from tools.yamlControl import get_yaml_data
    from lib.apiLib.login import Login
    from lib.apiLib.shop import Shop
    import pytest,os
    from tools.excelControl import get_excelData
    import allure
    @pytest.mark.shop#增加标签 mark
    @allure.epic('外卖项目-接口测试')
    @allure.feature('店铺模块')#测试类
    class TestShop:
        def setup_class(self):#使用这个类就一定会调用这个方法,只能运行一次
            #1- 登录
            res = get_yaml_data('../configs/conf.yaml')
            print(res)
            self.token = Login().login({'username':'sq0777','password':'xintian'},getToken=True)
            #2- 创建一个店铺的实例
            self.shop = Shop(self.token)
        #1- 列出店铺
        #没有返回返回值的fixture
        # @pytest.mark.usefixtures('shop_xt')
    
        # #@pytest.mark.skip(reason='下面接口后端存在问题,先跳过不执行!')#无条件跳过下面的用例执行--相当于注释--报告会显示
        # @allure.story('店铺列出')#接口的名称
        # @allure.link('https://www.baidu.com')
        # @allure.title('店铺列出用例')  # 用例的标题
        # @pytest.mark.shop_list# 增加标签 mark
        # @pytest.mark.parametrize('inData,respData',get_excelData('我的商铺','listshopping'))
        # def test_shop_list(self,inData,respData):
        #     #1- 调用店铺列出接口
        #     #店铺实例的创建必须要登录--需要一个店铺的实例---才能使用对应的方法
        #     #调用对应的方法
        #     res = self.shop.shop_list(inData)
        #     '''
        #     如果断言不是一个属性,需要多个组合判断?
        #     原理:assert   布尔表达式       多个条件使用and  or
        #     '''
        #     if 'code' in respData:
        #         assert res['code'] == respData['code']
        #     else:
        #         assert res['error'] == respData['error']
        #
        #2- 店铺更新
        @pytest.mark.run(order=1)#指定运行顺序!   最后@pytest.mark.last
        # @pytest.mark.skipif(Login().login({'username':'sq0777','password':'123456'})['msg']!='成功',reason='登录失败,先跳过不执行下面的接口!')  # 条件为真,跳过下面的用例执行
        @allure.story('店铺更新')  # 接口的名称
        @allure.title('店铺更新用例')#用例的标题
        @pytest.mark.shop_update  # 增加标签 mark
        @pytest.mark.parametrize('inData,respData', get_excelData('我的商铺', 'updateshopping'))
        def test_shop_update(self,inData,respData,shop_update_init):#引入初始化方法名字
            #1- 调用店铺更新的接口
            #shop_update_init[0],shop_update_init[1]  返回值0  返回值1
            #res = self.shop.shop_update(inData,shop_update_init[0],shop_update_init[1])#excel测试用例数据,店铺的id,图片信息
            #用例执行步骤
            with allure.step('第1步:登录'):
                print('登录')
            with allure.step('第2步:店铺更新操作'):#计算这一步的时间--执行时间
                res = self.shop.shop_update(inData,shop_update_init[0],shop_update_init[1])
            #2- 断言
            assert res['code'] == respData['code']
    
    
    if __name__ == '__main__':
        '''
        pytest.main :  -m 指定标签运行   ‘-m’,'shop_list'
        
        '''
        #1  -m
        #pytest.main(['test_shop.py', '-s', '-m','shop_list or shop_update','--alluredir', '../report/tmp'])  # -s 打印print信息
        #2  -k 匹配用例文件名称**   xxx.py
        #pytest.main(['test_shop.py', '-s', '-k', 'shop', '--alluredir', '../report/tmp'])  # -s 打印print信息
        pytest.main(['test_shop.py', '-s',  '--alluredir', '../report/tmp'])
        os.system('allure serve ../report/tmp')
    

    4.excel操作

    import xlrd#要安装的第三库  pip install xlrd
    import json
    #json字符串---转化成---字典  转化后的值(字典类型) = json.loads(被转json字符串)
    #字典---转化成---json字符串  转化后的值(json类型) = json.dumps(被转字典)
    def get_excelData(sheetName,caseName):
        resList = []#存放结果
        #1- 加载 ---打开
        excelDir = '../data/外卖系统接口测试用例-V1.5.xls'
        #formatting_info=True   保持原表样式
        workBook = xlrd.open_workbook(excelDir,formatting_info=True)
        #2-打开对应的操作的子表
        workSheet = workBook.sheet_by_name(sheetName)
        #3- 读数据--读取指定单元格数据
        #读取一行--print(workSheet.row_values(1))
        #请求体
    
        # print(workSheet.cell(1,9).value)#cell(行号,列号).value
        # #响应数据
        # print(workSheet.cell(1,11).value)#cell(行号,列号).value
        #print(workSheet.col_values(0))#获取用例编号列数据
        idx = 0#excel第0行数据
        for one in workSheet.col_values(0):#6次
            if caseName in one:#运行你需要运行的测试用例
                reqBodyData = workSheet.cell(idx,9).value#cell(行号,列号).value
                respData = workSheet.cell(idx, 11).value#cell(行号,列号).value
                #[(),(),()]
                resList.append((json.loads(reqBodyData),json.loads(respData)))
    
            idx += 1#轮询下一行数据
        return resList
    
    #新建空的excel  xlwt
    from xlutils.copy import copy#拷贝函数
    def set_excelData(sheetIndex):#1- 新建空excel文件写入   2- 打开原来的写入---能不能复制一个出来去写入
        #1- 加载 ---打开
        excelDir = '../data/外卖系统接口测试用例-V1.5.xls'
        #formatting_info=True   保持原表样式
        workBook = xlrd.open_workbook(excelDir,formatting_info=True)
        workBookNew = copy(workBook)
        workSheetNew = workBookNew.get_sheet(sheetIndex)#打开复制的excel的其中一个表--登录模块
        return workBookNew,workSheetNew
    
    
    import pprint
    if __name__ == '__main__':
        get_excelData('登录模块','Login')
    

    5.yaml文件操作

    #读取yaml文件数据
    import yaml
    def get_yaml_data(fileDir):
        #1- 文件在磁盘--需要在缓存里打开
        fo = open(fileDir,'r',encoding='utf-8')
        #2- 调用方法
        res = yaml.load(fo,Loader=yaml.FullLoader)
        return res
        # print(res['info'])
        # print(res['msg'])
    
    
    def get_yamls_data(fileDir):#获取yaml里多个文件
        resList = []
        #1- 文件在磁盘--需要在缓存里打开
        fo = open(fileDir,'r',encoding='utf-8')
        #2- 调用方法
        res = yaml.load_all(fo,Loader=yaml.FullLoader)
        for one in res:
            print(one)
            resList.append(one)
        return resList
    
    
    def set_yaml_data(fileDir):#写不需要去新建文件
        #1- 文件在磁盘--需要在缓存里打开
        fo = open(fileDir,'w',encoding='utf-8')
        #2- 调用方法
        yaml.dump({'a':100,'b':200,'c':[10,20]},fo)
    
    
    def get_yaml_data02(fileDir):#优化--所有去读取文件--加上异常机制--log日志机制
        resList = []
        #1- 文件在磁盘--需要在缓存里打开
        fo = open(fileDir,'r',encoding='utf-8')
        #2- 调用方法
        res = yaml.load(fo,Loader=yaml.FullLoader)
        for one in res:
            resList.append((one['data'],one['resp']))
        return resList
    
    
    if __name__ == '__main__':
        # get_yamls_data('../configs/conf.yaml')
        # set_yaml_data('../configs/test.yaml')
    
        print(get_yaml_data('../configs/conf.yaml'))
    

    6.mock

    import requests
    #1- url
    # url = 'http://127.0.0.1:9999/xintian_sq'
    # resp = requests.get(url)
    # print(resp.text)
    
    # url2 = 'http://127.0.0.1:9999/xintian'
    # resp = requests.get(url2)
    # print(resp.text)
    
    #3- get--带参数的
    # url2 = 'http://127.0.0.1:9999/xintian2'
    # payload = {
    # 			"key1":"abc",
    # 			"key2":"123"
    # 		  }
    # resp = requests.get(url2,params=payload)
    # print(resp.text)
    
    #4- post--带参数的
    # url2 = 'http://127.0.0.1:9999/xt3'
    # payload = {"key1":"abc"}
    # resp = requests.post(url2,data=payload)
    # print(resp.text)
    
    异步接口测试
    HOST = 'http://127.0.0.1:9999'
    #1- 申请退订请求
    def create_order():
        url = f'{HOST}/api/order/create/'
        payload = {
                    "user_id": "sq123456",
                    "goods_id": "20200815",
                    "num":1,
                    "amount":200.6
    				}
        resp = requests.post(url,json=payload)
        print(resp)
        #resp.request.headers#请求头
        #resp.headers响应头
        return resp.json()
    
    
    #2- 查询结果接口
    '''
    一般异步的查询接口:
        1、频率
        2、超时
    '''
    import time
    def get_order_result(orderID,interval,timeout):
        url = f'{HOST}/api/order/get_result/'
        payload = {"order_id": orderID}#参数
        #1- 开始时间:获取当前的时间
        startTime = time.time()
        #2-结束时间:开始+超时时间
        cnt = 0#为了显示效果--打印下查询的次数
        endTime = startTime+timeout
        while time.time()<endTime:#for:适用于:遍历操作、知道需要循环多少次的  while :靠条件结束
            resp = requests.get(url,params=payload)
            print(f'第{cnt}次查询')
            cnt +=1
            time.sleep(interval)  # 查询的频率   单位是s
            if resp.text:#一定有响应,我们就退出
                break
        return resp.text
    
    
    if __name__ == '__main__':
        orderId = create_order()['order_id']#1- 申请退订请求
        # print(get_order_result(orderId,2,10))#2- 查询接口
    
    
    # 扩展--pytest  有没有用例失败了重跑的机制  失败了可以按照一定频率去跑多次  频率+次数
    import pytest
    
    #reruns=2   重跑次数   ,reruns_delay=2  频率
    @pytest.mark.flaky(reruns=2,reruns_delay=2)#只要失败的才重跑
    @pytest.mark.parametrize('a',[100,200,300])
    def test_001(a):
        assert a == 200
    
    if __name__ == '__main__':
        pytest.main(['mockTest.py','-s'])
    

    7.日志模块

    #需要导入一个库
    import logging#标准库里
    '''
    日志的要素:
        1- 日志名称
        2- 日志的级别
        3- 日志文件中描述的格式
    
    '''
    import datetime#具体时间的
    def logger():
        #1- 日志名称  路径+名字+后缀名
        fileName = f'../logs/{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}.log'
        #2- 创建日志对象
        log = logging.getLogger()# __name__
        #3- 设置日志级别
        log.setLevel(logging.INFO)
        rHandler = logging.FileHandler(fileName,mode='w',encoding='utf-8')
        #4- 设置日志的内容格式    时间 - 级别 -模块名[行号] - 信息   s 字符串   d-int
        formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s[line:%(lineno)d] - %(message)s')
        #5- 设置格式
        rHandler.setFormatter(formatter)
        log.addHandler(rHandler)
        return log
    
    
    if __name__ == '__main__':
        log = logger()
        # print(datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))
        log .info('hello')
        log .error('xintian')
    

    8.封装日志

    #封装日志
    class EncapLogs():
    
        def __init__(self,name=None):  #name为日志的名称
            if name is None:
               self.name = 'testcase'
            else:
                self.name = name
            self.mylog = logging.getLogger(self.name)
            #创建日志对象
            self.mylog.setLevel(do_Encapyaml.getyaml_info('log','logger_level'))#设置日志等级
            #创建显示日志渠道
            consle_log = logging.StreamHandler() #输出到控制台
            #控制台日志设置日志等级
            consle_log.setLevel('WARNING')
            #日志文件
            log_addr = do_getpath.getpath('logs_path') + do_Encapyaml.getyaml_info('log','log_filename')
            #设置日志文件:文件地址、编码格式
            log_file = logging.FileHandler(log_addr,encoding ='utf-8')
            #输出到日志文件
            #设置日志的格式:日志记录的运行时间,日志报错等级,日志提示信息,日志的名称,第几行代码
            log_formater = logging.Formatter('%(asctime)s - [%(levelname)s] - [msg]: %(message)s - %(name)s - %(lineno)d')
            #把日志的格式加入到日志渠道中
            #formatter= '%(asctime)s-[%(levelname)s]-[msg]:%(message)s-%(name)s-%(lineno)d'
            # % (levelno)s:打印日志级别的数值。
            # % (levelname)s:打印日志级别的名称。
            # % (pathname)s:打印当前执行程序的路径,其实就是sys.argv[0]。
            # % (filename)s:打印当前执行程序名。
            # % (funcName)s:打印日志的当前函数。
            # % (lineno)d:打印日志的当前行号。
            # % (asctime)s:打印日志的时间。
            # % (thread)d:打印线程ID。
            # % (threadName)s:打印线程名称。
            # % (process)d:打印进程ID。
            # % (processName)s:打印线程名称。
            # % (module)s:打印模块名称。
            # % (message)s:打印日志错误提示信息
            consle_log.setFormatter(log_formater)
            log_file.setFormatter(log_formater)
            #把日志对象与输出渠道相关联
            self.mylog.addHandler(consle_log)
            self.mylog.addHandler(log_file)
    
        def runlogs(self) :
    
            return self.mylog
    
    do_log = EncapLogs().runlogs()
    
    if __name__ == '__main__':
        # do_log = EncapLogs()
        # mylog = do_log.runlogs()
        # mylog.info('这只是个提示')
        # mylog.error('错误信息')
        # mylog.critical('这是一个致命的错误')
        # mylog.debug('这是一个调试信息')
        # mylog.warning('警告')
        do_log.error('错误信息提示')
    

    日志使用

    
    @ddt
    class UnittestAdd(unittest.TestCase):
        filename = do_Encapyaml.getyaml_info('excel', 'filename')
        sheetname = do_Encapyaml.getyaml_info('excel', 'sheetname4')
        fileaddr = os.path.join(do_getpath.getpath('data_path'), filename)
        # 获取excel文件的地址
        my_date = Encapsulates_excel(fileaddr, sheetname)
        testcases = my_date.r_excel()
        @classmethod
        def setUpClass(cls):
            cls.do_request = HandleRequests()
            cls.do_request.add_headers(do_Encapyaml.getyaml_info("api", "api_version"))
            cls.reg = RegStr()
            cls.mysql = LinkMysql()
            setattr(GobleData,'${not_existed_id}',cls.mysql.not_existed_user_id())
    
            do_log.info('开始执行用例')
            
        @classmethod
        def tearDownClass(cls):
            cls.do_request.close()
            cls.mysql.close()
            do_log.info('用例执行结束')
    
        @data(*testcases)
        def test_add(self,onetestcase):
            new_data = self.reg.RegulaStr(onetestcase.data)
            res = self.do_request.send_requests(onetestcase.method,onetestcase.url,json = new_data)
            real_code = res.json()['code']
            try:
                self.assertEqual(onetestcase.expected_value,real_code,onetestcase.name)
            except AssertionError as err:
                do_log.error(f'{onetestcase.name}具体异常信息为:{err}')
                self.my_date.write_date(onetestcase,res.text,'失败')
                raise err
            else:
                if 'token_info' in res.text:
                    token = res.json()['data']['token_info']['token']
                    new_headers = {"Authorization":"Bearer " + token}
                    self.do_request.add_headers(new_headers)
                self.my_date.write_date(onetestcase,res.text,'成功')
    
    展开全文
  • requests+Pytest接口自动化测试实战(二)___相关视频涉及Python自动化测试、selenium、appium、jmeter、python、robotframework等。
  • pytest接口自动化测试

    2020-09-20 20:52:03
    import pytest import requests # def test_001():#函数 ----------------方法 # #断言 # print('test_001开始')#要想输出信息,加一个-s # assert 1+2 == 3 # print('test_001结束') # # #封装测试类 # class Test_...
    import pytest
    import requests
    # def test_001():#函数 ----------------方法
    #     #断言
    #     print('test_001开始')#要想输出信息,加一个-s
    #     assert 1+2 == 3
    #     print('test_001结束')
    #
    # #封装测试类
    # class Test_login:#---------------------类
    #     def test_003(self):
    #         assert 1+2==4
    #--------自带的装饰器--mark
    # @pytest.mark.parametrize('inData',[10,20])#---------参数化-----inData是参数化的文件,[10,20]是参数化的数据,把要参数化的函数写进去,如下
    # def test_001(inData):-----------------一个参数inData
    #     assert inData==3
    
    # @pytest.mark.parametrize('inData,outData',[(10,20),(30,40)])#-------------两个参数这样定义
    # def test_001(inData,outData):
    #     assert inData+outData==3
    
    #--------接口实战
    def test_get_token():
        token_url='http://www.xxx'#url
        header_token={'Cotent-Type':'application/jason'}#请求头
        payload={'userName':'12336728126','password':'8888863'}#请求体
    #--------发送请求
        reps=requests.post(token_url,jason=payload)
       # return reps.json()['token']#----------返回字典格式
    #----------------断言
        assert reps.json()['msg']=='成功'
    
    
    #---------------参数化
    token_data=[{'userName':'12336728126','password':'8888863'},{'userName':'1233','password':'56373'}]#-----假设第一组是正确的,第二组是错的
    #-----实际工作中的数据是读取excel
    @pytest.mark.parametrize('inData')
    def test_get_token(inData):
        token_url='http://www.xxx'#url
        header_token={'Cotent-Type':'application/jason'}#请求头
        payload=inData#请求体
    #--------发送请求
        reps=requests.post(token_url,jason=payload)
    #----------------断言
        assert reps.json()['msg']=='成功'
    
    #-----生成报告,在下面加一个'--html=../test_report/xt.html'
    if __name__ == '__main__':
        pytest.main(['test_func.py','-s','--html=../test_report/ceshi.html'])#在这里加-s
    
    
    展开全文
  • 经过之前的学习铺垫,我们尝试着利用pytest框架编写一条接口自动化测试用例,来厘清接口自动化用例编写的思路。 我们在百度搜索天气查询,会出现如下图所示结果: 接下来,我们以该天气查询接口为例,编写接口测试...
  • 搭建接口自动化测试框架 目录分层: 1.common:放置常用公共方法,例如:操作yaml文件的模块、读取配置文件模块等 2.config:存放配置文件:例如:config.ini文件 3.logs:存放日志文件 4.report:存放生成的报告 5....
  • pytest接口自动化测试框架搭建

    千次阅读 2022-01-26 16:10:40
    Pytest目前已经成为Python系自动化测试必学必备的一个框架,最近抽时间梳理了一份pytest接口自动化测试框架,尽量简单通俗易懂。如果能够对新学习这个框架的同学起到一些帮助,那就更好了~
  • Pytest+Allure+Jenkins接口自动化项目实战(一)

    千次阅读 多人点赞 2020-01-20 13:09:08
    经过一周多时间,基于python+pytest+excel+allure框架的接口自动化测试初版已基本实现,包括基本配置读取、用例读取、用例执行、sql读取执行、前置数据准备、后置数据清理以及测试报告生成等,环境独立运行、项目...
  • pytest接口自动化测试框架+项目实例

    万次阅读 2019-06-19 15:26:16
    python pytest (或许以后加上django) 一、基础框架:测试用例;测试数据;测试报告------------实现逻辑和数据分离,后期可以增加日志、公用配置、封装完善 1、  项目背景:http 接口、pycharm、py...
  • 前段时间公司业务需要,准备把之前的接口自动化的脚本整理一下,把之前的冗长的代码整理成一个个的用例,这样代码的可读性就变得高了,而且相应的维护的成本降低。我们用到的是Pytest框架,关于框架的介绍及优点我...
  • 从零开始深入pytest的世界!个人实战总结:https://www.yuque.com/zaygee/pytest
  •  本文章主要会讲解Python中pytest框架的讲解,介绍什么是pytest、为何要测试、为何使用以及参考和扩展等
  •  前面介绍了pytest框架一些基础知识与基本用法,掌握了一定基础后,我们可以进行项目实战,搭建pytest接口自动测试框架。  框架设计思路  画了一张草图,大家自行领会。  项目结构  源码展示  将test_...
  • python接口自动化实战(框架)

    万次阅读 多人点赞 2018-03-10 23:00:36
    理清思路 我这个自动化框架要实现什么 1.从excel里面提取测试用例 2.测试报告的输出,并且测试报告得包括执行的测试用例的数量、成功的数量、失败的数量以及哪条成功了,失败的是哪一个,失败的原因是什么;测试...
  • import pytest @pytest.fixture() def login(): print('登陆了') 例子 1 import pytest @pytest.fixture(scope="module", autouse=True) def open_browser(): print("\n打开浏览器,打开百度首页") yield ...
  • ,其中包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试...
  • pytest 接口自动化从百草园到三味书屋...开发环境requests安装requestsGET 请求POST请求添加header信息结合pytest实战flask安装 flask最简单的flaskflask - POST请求flask本地json接口动态写法flask一些常用的属性...
  • python+requests+pytest实现接口自动化测试
  • Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 接口定义 一般我们所说的接口即API,那什么又是API呢,百度给的定义如下: API(Application Programming Interface,应用程序接口)是一些...
  • 1.了解pytest框架 2.安装pytest,以及相关插件 2.1安装pytest 2.2安装插件 1.使用虚拟环境(也是针对此项目,局部安装)安装。 2.使用dos命令安装全局的环境 3.pytest默认使用规则 4.运行规则 1.使用主函数...
  • 通过yagmail第三方库,编写发送报告接口,测试工作完成后自动发送测试报告。 目录结构 PytestAutoTestFrameWork |—|config |——|__init__.py |——|conf.py |——|config.ini |—|data |——|__init__.py |——|...
  • 废话不多说哈,今天再来说说pytest吧,经过几周的时间学习,有收获也有疑惑,总之最后还是搞个小项目出来证明自己的努力不没有白费环境准备序号库/插件/工具安装命令1确保您已经安装了python3.x2配置python3+pycharm...
  • 更多信息请参考 Pytest自动化测试框架 Pytest中常用的断言 (1)pytest 中可以直接使用python的assert断言语句进行断言 如: # content of test_assert1.py def f(): return 3 def test_function(): assert f() ==...
  • --------UnitTest框架和PyTest框架的简单认识对比与项目实战--------定义:Unittest是Python标准库中自带的单元测试框架,Unittest有时候也被称为PyUnit,就像JUnit是Java语言的标准单元测试框架一样,Unittest则是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 996
精华内容 398
关键字:

pytest接口自动化实战