pytest+yaml+allure接口自动化测试框架

自动化测试,是目前测试行业一项比较普遍的测试技术了,之前的以UI自动化测试为主,现在的以接口自动化测试为主,无论技术更迭,自动化测试总有他的重量,用机器代替手工工作,是21世纪不断进行的课题。

可是身为测试,难受的是脚本容易写,学几天python,照猫画虎三两天也能写一个不错的脚本。可是想更上一层,去搭建一个测试框架却显得不是那么容易,曾经我也是这样的困难。时光不负有心人,学习了漫长时间终于是现在有了一些开发基础,抽空搞了一个简单版本的接口自动化测试框架。

希望我的框架能给予你一定启发的同时,你也能指出一些我的不足之处,互相学习,我们才能共同进步。

环境搭建

目录文件添加

我们打开vscode新建一个项目,名字就姑且命名为:interface_test_example, 创建好之后,我们就按照这个下面这个目录结构去创建相应的文件内容。

.
├── common                        ——公共方法目录
│   ├── cache.py                ——缓存文件
│   ├── exceptions.py            ——异常处理
│   ├── __init__.py                
│   ├── json.py                    ——序列化和反序列化
│   ├── regular.py                ——正则处理
│   ├── request.py                ——请求处理
│   └── result.py                ——响应处理
├── conftest.py                    ——pytest胶水文件
├── environment.properties        ——allure配置文件
├── logs                        ——日志目录
├── main.py                        ——主运行文件
├── pytest.ini                    ——pytest配置文件
├── readme.md                    
├── requirements.txt    
├── tests                        ——测试用例目录
│   └── testcase.yaml
└── utils                        ——第三方工具文件
    ├── __init__.py    
    ├── logger.py                ——日志
    ├── readme.md
    └── time.py                    ——时间处理

    当你把上面这些内容创建完成之后我们的项目内容就算整体创建完成了。

    python虚拟环境创建

    在创建之前我先声明一下我所使用的python版本是3.8.6版本。学习本篇请不要使用3.8版本以下python,某些语法会不支持。

    1、创建虚拟环境

    python3 -m venv env
    

      2、 安装requirements.txt的依赖包

      pip install -r requirements.txt
      

        requirements.txt的具体内容

        allure-pytest==2.9.43
        allure-python-commons==2.9.43
        pytest==6.2.5
        pytest-assume==2.4.3
        pytest-html==3.1.1
        PyYAML==5.4.1
        requests==2.26.0
        

          安装完成之后我们的环境就搭建好了。

          测试用例管理

          excel这种总归是太麻烦了,所以我们需要一个更合适的。挑来选去yaml是最简单方便的,数据能几乎无缝切换。

          先来看看我们的用例吧,都写了些什么。打开tests/testcase.yaml文件,输入以下内容。

          config: # 测试信息
            baseurl: "https://www.zhixue.com"
            timeout: 30.0
            headers:
              Accept: application/json, text/javascript, */*; q=0.01
              Accept-Encoding: gzip, deflate, br
              Accept-Language: zh-CN,zh;q=0.9
              Connection: keep-alive
              User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
              cookies: aliyungf_tc=AQAAANNdlkvZ2QYAIb2Q221oiyiSOfhg; tlsysSessionId=cf0a8657-4a02-4a40-8530-ca54889da838; isJump=true; deviceId=27763EA6-04F9-4269-A2D5-59BA0FB1F154; 6e12c6a9-fda1-41b3-82ec-cc496762788d=webim-visitor-69CJM3RYGHMP79F7XV2M; loginUserName=18291900215
              X-Requested-With: XMLHttpRequest
          variable:
            none : none
          tests:
            test_login:
              description: "登录"
              method: post
              route: /weakPwdLogin/?from=web_login
              RequestData:
                data:
                  loginName: 18291900215
                  password: dd636482aca022
                  code:
                  description: encrypt
              Validate:
                expectcode: 200
                resultcheck: '"result":"success"'
                regularcheck: '[\d]{16}'
              Extract:
                - data
            test_login_verify:
              description: "验证登录"
              method: post
              route: /loginSuccess/
              RequestData:
                data:
                  userId: "${data}"
              Validate:
                expectcode: 200
                regularcheck:
                resultcheck: '"result":"success"'
          

            第一部分config内容:主要是一些全局的配置信息,如请求地址、请求头等。

            第二部分variable内容:主要是预先设置一些全局变量等等内容。比如可以加入邮箱地址等等。

            第三部分tests内容:这个是真正的测试用例部分,通过匹配requests库的输入参数,以简洁明了的写法更好的支持测试。

            日志封装

            打开utils/logger.py文件,这个utils的意思是一个工具包的意思。在这个里面我们主要存放可以独立运行的工具模块。比如日志文件就是一个可以独立运行的。打开之后我们输入以下的内容:

            # -*- coding: utf-8 -*-
            __author__ = 'wxhou'
            __email__ = '1084502012@qq.com'
            """
            日志类
            """
            import os
            import logging
            from logging.handlers import RotatingFileHandler
            
            
            def init_logger():
                """初始化日志"""
                basedir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
                debug_file = os.path.join(basedir, 'logs', 'server.log')
            
                logger_formatter = logging.Formatter(
                    '%(levelname)s %(asctime)s [%(filename)s:%(lineno)s] %(thread)d %(message)s')
            
                # debug
                logger_debug = logging.getLogger('apitest')
                handler_debug = RotatingFileHandler(debug_file,
                                                    encoding='utf-8',
                                                    maxBytes=20 * 1024 * 1024,
                                                    backupCount=10)
                handler_debug.setFormatter(logger_formatter)
                logger_debug.setLevel(logging.DEBUG)
                logger_debug.addHandler(handler_debug)
                # 在控制台输出
                return logger_debug
            
            
            logger = init_logger()
            
            if __name__ == '__main__':
                logger.debug("debug")
                logger.info("info")
                logger.warning('warning')
                logger.error("error")
                logger.critical('critical')
            

              下面一些日志输入示例。我们来执行一下。

              可以看到成功的在日志文件中写入了新的信息。

              缓存工具

              是的你没看错,我给它起的名字就叫缓存,其实内部组成本质就是一个python字典。而不是你想的redis这种。

              打开common/cache.py文件,我们输入以下内容。

              # -*- coding: utf-8 -*-
              __author__ = 'wxhou'
              __email__ = '1084502012@qq.com'
              """
              缓存类
              """
              from collections import UserDict
              
              
              class CachePool(UserDict):
                  """全局变量池"""
              
                  def get(self, key, default=None):
                      return self.data.get(key, default)
              
                  def set(self, key, value = None):
                      self.data.setdefault(key, value)
              
                  def has(self, key):
                      return key in self.data
              
                  def __len__(self):
                      return len(self.data)
              
                  def __bool__(self):
                      return bool(self.data)
              
              
              cache = CachePool()
              
              if __name__ == '__main__':
                  cache.set('name', 'wxhou')
                  print(len(cache))
                  print(cache.get('name'))
              

                我们执行测试一下:

                可以看到没有问题。通过这个字典我们把一些临时的信息放在这个里面,因为只是示例项目,用redis显得有些麻烦,采用这种方式更为简便一些。

                读取yaml测试用例

                使用yaml作为测试用例,我们就需要对文件的内容进行读取,常规来说的应该是通过pyyaml对读取到的内容进行数据解析,然后使用pytest parametrize参数化功能进行数据参数化用例测试。但是完事之后,这样的方式好像不是很优雅,写的代码组织起来比较费劲,于是乎,我在pytest的官方文档中,发现了一套更为一套非常优雅的测试执行方式,他们称之为non-python test的测试模式。

                具体内容可以查看官方文档,感兴趣的可以去看看:Working with non-python tests — pytest documentation
                https://docs.pytest.org/en/6.2.x/example/nonpython.

                评论
                添加红包

                请填写红包祝福语或标题

                红包个数最小为10个

                红包金额最低5元

                当前余额3.43前往充值 >
                需支付:10.00
                成就一亿技术人!
                领取后你会自动成为博主和红包主的粉丝 规则
                hope_wisdom
                发出的红包
                实付
                使用余额支付
                点击重新获取
                扫码支付
                钱包余额 0

                抵扣说明:

                1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
                2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

                余额充值