pytest+requests+allure实现接口自动化测试系列(9)-封装自己的断言

接着上一篇分享

上一篇分享了接口之间的数据依赖,我们的测试结构数据,还有一部分没有说明,就是断言这一部分,下面的数据结构,我设计的需要断言的放在

validate这个地方,每一项是一个字典,键是响应的jsonpath,值是预期结果,同时声明了断言的类型,整体是一个列表。

代码语言:javascript
复制
  - testCase:
      description: login success
      name: login
      method: post
      uri: "https://api2.mubu.com/v3/api/user/phone_login"
      headers:
        Content-Type: application/json
      payload:
        phone: "135288728ddd"
        password: "Aa12345678"
        callbackType: 0
      extract:
        token: $.data.token
      validate:
         - equal_to:
            $.code: 0
         - equal_to:
            $.code: 0
  - testCase:
      description: profile
      name: profile
      method: post
      uri: "https://api2.mubu.com/v3/api/user/profile"
      headers:
        Content-Type: application/json
        jwt-token: ${token}
      payload: {}
      validate:
        - equal_to:
            $.code: 0
        - equal_to:
            $.code: 0

如果用pytest自带的断言进行封装,可能会比较麻烦点,所以我用了一个第三方的断言库hamcrest,通过pip install PyHamcrest进行安装,我们在utils.py,新增函数validate,代码如下

代码语言:javascript
复制
 from hamcrest import *
    @staticmethod
    def validate(validate_list: list, response):
        for validate in validate_list:
            for key, item in validate.items():
                for key_json_path, item_expect in item.items():
                    logger.info(f"预期结果的值是{item_expect}")
                    actual_val = jsonpath.jsonpath(response, key_json_path)[0]
                    logger.info(f"获取真实值是{actual_val}")
                    if key == "equal_to": # 断言相等
                        assert_that(actual_val, equal_to(item_expect))
                    elif key == "less_than":
                        assert_that(actual_val, less_than(item_expect))
                    elif key == "greater_than":
                        assert_that(actual_val, greater_than(item_expect))
                    elif key == "has_length":
                        assert_that(actual_val, has_length(item_expect))
                    elif key == "has_string":
                        assert_that(actual_val, has_string(item_expect))
                    elif key == "greater_than_or_equal_to":
                        assert_that(actual_val, greater_than_or_equal_to(item_expect))
                    elif key == "less_than_or_equal_to":
                        assert_that(actual_val, less_than_or_equal_to(item_expect))
                    else:
                        logger.info("-------暂时不支持该断言方法---------")

重新修改下断言的字段,第一个接口增加了手机号这个字段的验证,如下:

代码语言:javascript
复制
  - testCase:
      description: login success
      name: login
      method: post
      uri: "https://api2.mubu.com/v3/api/user/phone_login"
      headers:
        Content-Type: application/json
      payload:
        phone: "13528872ssss2"
        password: "Aa12345678"
        callbackType: 0
      extract:
        token: $.data.token
      validate:
         - equal_to:
            $.code: 0
         - equal_to:
            $.data.phone: "135288ssss802"
  - testCase:
      description: profile
      name: profile
      method: post
      uri: "https://api2.mubu.com/v3/api/user/profile"
      headers:
        Content-Type: application/json
        jwt-token: ${token}
      payload: {}
      validate:
        - equal_to:
            $.code: 0

重新修改下之前的测试用例如下:

代码语言:javascript
复制
#!/usr/bin/python
# -*- coding: utf-8 -*-
import pytest
from common.request_handler import request_handler
from common.yamlRead import read_yaml
from common.utils import Utils
from common.logger import logger

class Testrequests:
@pytest.mark.parametrize('test_data', read_yaml('../testData/login.yml'))
def test_requests(self, test_data):
request_data = test_data['testCase']
request_data = Utils.handle_request_data(request_data)
method = request_data['method']
headers = request_data['headers']
url = request_data['uri']
data = request_data['payload']
logger.debug(request_data)
response = request_handler(method, url, headers, data)
logger.debug(response)
if 'extract' in request_data:
Utils.extract(request_data['extract'], response)
if 'validate' in request_data:
validate_list = request_data['validate']
Utils.validate(validate_list, response)

运行测试用例,结果如下:

我们看到已经对所有的字段进行断言了,但是我们测试用例有的地方可以进行优化,可已经提取和发送请求放在一个函数里面,在request_handler这个文件里面增加函数

代码语言:javascript
复制
def request_from_request_data(request_data: dict):
    """
:param base_url: 请求域名
:param request_data: 请求数据
:return: 返回响应
"""
request_data = Utils.handle_request_data(request_data)
method = request_data['method']
headers = request_data['headers']
url = request_data['uri']
data = request_data['payload']
response = request_handler(method, url, headers, data)
if 'extract' in request_data:
    Utils.extract(request_data['extract'], response)
return response</code></pre></div></div><p>再次修改用例如下,代码比上面更加简洁一点。

代码语言:javascript
复制
#!/usr/bin/python
# -*- coding: utf-8 -*-
import pytest
from common.request_handler import request_from_request_data
from common.yamlRead import read_yaml
from common.utils import Utils
from common.logger import logger

class Testrequests:
@pytest.mark.parametrize('test_data', read_yaml('../testData/login.yml'))
def test_requests(self, test_data):
request_data = test_data['testCase']
request_data = Utils.handle_request_data(request_data)
response = request_from_request_data(request_data)
if 'validate' in request_data:
validate_list = request_data['validate']
Utils.validate(validate_list, response)

今天分享到这里!