接口自动化框架实现

api_keys

api_keys.py

'''
    接口的关键字驱动类底层:
        1. 核心还是基于requests来实现的。
        2. 整体还是以模拟请求为主
        3. 响应的获取与解析
    接口关联解决手段只有两种:
        1. 将关联数据写入文件之中:适合相对于业务复杂程度更高的接口测试。
        2. 将关联数据作为全局变量:适合关联数据相对较少的接口测试。
'''
import json

import jsonpath
import requests

from class33_interface_auto.conf import set_conf


class Api:
    # get请求:需要在方法中将常见的参数定义好
    def do_get(self, path=None, params=None, headers=None, **kwargs):
        # 获取url
        url = self.set_url(path)
        # 获取headers
        headers = self.set_headers(headers)
        return requests.get(url=url, headers=headers, params=params, **kwargs)

    # post请求
    def do_post(self, path=None, data=None, headers=None, json=1, **kwargs):
        # 获取url
        url = self.set_url(path)
        # 获取headers
        headers = self.set_headers(headers)
        # 发送post请求
        if json == 1:
            response = requests.post(url=url, headers=headers, json=data, **kwargs)
        else:
            response = requests.post(url=url, headers=headers, data=data, **kwargs)
        return response

    # 拼接URL
    def set_url(self, path):
        url = set_conf.read_conf('SERVERS', 'TESTS')
        if path:
            url = url + path
        return url

    # 拼接headers
    def set_headers(self, headers):
        base_headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                          "Chrome/115.0.0.0 Safari/537.36"
        }
        if headers:
            # 如果用户传入新的headers值,则拼接在原有的base_headers之后
            base_headers.update(headers)
        if set_conf.read_conf('HEADERS', 'access-token'):
            print(1)
            access_token = set_conf.read_conf('HEADERS', 'access-token')
            base_headers['access-token'] = access_token

        return base_headers

    # 获取文本信息
    def get_text(self, text, key):
        text = json.loads(text)
        values = jsonpath.jsonpath(text, key)
        if values:
            if len(values) == 1:
                return values[0]
        return values

    # 断言校验
    def assert_text(self, expected, text, key):
        reality = self.get_text(text, key)
        assert expected == reality, f'''
            预期结果:{expected}
            实际结果:{reality}
            断言结果:{expected} != {reality}
        '''

conf

conf.ini

[SERVERS]
devs = http://www.baidu.com/
tests = http://apihcc.fecmall.com/
online = http://www.jd.com/

[HEADERS]
access-token = 

[BODY]
body = 

set_conf.py

'''
    配置和读取配置文件的内容,方便自动化测试的正常执行
'''
import configparser
import pathlib

# 获取配置文件
file = pathlib.Path(__file__).parents[0].resolve() / 'conf.ini'


# 配置项的读取
def read_conf(section, option):
    conf = configparser.ConfigParser()
    conf.read(file)
    values = conf.get(section, option)
    return values


# 配置项的写入
def write_conf(section, option, value):
    conf = configparser.ConfigParser()
    conf.read(file)
    # 将指定的内容写入到conf之中
    conf.set(section, option, value)
    # 将写入操作进行保存
    with open(file, 'w') as f:
        conf.write(f)

 test_cases

test_api.py

'''
    接口测试用例
'''
import unittest

from ddt import file_data, ddt

from class35_interface_pytest.api_keys.api_keys import Api
from class35_interface_pytest.conf import set_conf


@ddt
class TestApi(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        cls.api = Api()

    # 清空测试过程中产生的数据内容
    @classmethod
    def tearDownClass(cls) -> None:
        set_conf.write_conf('HEADERS', 'access-token', '')

    # 登录
    # @file_data('../test_data/login.yaml')
    @file_data('../test_data/languages.yaml')
    def test_01_login(self, **kwargs):
        data = kwargs['login']
        res = self.api.do_post(path=data['path'], data=data['data'])
        txt = self.api.get_text(res.text, 'access-token')
        # 将access-token写入到文件之中
        set_conf.write_conf('HEADERS', 'access-token', txt)
        print(res.text)
        self.api.assert_text(data['expected'], res.text, 'status')

    # 获取多语言list
    # @file_data('../test_data/getList.yaml')
    @file_data('../test_data/languages.yaml')
    def test_02_getList(self, **kwargs):
        data = kwargs['get_list']
        res = self.api.do_get(path=data['path'])
        print(res.text)
        self.api.assert_text(data['expected'], res.text, 'code')


if __name__ == '__main__':
    unittest.main()

test_demo.py

'''
    全局变量的形态实现关联接口的数据传递:
        全局变量的形态实现接口关联业务,最大的问题在于关联数据的传递会很麻烦。推荐自定义封装赋值的操作行为,减少赋值的工作量
'''

import unittest

import requests
from ddt import file_data, ddt


@ddt
class TestDemo(unittest.TestCase):
    # 将关联数据和yaml中对应的数据进行关联,实现自动赋值
    def assignment(self, values):
        # 对yaml中的字典进行解析,有值的不再二次处理,无值的需要进行赋值操作
        for key, value in values.items():
            # 如果value是字典则继续解析到最终形态,如果不是字典则停止解析
            if type(value) is dict:
                self.assignment(value)
            else:
                # 解析到最后,value只会有有值和无值两种情况
                if value:  # 有值则不作任何操作
                    pass
                else:  # 无值情况下,进行赋值操作
                    values[key] = getattr(self, key)
        return values

    @classmethod
    def setUpClass(cls):
        cls.token = None
        cls.ida = None
        cls.name = None
        cls.age = None
        cls.hcc = None

    def test_01_login(self):
        TestDemo.token = 'token'
        TestDemo.ida = 'ida'
        TestDemo.name = 'name'
        TestDemo.age = 'age'
        TestDemo.hcc = 'hcc'

    # @file_data('../test_data/test.yaml')
    # def test_02_getToken(self, **kwargs):
    #     kwargs['headers']['token'] = self.token
    #     kwargs['data']['name'] = self.name
    #     kwargs['data']['ida'] = self.ida
    #     kwargs['data']['hcc'] = self.hcc
    #     kwargs['data']['age'] = self.age
    #     print(kwargs)


    @file_data('../test_data/test.yaml')
    def test_02(self, **kwargs):
        print(self.assignment(kwargs))


if __name__ == '__main__':
    unittest.main()

test_data

getList.yaml

-
  path: v1/languages
  expected: 200

languages.yaml

-
  login:
    path: v1/account/login
    data:
      username: admin
      password: admin123
    expected: success
  get_list:
    path: v1/languages
    expected: 200

login.yaml

-
  path: v1/account/login
  data:
    username: admin
    password: admin123
  expected: success

test.yaml

-
  path: /hcc
  headers:
    token:
  data:
    name:
    ida:
    age:
    hcc:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值