精华内容
下载资源
问答
  • python+pytest+request 接口自动化测试
    2021-11-16 14:40:05

     

     

    一、环境配置

    1.安装python3

    brew update

    brew install pyenv

    然后在 .bash_profile 文件中添加 eval “$(pyenv init -)”

    pyenv install 3.5.3 -v

    pyenv rehash 安装完成后,更新数据库

    pyenv versions 查看目前系统已安装的 Python 版本

    pyenv global 3.5.3 切换 Python 版本

    python -V,查看 Python 版本

    2.安装pytest及其他所需安装包:

    pip install -U pytest
    pip install -U requests
    pip install -U pytest-pythonpath
    pip install -U pytest-capturelog
    pip install PyYAML
    pip install configparser
    pip install pyopenssl

    二、pytest框架

    setup_module(module): #开始测试前执行一次,目前无实际使用

    setup_function(function): #每个测试用开始前执行一次,用于检查、准备测试环境

    teardown_function(function): #每个测试用例执行完执行一次,用于清除生成的测试数据

    teardown_module(module): #每次测试完成执行一次,用于还原测试环境

    @pytest.mark.parametrize(‘mycase’, case.list,ids=case.name) #装饰器,用来将list格式的测试用例分开执行

    pytest.skip("skip testcase: (%s)" % mycase['Name']) #跳过测试用例
    pytest.xfail("previous test failed (%s)" % mycase['Name']) #跳过会失败的测试用例

    三、测试报告

    python -m pytest -s -q 控制台输出每一步结果

    1.allure

    安装:

    sudo pip install pytest-allure-adaptor
    brew tap qatools/formulas
    brew install allure-commandline

    执行:

    python -m pytest -s -q --alluredir ./report #控制台也输出每一步结果
    python -m pytest --alluredir ./report #控制台只输出成功/失败和失败报的错误
    allure generate report/ -o report/html #生成报告,可直接打卡看

    2.pytest-html

    安装:

    sudo pip install pytest-html

    执行:

    python -m pytest -s -q --html=./report.html #控制台也输出每一步结果

    python -m pytest --html=./report.html #控制台只输出成功/失败和失败报的错误

    四、Demo

    # coding: utf-8
    import pytest
    import public
    import read_testcase
    import record
     
    #获取一个账号token,全局变量
    public.getalltoken()
    #测试用例实例化
    testcase=read_testcase.case()
     
    #所有测试用例开始前执行的文件,只执行一次
    def setup_module(module):#每次开始测试执行一次
        print ("setup_module")
    #所有测试用例结束后执行的文件,只执行一次
    def teardown_module(module):#每次测试完成执行一次
        print ("teardown_module")
    #每个测试用开始执行一次
    def setup_function(function):
        print ("setup_function")
    #每个测试用例执行完执行一次
    def teardown_function(function):
        print ("teardown_function")
    #装饰器 pytest 整合的测试用例生成多个结果
    @pytest.mark.parametrize('mycase', testcase.testcase_list,ids=testcase.testcasename)
    def test_all(mycase):
        testcase=mycase['Testcase_name']+str(mycase['Testcase_ID'])+'.'+str(mycase['ID'])+":"+mycase['Name']
        #print(mycase['Name'])
        #pytest.skip("skip testcase: (%s)" % mycase['Name'])
        #pytest.xfail("previous test skip (%s)" % mycase['Name'])
        mycase = public.get_Precondition(mycase)
     
        #执行接口的测试
        r=public.request_method(mycase)
        try:
            print(r.status_code)
            print(r.json())
        except Exception as e:
            print(r.content)
            print(e)
        #对返回数据进行断言
        public.assert_method(r, mycase)
        #记录测试用例名称存储log
        record.record_testcase_name(testcase)
        #记录测试时使用的数据
        record.record_testcase_msg(mycase)

    点赞关注不迷路~~~

    下面是配套资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

    å¨è¿éæå¥å¾çæè¿°
    最后: 可以在公众号:程序员小濠 ! 免费领取一份216页软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享!,其中包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等。

    学习不要孤军奋战,最好是能抱团取暖,相互成就一起成长,群众效应的效果是非常强大的,大家一起学习,一起打卡,会更有学习动力,也更能坚持下去。你可以加入我们的测试技术交流扣扣群:310357728(里面有各种软件测试资源和技术讨论)

    喜欢软件测试的小伙伴们,如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!

    更多相关内容
  • 相关视频涉及Python自动化测试、selenium、appium、jmeter、python、robotframework等。
  • 软件测试/requests+Pytest接口自动化测试实战(一)___相关视频涉及Python自动化测试、selenium、appium、jmeter、python、robotframework等。
  • python+requests+pytest实现接口自动化测试

    前言

    • 运用框架:requests,pytest

    封装requests和断言方法

     1、新建py文件requests_,文件名称自定
     2、封装分3个阶段,
       封装控制台打印网络请求信息和返回信息
       封装requests网络请求,已post请求为主
       重新封装断言方法

    improt json
    from requests import Request
    
    """ 1、封装控制台打印网络请求信息和返回信息 """
    # 控制台带引网络请求信息
    def print_req(preq):
        print('=======================【请求信息】=======================')
        print(f'【url】-{preq.method}{preq.url}')
        print(f'【headers】-{preq.headers}')
        print(f'【data】-{preq.body}')
    # 控制台打印网络返回结果
    def print_resp(resp):
        print('=======================【返回结果】=======================')
        print(f'【status_code】-{resp.status_code}')
        print(resp.json()) # 不美化打印返回数据
        ppd(resp.json()) # 美化打印字典格式数据
        print('========================================================')
    # 美化打印字典格式数据
    def ppd(dic):
        print(json.dumps(dic,indent=2,ensure_ascii=False))
        
    """ 2、封装requests网络请求 """
    # 发送网络请求,返回原始response对象
    def pure_request(s,url,data='{}',headers={'Content-type':'application/json'}):
        req = Request('POST',url,data=data,headers=headers)
        prep = req.prepare() # 准备url
        print_req(prep) # 调用上面封装好的控制台打印方法,打印请求信息
        
        # 发送网络请求,返回请求结果
        resp = s.send(prep)
        print_resp(resp) # 调用上面封装好的控制台打印方法,打印返回信息
        return resp
    # 发送网络请求,返回json对象
    def request(s,url,data='{}',headers={'Content-type':'application/json'}):
        result = pure_request(s,url,json.dumps(data),headers)
        return result.json()    
    
    """ 3.重新封装json格式断言方法 """
    """
        d1-预期结果,d2-实际返回结果
        递归d2字典是不是和d1模板字典所期望值
        d1中 键开头是 !,那么 d1 != d2
        d1中 键开头是 * ,那么表示这个key不应该存在
        d1中 键开头是 ?,可选字段,有的话进行验证,没有的略过
        d1中 键开头是 @ ,那么检查长度是否正确
        d1中 键开头是 [] ,那么检查只是否在一个范围内,例如[1,2,3,4]
        d1中 值是None, 只检查是否有这个键
        d1中 值不是None, 检查两个值是否一模一样
    """
    def iterdict_dic(d1,d2):
        # 判断数据类型是否一样
        if type(d1) != type(d2):
            return False,f"数据类型不同 {d1}={type(d1)},{d2}={type(d2)}"
        # 判断字典内key和values是否期望值
        for k,v in d1.items():
            opposite = False # 取反操作符
            if k[0] == '*': # 如果键的开头是*,那么表示键在实际值中不应该存在
                k = k[1:] # 取键的实际值
                if k in d2:
                    return False,f'多余字段:{k}'
            elif k[0] == '@': # 如果键的开头是@,那么values的长度和实际值应相等
                k = k[1:]
                if k not in d2:
                    return False,f'缺少字段:{k}'
                if len(v) != len(d2[k]):
                    return False,f'[{k}]的长度是:{len(v)},实际长度:{len(d2[k])}'
            elif k[:2] == '[]': # 如果键的开头是[],那么实际值需要在预期值得范围内,比如实际值是1,预期值是[1,2,3]那么返回True
                k = k[2:]
                if k not in d2:
                    return False,f'缺少字段:{k}'
                if d2[k] not in v:
                    return False,f"[{k}]的值是:{d2[k]},不在期望值内[{v}]"
            elif k[0] == "?":
                k = k[1:]
                if k not in d2:
                    continue
            elif k[0] == "!"
                k = k[1:]
                opposite = True
                                                                            
            if k not in d2:
                return False,f"缺少必要字段:[{k}]"
            if v == Nonecontinue # 如果values等于None,跳过
            if isinstance(v,dict):
                res,msg = iterdict_(v,d2[k])
                if ret == False:
                    return ret,msg
            elif isinstance(v,list):
                if not isinstance(d2[k],list):
                    return False,f"[{d2[k]}]是:{type(d2[k])},不是一个数组"
                if len(v) > len(d2[k]):
                    return False,f"[{v}]长度和实际值:{d2[k]}长度不同"
                for i in range(0,len(v)):
                    ret,msg = iterdict_(v[i],d2[k][i])
                    if ret == False:
                        return ret,msg
            elif opposite:
                if v == d2[k]:
                    return False,f"[{k}]的值不应该等于[{v}]"
            else:
                if v != d2[k]:
                    return False,f"[{k}]的期望值:[{v}] != 实际值:[{d2[k]}]"
            
         return True,""                                                                                                                                                                                                                                                                                                                                                           
                            
    def iterdict_(d1,d2):
        if type(d1) != type(d2):
            return False,f"数据类型不同 {d1}={type(d1)},{d2}={type(d2)}"
             
        # isinstance-主要用来判断变量是否属于某个内建类型,对象的类型与参数二的类型相同则返回True,否则返回False
        if isinstance(d1,dict): # 如果预期值是字典格式则返回上面封装好的方法做判断                             
            return iterdict_dic(d1,d2)
        elif isinstance(d1,list): #如果预期值是列表格式则走下面方法
            if len(d1) > len(d2):
                return False,"列表长度不相等"
            # 循环列表断言列表值
            for i in range(0,len(d1)):
                ret,msg = iterdict_(d1[i],d2[i]) # 判断预期值是否等于实际值 
                if ret == False:
                    return ret,msg
                return True,""
         else:
            if d1 != d2:
                return False,"预期值-[{d1}] != 实际值-[{d2}]" # 判断预期值是否等于实际值 
             else:
                return True,""                                                                                           
    
    # 最后调用断言方法
    def iterdict(d1,d2):
        ret,msg = iterdict_(d1,d2)
        assert ret,msg
    
    

     3、测试封装的requests_方法是否达到预期
       1.新建文件test_iterdict
       2.测试request网络请求方法,可用自家公司接口测试

    在这里插入图片描述
       【Terminal】控制台输入pytest -s test_iterdict.py即可运行以test开头或结尾的用例,可在控制台打印接口请求的详细信息
    在这里插入图片描述
    4、测试iterdict断言方法,(挑几个演示一下,有兴趣的可以自行调试)
       预期值d1都出现在实际值d2中
    在这里插入图片描述
       d2中缺少字段在这里插入图片描述
       d1中值和d2实际值不相等在这里插入图片描述
       d1中值等于None则值判断键是否存在在这里插入图片描述
       键前面是?实际值中没有则跳过在这里插入图片描述
       键前面是?实际值中出现则验证
    在这里插入图片描述

     


    编写接口测试用例,使用pytest运行用例

    • pytest-文件名、函数名要以test_开头或以_test结尾,类名以Test开头或结尾,控制台输入pytest -s 文件名
      即会运行文件中以test为名的用例类或函数,更多pytest知识可看官方文档;

     1、不方便用公司接口做演示,自己写了一个简易的小接口来编写一下测试用例,然后启动服务就可以本机调用测试接口

    from flask import Flask,request
    
    app = Flask(__name__)
    
    """
        /api_test 接口路径
        请求参数:user:liuage    pwd:123456
        正常请求-返回值:{'rc':1,'msg':'登录成功'}
        异常请求-返回值:{'rc':999,'msg':'异常情况'}   
    """
    
    @app.route('/api_test',methods=['GET','POST'])
    def login_api():
        if request.method == "POST":
            data = eval(request.data)
            if 'user' not in data:
                return {'rc':-999,'msg':'账号不能为空'}
            if 'pwd' not in data:
                return {'rc':-999,'msg':'密码不能为空'}
            user = data['user']
            pwd = data['pwd']
    
            if user != 'liuage':
                return {'rc':-999,'msg':'请输入正确账号'}
            elif pwd != 123456:
                return {'rc':-999,'msg':'请输入正确密码'}
            else:
                return {'rc': 1, 'msg': '登录成功'}
        else:
            return {'rc':-999}
    
    if __name__ == '__main__':
        # ip地址填自己电脑的IP地址,如:192.168.2.3
        app.run('自己电脑IP地址',debug=True)
    

     2、编写接口测试用例

    from study.api_test import requests_
    from requests import Session
    
    s = Session()
    
    class Test_login():
    
        def setup_class(self):
            self.url = "http://192.168.22.50:5000/api_test"
            # 请求参数
            self.payload = {
                "user" : "liuage",
                "pwd" : 123456
            }
    
        # 测试接口正常请求情况
        def test_normal(self):
            # 调用网络请求
            result = requests_.request(s,self.url,self.payload)
    
            # 填入预期值
            fields = {
                "rc" : 1,
                "msg" : '登录成功'
            }
    
            # 断言返回值
            requests_.iterdict(fields,result)
    
        # 测试账号错误情况
        def test_account_error(self):
            payload = {
                'user' : '111',
                'pwd' : 123456
            }
            result = requests_.request(s,self.url,payload)
    
            fields = {
                'msg' : '请输入正确账号',
                'rc' : -999
            }
            requests_.iterdict(fields,result)
    
        # 测试密码错误情况
        def test_pwd_error(self):
            payload = {
                'user':'liuage',
                'pwd' : 12345
            }
            result = requests_.request(s,self.url,payload)
    
            fields = {
                'rc' : -999,
                'msg' : '请输入正确密码'
            }
            requests_.iterdict(fields,result)
    
        # 测试账号为空情况
        def test_not_account(self):
            payload = {'pwd':''}
            result = requests_.request(s,self.url,payload)
            fields = {'rc':-999,'msg':'账号不能为空'}
            requests_.iterdict(fields,result)
    

     3、【Terminal】终端输入pytest -s 用例文件名 运行用例在这里插入图片描述
      如果有一个用例没达到预期结果就会报错在这里插入图片描述


    感谢观看

    展开全文
  • requests+Pytest接口自动化测试实战(五)___相关视频系列涉及Python自动化测试、selenium、appium、jmeter、python、robotframework等。
  • requests+Pytest接口自动化测试实战(三)___相关视频系列涉及Python自动化测试、selenium、appium、jmeter、python、robotframework等。
  • 今日内容:接口自动化测试框架必会之pytest插件,运行规则以及参数,pytest.ini配置文 件,跳过用例,用例执行顺序,夹具等

    目录

    一、Pytest详解以及常用的插件安装

    二、Pytest默认的测试用例的规则

    三、Pytest用例运行方式以及参数

    1.命令行模式运行 命令:pytes

    2.主函数模式运行

    3.基于pytest.ini配置文件运行

    四、pytest测试用例的执行顺序

    五、pytest跳过测试用例

    六、pytest测试用例的前后置

    今日内容:接口自动化测试框架必会之pytest插件,运行规则以及参数,pytest.ini配置文 件,跳过用例,用例执行顺序,夹具等

    一、Pytest详解以及常用的插件安装

    1.pytest是一个非常成熟的基于python的单元测试框架(测试的是程序的最小单元:函 数,方法)

    • python:unittest和pytest
    • java:junit和testng

    2.pytest可以和所有的自动化测试工具或模块:selenium,requets,appium结合实现 web自动化,接口自动化,app自动化。

    3.它可以和allure插件生成美观以及定制化的报告以及和jenkins实现持续集成。

    4.pytest有很多强大的插件 pytest(自己)

    • pytest-html (生成简易的HTML报告)
    • pytest-xdist(多线程执行)
    • pytest-ordering(修改测试用例的执行顺序)
    • pytest-rerunfailures (失败用例重跑)
    • pytest-base-url(管理基础路径:测试环境,开发环境,线上环境)
    • allure-pytest(生成allure报告)

    放到一个requirements.txt的文件。一次行的安装所有的插件。

    命令如下:-r表示递归

    pip install ‐r requirements.txt

    5.pytest单元框架主要用来做什么?

    1. 发现测试用
    2. 执行测试用例
    3. 判断测试结果
    4. 生成测试报告

    二、Pytest默认的测试用例的规则

    1. 模块名(py文件)必须以test_开头或_test结尾
    2. 测试类必须以Test开头,并且不能带有init方法(初始化方法)
    3. 测试用例必须以test开头

    三、Pytest用例运行方式以及参数

    1.命令行模式运行

    命令:pytes

    参数: -vs

    -v 输出更加详细的测试用例的信息

    -s 输出用例中的调试信息

    示例:pytest -vs

    -n 多线程运行

            示例:pytest -vs -n 2

    --reruns 失败用例重跑

            示例:pytest -vs --reruns 2

    -x 一旦出现一个用例失败则终止测试。

            示例:pytest -x

    --maxfail 出现指定次数的错误则终止测试。

            示例:pytest -vs --maxfail 2

    --html 生成简易的html报告

            示例:pytest -vs --html=./reports/report.html

    -k 运行包含有指定字符串的测试用例(测试用例的名称必须很规范)

            test_usermanage_adduser

            test_usermanage_deluser

            test_usermanage_edituser

            示例:pytest -vs -k "mashang or jiaoyu"

    指定模块运行:pytest -vs ./testcases/test_weixin.py

    指定文件夹运行:pytest -vs ./testcases/weixin

    通过node id运行:pytest -vs

    ./testcases/weixin/test_weixin.py::TestApi::test_02_add_flag

    2.主函数模式运行

    if __name__ == '__main__':
        pytest.main(['‐vs']);

    3.基于pytest.ini配置文件运行

    • 配置文件的名称是固定的,一般放在项目的根目录下。
    • 作用是:可以改变pytest默认的测试用例的规则。
    • 不管是命令行的方式,还是主函数的方式都会自动的读取这个配置文件去运行。
    [pytest]
    #命令行参数
    addopts = -vs --html=./reports/report.html
    #指定测试用例的路径
    testpaths = ./testcases
    #指定测试模块的默认规则
    python_files = test_*.py
    #指定测试类的默认规则
    python_classes = Test*
    #指定测试用例的默认规则
    python_functions = test_*

    四、pytest测试用例的执行顺序

    默认的执行顺序是从上到下依次执行。

    改变测试用例的执行顺序可以使用插件:pytest-ordering

    五、pytest跳过测试用例

    1.无条件跳过

    @pytest.mark.skip(reason="这里写跳过的理由")

    2.有条件跳过

     @pytest.mark.skipif(age<5,reason="少于10年工作经验不考虑录取")
    

    六、pytest测试用例的前后置

    def setup_class(self):
        print("在类的前面执行的操作")
    
    def teardown_class(self):
        print("在类的后面执行的操作")
    
    def setup(self):
        print("测试用例执行之前的操作")
    
    def teardown(self):
        print("测试用例执行之后的操作")
    
    展开全文
  • 一、Python+unittest+requests+HTMLTestRunner 完整的接口自动化测试框架搭建_00——框架结构简解  首先配置好开发环境,下载安装Python并下载安装pycharm,在pycharm中创建项目功能目录。如果不会的可以百度Google...
  • 为什么要做接口自动化框架 1、业务与配置的分离 2、数据与程序的分离;数据的变更不影响程序 3、有日志功能,实现无人值守 4、自动发送测试报告 5、不懂编程的测试人员也可以进行测试 正常接口测试的流程是什么? ...
  • Python+Requests+Pytest 接口自动化测试脚本总结

    万次阅读 多人点赞 2020-04-07 14:28:05
    1. 封装post和get方法:方便在使用requests模块发送请求时,仅调用一个方法即可 备注:文件名均在脚本中的顶部,用”fileName“标识 #!/usr/bin/env python # -*- coding:utf-8 -*- # fileName: run_method.py ...

    目录

    一、框架搭建流程

    1. 封装接口请求

    2. 存储接口信息

    3. 封装登录和其他方法

    4. 使用Pytest管理测试用例

    5. 添加日志模块

    6. 生成测试报告

    7. 测试报告发送至邮箱

    8. 优化动态数据的存储

    9. 项目目录

    二、上传代码到github

    三、运行测试用例的两种方法

    1. 命令行模式

    2. 在python脚本中调用pytest

    四、重构接口自动化测试框架


    一、框架搭建流程

    1. 封装接口请求

    封装post和get方法方便在使用requests模块发送请求时,仅调用一个方法即可

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # fileName: run_method.py
    import requests
    
    
    class RunMethod(object):
    
        def post_main(self, url, headers, data):
            # 忽略不安全的请求警告信息
            requests.packages.urllib3.disable_warnings()
            # 遇到requests的ssl验证,若想直接跳过不验证,设置verify=False即可
            response = requests.post(url=url, headers=headers, data=data, verify=False)
            return response
    
        def get_main(self, url, headers, data=None):
            # 忽略不安全的请求警告信息
            requests.packages.urllib3.disable_warnings()
            response = requests.get(url=url, headers=headers, data=data, verify=False)
            return response
    
        def run_main(self, method, url, headers, data=None):
            # 忽略不安全的请求警告信息
            requests.packages.urllib3.disable_warnings()
            requests.adapters.DEFAULT_RETRIES = 5
    
            if method == "Post":
                res = self.post_main(url, headers, data)
            elif method == "Get":
                res = self.get_main(url, headers, data)
            # 将响应的的数据以字典数据结构和json数据格式返回
            return res.json()
    

    2. 存储接口信息

    使用yml文件作为配置文件,存储每一个接口信息,主要包括”接口名称、method、url、data和headers“,以及预期结果”expected“

    # fileName: api_config.yml
    
    host: https://XXX.com
    
    login:
      name: 【登录】手机号码登录
      method: Post
      url: /v1/login/
      data:
        phone_country: 86
        phone_number: 1210000000
        password: 123456
        device_id: XXX
        device_name: Iphone8plus
        device_pubkey: XXX
      headers:
        Content-Type: application/x-www-form-urlencoded
        Authorization: Basic XXX
    
    asset_main:
      name: 【资产】用户资产列表页
      method: Get
      url: /v2/main/
      headers:
        Authorization: Bearer
        app-version: 4.8.0
        device-id: XXX
      expected:
        success: true
    
    lend:
      name: 发送请求
      method: Post
      url: /v1/lend/
      data:
        payment_password: 123456
        amount: 100
        pledge_source: 1
      headers:
        Content-Type: application/x-www-form-urlencoded
        Authorization: Bearer
        device-id: XXX
        app-version: 4.8.0

    3. 封装登录和其他方法

       1)登录方法用于获取并存储token,存储至access_token.yml中;

       2)参数”api_name“的取值是配置文件api_config.yml中的接口名称,比如:login、asset_main和loan_lend。同样封装了一个类ReadYaml,方法是取配置文件中各接口的”method、url、data、headers和expected“等;

       3)除了登录接口,其他接口的headers均需要token值,所以在处理headers时要区分登录接口和其他接口;

       4)建议:添加异常处理捕获异常,输出自定义的错误信息。

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # fileName: app_api.py
    from common.run_method import RunMethod
    from common.read_info import ReadYaml
    from common.get_log import get_log
    from common.deal_token import write_token
    import json
    
    
    class AllApi(object):
        def __init__(self):
            self.run = RunMethod()
            self.read = ReadYaml()
            self.logger = get_log()
    
        # 登录,获取token
        def login(self, api_name):
            try:
                # 获取接口请求参数
                method = self.read.get_method(api_name)
                url = self.read.get_url(api_name)
                data = self.read.get_data(api_name)
                headers = self.read.get_headers(api_name)
                response = self.run.run_main(method, url, headers, data)
    
                # 把token值写到配置文件access_token.yml中,供其他接口调用
                write_token(response)
    
                print(json.dumps(response, indent=2, ensure_ascii=False, sort_keys=False))
                return response
            except Exception as e:
                self.logger.info("接口访问出错啦~ %s" % e)
    
        # 其他接口请求封装
        def send_request(self, api_name):
            try:
                # 获取接口请求参数
                method = self.read.get_method(api_name)
                url = self.read.get_url(api_name)
                headers = self.read.get_headers(api_name)
                # 区分Get和Post方法
                if method == "Get":
                    response = self.run.run_main(method, url, headers)
                elif method == "Post":
                    data = self.read.get_data(api_name)
                    response = self.run.run_main(method, url, headers, data)
                    # print(json.dumps(response, indent=2, ensure_ascii=False, sort_keys=False))
    
                print(json.dumps(response, indent=2, ensure_ascii=False, sort_keys=False))
                print(response["success"])
                return response
            except Exception as e:
                self.logger.info("接口访问出错啦~ %s" % e)
    
        # 获取预期结果,方便断言时直接使用
        def get_expect(self, api_name):
            try:
                # 获取配置文件中的预期结果
                expect = self.read.get_expected(api_name)
                # print(expect)
                return expect
            except Exception as e:
                self.logger.info("获取预期结果出错啦~ %s" % e)
    

    4. 使用Pytest管理测试用例

       1)在执行所有用例之前先执行登录接口,获取token。所以把登录接口的请求放在conftest.py文件中

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # fileName: conftest.py
    from API.all_api import AllApi
    import pytest
    from common.get_log import get_log
    logger = get_log()
    
    # 在执行所有用例之前先执行登录接口,获取token
    @pytest.fixture(scope="session")
    def init_token():
        # 正确邮箱/手机号和密码登录
        logger.info("\n ============================= 在所有用例执行之前,生成token =============================")
        all_login = AllApi()
        all_login.login("login_sandbox_phoneNumber")
    

      2) 把每个功能模块封装成一个类,每个用例封装成一个方法。例如资产模块的用例如下:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # fileName: test_asset.py
    from API.all_api import AllApi
    import pytest
    from common.get_log import get_log
    logger = get_log()
    
    
    # 资产模块的测试用例
    @pytest.mark.usefixtures("init_token")
    class TestAsset(object):
        @pytest.fixture(scope="class")
        def init_asset(self):
            logger.info("\n ==============================【资产】测试用例开始 ==============================")
            all_request = AllApi()
            return all_request
    
        @pytest.mark.parametrize("api_name", ["asset_main"])
        def test_asset_main(self, api_name, init_asset):
            print("\n 用例名称:获取资产列表信息\n")
            res = init_asset.send_request(api_name)
            expected = init_asset.get_expect(api_name)
            # 断言1:success的值为true
            assert res['success'] == expected['success'], "success的值为: %s" % res['success']
    
    
    if __name__ == "__main__":
        # pytest.main(['-v', 'test_asset.py'])
        pytest.main(['-v', 'test_asset.py', '--html=report/asset_report.html', '--self-contained-html'])

    5. 添加日志模块

       1)使用配置文件配置loggers、handlers和formatters(日志器、处理器和格式器),文件名称是log.conf

    [loggers]
    keys=root,main
    [logger_root]
    level=DEBUG
    handlers=consoleHandler,fileHandler
    [logger_main]
    level=DEBUG
    qualname=main
    handlers=fileHandler
    [handlers]
    keys=consoleHandler,fileHandler
    [handler_consoleHandler]
    class=StreamHandler
    level=DEBUG
    formatter=fmt
    args=(sys.stdout,)
    [handler_fileHandler]
    class=logging.handlers.RotatingFileHandler
    level=DEBUG
    formatter=fmt
    args=('../log/Wallet_API_Test.log','a')
    [formatters]
    keys=fmt
    [formatter_fmt]
    format=%(asctime)s - %(filename)s - %(levelname)s - [line:%(lineno)d] - %(message)s

       2)使用fileConfig()函数读取日志配置文件

    # fileName: get_log.py
    import logging.config
    import logging
    
    
    # 读取日志配置文件
    def get_log():
        con_log = "../configs/log.conf"
        logging.config.fileConfig(con_log)
        log = logging.getLogger()
        return log

    6. 生成测试报告

       1)安装pytest-html插件。也可以使用allure插件生成测试报告,但是如果pytest版本过高,就无法识别allure插件

       2)添加“--self-contained-html”可以整合样式文件到html文档中,方便之后发送测试报告到邮箱

    pytest.main(['-v', '--html=report/all_report.html', '--self-contained-html'])

    7. 测试报告发送至邮箱

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # fileName: run_email.py
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart
    from email.header import Header
    import smtplib
    
    
    # 定义发邮件
    def send_mail(file_path):
    
        f = open(file_path, 'rb')
        mail_body = f.read()
        f.close()
    
        smtpserver = 'smtp.qq.com'
        # 设置登录邮箱的账号和授权密码
        user = 'XXX@qq.com'
        password = ""
        sender = 'XXX@qq.com'
        # 可添加多个收件人的邮箱
        receives = ['XXX@qq.com']
        # 构造邮件对象
        msg = MIMEMultipart('mixed')
        # 定义邮件的标题
        subject = '接口自动化测试报告'
        # HTML邮件正文,定义成字典
        msg['Subject'] = Header(subject, "utf-8")
        msg['From'] = sender
        msg['To'] = ','.join(receives)
        # 构造文字内容
        text_plain = MIMEText("附件是最新的接口自动化测试报告,请查看", 'html', 'utf-8')
        msg.attach(text_plain)
        # 构造附件
        text_attr = MIMEText(mail_body, 'base64', 'utf-8')
        text_attr["Content-Type"] = 'application/octet-stream'
        text_attr['Content-Disposition'] = 'attachment; filename = "test.html"'
        msg.attach(text_attr)
    
        # 邮箱设置时勾选了SSL加密连接,进行防垃圾邮件,SSL协议端口号要使用465
        smtp = smtplib.SMTP_SSL(smtpserver, 465)
        # 向服务器标识用户身份
        smtp.helo(smtpserver)
        # 向服务器返回确认结果
        smtp.ehlo(smtpserver)
        # 登录邮箱的账号和授权密码
        smtp.login(user, password)
    
        print("开始发送邮件...")
        # 开始进行邮件的发送,msg表示已定义的字典
        smtp.sendmail(sender, receives, msg.as_string())
        smtp.quit()
        print("已发送邮件")
    
    
    if __name__ == "__main__":
        report = "../testcase/report/report.html"
        send_mail(report)

    8. 优化动态数据的存储

    把多个登录账号信息等动态数据放到excel表格中,使用xrld和xlutils库对表格进行读取和写入。利用excel存储测试数据,实现测试数据和测试脚本的分离,方便测试数据的维护

    9. 项目目录

    一直在更新中,文件名可能与其他地方不一致

    二、上传代码到github

    1. 创建git仓库:进入项目的根目录,比如项目名是:Test,则进入Test文件夹下

    命令:git init

    2. 将项目内所有文件添加至仓库中

    命令:git add .

    3. commit到仓库

    命令:git commit -m '首次提交'

    4. 到github上创建Repositories后,复制仓库的地址,比如:https://github.com/XXX/Test.git

    5. 将本地仓库关联到github上(很重要)

    命令:git remote add origin https://github.com/XXX/Test.git

    6. 上传代码到github远程仓库:其中-u是把本地master分支和远程master分支关联起来,以后再push时不需要加上-u

    命令:git push -u origin master

    7. 若再次上传,则要执行这三步:

        1)把Test中的文件都添加进来:git add .

        2)提交暂存区的文件,其中message是简要说明这次提交的信息:git commit -m "message"

        3)把本地文件推送到github上(有时候需要输入github账号和密码): git push origin master

    8. git常用命令,可参考文章git常用命令结合若干个使用场景

    9. 项目git地址:(备注:代码写的不够专业,一直在优化改进中。有兴趣的可以一起讨论)

    https://github.com/ChangYixue/Test.git

    三、运行测试用例的两种方法

    1. 命令行模式

      1)先进入测试用例文件所在目录,然后使用“pytest”命令执行该目录下所有的测试用例文件;

      2)也可以指定某一个测试用例文件,直接在pytest后面加上文件名称即可,比如“pytest test_asset.py” 

      3)执行”某文件下的类中所有用例方法“或者”某方法“,分别用命令”pytest 文件名::类名“和”pytest 文件名::类名::方法名“

    2. 在python脚本中调用pytest

    if __name__ == "__main__":
        # 若存在多个标记,则用or连接,形成一个测试集,比如'-m=assetList or test or allLists'
        pytest.main(['-v', 'test_asset.py', '-m=test'])

    四、重构接口自动化测试框架

    1. 背景:公司开发人员帮忙重构了脚本,使配置测试环境、维护测试数据、取接口信息和处理接口依赖等更加灵活

    2. 重构后的框架简介请移步:Python+Pytest+tox 接口自动化测试框架

    未完待续......

    展开全文
  • Pytest接口自动化
  • requests+Pytest接口自动化测试实战(四)___相关视频系列涉及Python自动化测试、selenium、appium、jmeter、python、robotframework等。
  • requests+Pytest接口自动化测试实战(二)___相关视频涉及Python自动化测试、selenium、appium、jmeter、python、robotframework等。
  • 本框架采用Pytest+Allure+Requests实现,run.py为主运行文件,共实现以下三个功能: 1.爬取yapi接口文档生成测试用例数据yaml模板 2.编辑测试数据yaml模板,自动生成case_suite的py文件 3.调用核心装饰器方法@call_...
  • 前段时间公司业务需要,准备把之前的接口自动化的脚本整理一下,把之前的冗长的代码整理成一个个的用例,这样代码的可读性就变得高了,而且相应的维护的成本降低。我们用到的是Pytest框架,关于框架的介绍及优点我...
  • 搭建接口自动化测试框架 目录分层: 1.common:放置常用公共方法,例如:操作yaml文件的模块、读取配置文件模块等 2.config:存放配置文件:例如:config.ini文件 3.logs:存放日志文件 4.report:存放生成的报告 5....
  • pytest框架进行接口自动化

    千次阅读 2021-12-24 21:47:47
    pytest框架进行接口自动化 1、框架目录结构介绍 目录结构图 1、公共目录(主要放请求发送工具文件,读取yaml文件工具等) 请求发送工具文件:send_request_util.py 读取yaml工具文件: yaml_util.py 2、报告目录...
  • python+requests+pytest+yaml+热加载+allure+logs 框架代码已封装 小白 3行代码即可实现接口自动化
  • Python+pytest+requests 自动化测试框架

    千次阅读 2022-01-18 17:49:57
    本次选用的是Python+Pytest+requests来搭建自动化框架,需要有 Python 环境(3.x 版本),安装pytestrequests,不会安装的自行去网上搜教程。 关于 Pytest 的基本使用,这里不作讲解,不清楚的可以看我之前的文章...
  • pytest-接口自动化实战

    2021-04-28 13:00:26
    import requests from lib.apiLib.login import Login class Shop: def __init__(self,inToken): self.headers = {'Authorization':inToken}#身份信息校验--鉴权 #1- 列出店铺 def shop_list(self,inData): ur
  • 内容:Pytest测试框架之Allure报告定制以及Parametrize数据驱动
  • python+request+pytest+auller 搭建接口自动化测试框架

    千次阅读 多人点赞 2021-03-18 10:46:33
    接口自动化测试框架 一、项目目录 项目整体框架分为6个模块公共方法(common)配置模块(conf)测试用例(data)日志(log)测试报告(report)测试套件(test_case) 启动项目运行主函数(main)即可 主函数代码 #...
  • pytest接口自动化测试框架搭建

    千次阅读 2022-03-04 20:52:09
    文章目录 目录 ...最近自己也抽时间梳理了一份pytest接口自动化测试框架,因此准备写文章记录一下,做到尽量简单通俗易懂,当然前提是基本的python基础已经掌握了。如果能够对新学习这个框架的同
  • 测试一条数据 先下载一个模块 requests pip install requests 然后新创一个文件夹,创一个py文件,先用百度的来获取 然后用聚合函数上面的真实数据做一个模拟的,就...然后导入刚刚写的那个包名,实例刚刚那个包
  • requests+pytest+allure接口自动化测试 步骤流程 1.读取文件中的数据 2.requests拿到数据请求接口返回状态码 3.通过断言验证返回状态码和200对比 4.生成allure的测试报告 先从聚合数据里面寻找两个或两个以上的接口...
  • 这篇文章主要介绍了python使用pytest接口自动化测试的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 ,多多支持 攻粽号 "软件测试...
  • 2.get请求接口,拿到返回值 1)url和params拼接 import requests a=['https://apis.map.qq.com/ws/place/v1/search',{"keword": "酒店", "boundary": "nearby(39.908491,116.374328,1000)","key": "RTVBZ-IB4R6-...
  • 完整的框架源码下载...一、Python+unittest+requests+HTMLTestRunner 完整的接口自动化测试框架搭建_00——框架结构简解 首先配置好开发环境,下载安装Python并...
  • pytest接口自动化框架搭建

    千次阅读 2021-09-07 10:41:56
    目标:最终完成一个用jenkins集成或用django,达到一个自由灵活可复用的接口自动化测试框架 一、设计思路-整体框架: 接口自动化测试之框架搭建步骤——思路整理 1.先搭建框架主干 config:存放配置文件,如ini文件...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,625
精华内容 1,050
关键字:

pytest requests接口自动化