接口自动化测试框架Plus

api.keys

api_keys.py

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

import jsonpath
import requests

from class35_interface_pytest.conf import set_conf


class Api:
    def __init__(self, env):
        self.env = env

    # 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)
        # print(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', self.env)
        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'):
            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 = 

read_yaml.py

'''
    读取yaml文件中的数据内容,作为测试数据的导入
'''
import yaml


# yaml文件中的内容获取
def read(path):
    with open(path, 'r', encoding='utf-8') as file:
        values = yaml.load(stream=file, Loader=yaml.FullLoader)
        return values

# print(read('../test_data/login.yaml'))

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)

# 配置项内容的清空
def clear_conf():
    pass

demo

demo.py

'''
    数据加密:
        1. MD5加密
'''
import base64
import hashlib


# 进行md5加密
# md5 = hashlib.md5()
# pwd = 'hcc123456'  # 需要加密的数据
# md5.update(pwd.encode('utf-8'))  # 对数据进行加密操作
# print(md5.hexdigest())  # 输出加密后的数据


# md5加密封装
def md5(value):
    md = hashlib.md5()
    md.update(value.encode('utf-8'))
    return md.hexdigest()


# print('准备测试数据')
# print('接口的密码数据加密执行')
# pwd = md5('hcchcchcc')
# print('数据加密后的结果:' + pwd)
# print('下发请求,传递加密后的数据包至对应请求')

# base64转码
url = 'hcc is 最棒的'
url = url.encode('utf-8')
print(url)

# 基本的base64转码
# a = base64.b16encode(url)
# # 转码后的数据
# print(a)
# print(str(a)[2:-1])
# b = base64.b32encode(url)
# print(b)
c = base64.urlsafe_b64encode(url)
print(c)

d = base64.urlsafe_b64decode(c)
print(d.decode('utf-8'))

test_cases

conftest.py

'''
    conftest用于定义常用的Fixture:
        如果conftest不生效,则将该文件直接放到test_cases路径下即可。
        pytest测试用例管理的核心点在于conftest中,可以极大节省我们的维护时间成本
'''
import pytest

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


# 生成api对象
@pytest.fixture(scope='session')
def api():
    return Api('tests')


@pytest.fixture(scope='session')
def devs_api():
    return Api('devs')


@pytest.fixture(scope='session')
def tests_api():
    return Api('tests')


@pytest.fixture(scope='session')
def online_api():
    return Api('online')


# 清空测试过程中生成的脏数据
@pytest.fixture(scope='session')
def clear(request):
    def clear_finalizer():
        set_conf.write_conf('HEADERS', 'access-token', '')

    request.addfinalizer(clear_finalizer)

test_fecmall.py

'''
    fecmall的基于pytest实现的测试用例管理:
        1. 设置conftest.py
        2. 测试用例的流程设计
        3. allure测试报告的相关内容,包含常见的装饰器的调用

    fecmall业务是:登录——获取多语言list——获取货币list
'''
import os

import allure
import pytest

from class35_interface_pytest.conf import set_conf
from class35_interface_pytest.conf.read_yaml import read


# 登录测试用例的设计
@allure.epic('实现fecmall从登录到获取语言与货币list的流程')
@allure.feature('基于access-token的数据获取')
@allure.story('实现fecmall登录流程')
@allure.title('用户登录,获取access-token')
@allure.step('登录操作步骤')
@pytest.mark.parametrize('data', read('../test_data/login.yaml'))
def test_login(api, data):
    with allure.step('请求登录接口,获取响应结果'):
        res = api.do_post(**data['request_data'])
        print(res.text)
    with allure.step('断言校验登录是否成功'):
        api.assert_text(data['expected'], res.text, 'status')
    with allure.step('将access-token数据添加到conf.ini文件之中'):
        set_conf.write_conf('HEADERS', 'access-token', api.get_text(res.text, 'access-token'))


# 获取多语言list
@allure.epic('实现fecmall从登录到获取语言与货币list的流程')
@allure.feature('基于access-token的数据获取')
@allure.story('实现fecmall获取多语言list')
@allure.title('获取多语言list')
@allure.step('调用多语言接口')
def test_languages(api):
    with allure.step('请求获取多语言list操作'):
        res = api.do_get(path='/v1/languages')
    with allure.step('展示响应结果'):
        print(res.text)


# 获取货币list
@allure.epic('实现fecmall从登录到获取语言与货币list的流程')
@allure.feature('基于access-token的数据获取')
@allure.story('实现fecmall获取货币list')
@allure.title('获取货币list')
@allure.step('调用货币接口')
def test_money(api):
    with allure.step('请求获取货币list操作'):
        res = api.do_get(path='/v1/currency')
    with allure.step('展示响应结果'):
        print(res.text)


def test_end(clear):
    pass


if __name__ == '__main__':
    pytest.main(['-sv', '--alluredir=../allure_report/'])
    os.system('allure generate ../allure_report -o ../report --clean')

test_data

login.yaml

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值