python接口篇-python框架搭建

一、框架介绍

python接口自动化采用的框架是:python+request+pytest+excel/yaml+allure

python接口篇-python框架搭建_第1张图片
config:存放config.ini配置文件。
org_business:需要进行测试的接口极其参数。
org_data:这里将测试数据放在excel中,通过read_data方法读取。
org_logs:生成的日志文件。
org_report:存放生成的测试报告。
org_testcase:存放测试用例。
conftest.py:存放了一些通用方法(读Excel数据,比较json串等)。
pytest.ini:主配置文件,可以改变pytest的默认行为。
requirements.txt:项目依赖包。
run_org_api:主程序入口,执行测试用例

二、框架详解

1、allure下载及环境变量配置

(1)下载allure(前提:电脑需要安装jdk,linux安装Linux搭建测试环境)
1)下载allure-commandline并解压,下载地址:
Central Repository: io/qameta/allure/allure-commandline
python接口篇-python框架搭建_第2张图片
(2)配置环境变量
python接口篇-python框架搭建_第3张图片
python接口篇-python框架搭建_第4张图片
  1. Common目录(公共方法)

主要是针对使用频率较高的方法进行第一次封装。例如:请求方法、基本配置读取、DEBUG日志获取、发送邮件、业务流封装、数据库操作等都可以放在此模块。

编号

脚本名称

脚本描述

1

__init__.py

2

db_opera.py

数据库的基础操作包含

1、数据库连接方法

2、sql语句执行方法

3

logger.py

日志模块:定义日志的输出目录、格式、内容

4

read_basic_conf.py

读取配置文件basicConf.ini并转换列表展示

5

reload_yaml.py

yaml文件解析

1、yaml文件读取

2、yaml文件中变量数据替换

6

send_email.py

打包测试结果发送邮件【暂时用不到】


import requests
from logging import config, getLogger
from AotoInterfaceTest.conf import logsettings

config.dictConfig(logsettings.LOGGING_DIC)
log = getLogger('log_msg')


class RequestsMethod(object):

    def post_requests(self, url, headers, data):
        # 忽略不安全的请求警告信息
        # requests.packages.urllib3.disable_warnings()
        # 遇到requests的ssl验证,若想直接跳过不验证,设置verify=False即可
        try:
             response = requests.post(url=url, headers=headers, data=data, verify=False)
             return response
        except Exception as ex:
            log.warning(ex)


    def get_requestsn(self, url, headers, data=None):
        # 忽略不安全的请求警告信息
        # requests.packages.urllib3.disable_warnings()
        try:
            response = requests.get(url=url, headers=headers, data=data, verify=False)
            return response
        except Exception as ex:
            log.warning(ex)
    def request(self, url, method, headers=None, data=None):
        # # 忽略不安全的请求警告信息
        # requests.packages.urllib3.disable_warnings()
        # requests.adapters.DEFAULT_RETRIES = 5

        if method == "POST":
            log.info('调用POST请求')
            response = self.post_requests(url, headers, data)
        elif method == "GET":
            log.info('调用GET请求')
            response = self.get_requestsn(url, headers, data)
        # 将响应的的数据以字典数据结构和json数据格式返回
        else:
            log.warning('请求方式不存在')

        return response
  1. Conf目录(配置模块)

该模块主要放日志配置、邮件配置、相关路径配置、数据库配置、优先级配置等需要用的参数。

编号

脚本名称

脚本描述

1

basicConf.ini

存放连接配置等信息:数据库、radis等


"""
配置
"""
import os
import time

# 时间格式
timestamp = time.strftime('%Y-%m-%d %H:%M:%S')

## 获取项目当前运行路径
BASE_PATH = os.path.dirname(
    os.path.dirname(__file__)
)
# 测试数据地址
CASE_TABLE = 'test_Case.xls'

# 需要执行的case py文件
CASE_FILE = 'test_Demo.py'

# 测试用例路径
TEST_CASE_PATH = os.path.join(
    BASE_PATH, 'test_case')

# 获取测试用例EXCEL表格 路径
CASE_DATA_PATH = os.path.join(
       BASE_PATH, 'data', CASE_TABLE)

# 运行日志存放路径
CASE_RUN_PATH = os.path.join(
    BASE_PATH, 'log')


# allure  JONS文件路径
RESULT_JSON_FILE_PATH = os.path.join(
    BASE_PATH,'report','result')

# allure HTML报告路径
RESULT_HTML_FILE_PATH = os.path.join(
    BASE_PATH,'report','HTML')

# 发送邮件 报告所在地址
SEND_REPORT_EMAIL_PATH = os.path.join(
    BASE_PATH,'report','HTML','index.html')

RUN_TEST_CASE = ''

# 生成测试报告命令
GENERATE_ALLURE_REPORT = f'allure generate {RESULT_JSON_FILE_PATH} -o  {RESULT_HTML_FILE_PATH} --clean' #
# GENERATE_ALLURE_REPORT = f'allure generate {RESULT_JSON_FILE_PATH} -c  {RESULT_HTML_FILE_PATH} --clean' #清楚历史数据
# 邮件配置
smtp_server = 'smtp.qq.com'
smtp_user = '@qq.com' # 发件邮箱
smtp_password = ''  # 授权码

sender = smtp_user  # 发件人
receiver = '@126.com'  # 收件人
subject = '自动化接口测试报告'  # 邮件主题

from AotoInterfaceTest.conf import settings
import os

standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                  '[%(levelname)s][%(message)s]'

simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'

test_format = '%(asctime)s] %(message)s'

# 3、日志配置字典
LOGGING_DIC = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
        'test': {
            'format': test_format
        },
    },
    'filters': {},
    'handlers': {
        #打印到终端的日志
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',  # 打印到屏幕
            'formatter': 'simple'
        },

        #打印到文件的日志,收集info及以上的日志
        'default': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,日志轮转
            'formatter': 'standard',
            # 可以定制日志文件路径
            # BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # log文件的目录
            # LOG_PATH = os.path.join(BASE_DIR,'a1.log')
            'filename': os.path.join(settings.CASE_RUN_PATH,'接口自动化测试.log'),  # 日志文件
            'maxBytes': 1024*1024*5,  # 日志大小 5M
            'backupCount': 5,
            'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
        },
    },
    'loggers': {
        #logging.getLogger(__name__)拿到的logger配置
        'log_msg': {
            'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            'level': 'DEBUG', # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
            'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
        },
    },
}
  1. Data目录 (测试用例)

该模块可以根据自己的需求、或者业务场景设计用例、常用excel、Yaml等2中方式编写测试用例,若因用例过多,后期可能会考虑创建子目录来定义用例范围。

本架构中使用yaml文件作为数据传入

目录分层与用例脚本一一对应

yaml文件分为公共数据文件和用例数据文件

python接口篇-python框架搭建_第5张图片

  1. Log目录 (日志)

日志模块就是用来存放项目运行的日志,或某个用例运行出错,异常做一下记录,方便查阅,定位问题。

日志级别分为:"info"、 "debug"、"warning"、"error"4种,由conf中的配置文件来控制。

  1. Report目录(测试报告)

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

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

python接口篇-python框架搭建_第6张图片

#!/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 = '[email protected]'
    password = ""
    sender = '[email protected]'
    # 可添加多个收件人的邮箱
    receives = ['[email protected]']
    # 构造邮件对象
    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)
  1. TestSuite目录(测试套件)

使用pytest作为测试套件进行测试,如果pytest命令行有指定目录,则从该目录中开始查找测试用例文件,如果没有指定,则从当前运行目录开始查找文件。注意,该查找是递归查找,子目录中的文件也会被查找到。

该模块主要使用pytest做为测试套件进行测试

pytest须要知识点:

pytest以特定规则搜索测试用例,所以测试用例文件、测试类以及类中的方法、测试函数这些命名都必须符合规则,才能被pytest搜索到并加入测试运行队列中。

搜索规则

如果pytest命令行有指定目录,则从该目录中开始查找测试用例文件,如果没有指定,则从当前运行目录开始查找文件。注意,该查找是递归查找,子目录中的文件也会被查找到。

并不是能够查找到目录下的所有文件,只有符合命名规则的文件才会被查找。默认规则是以test_开头或者以_test结尾的.py文件。

在测试文件中查找Test开头的类,以及类中以test_开头的方法,查找测试


#!/usr/bin/env python
# -*- coding:utf-8 -*-
# fileName: test_Demo.py
import pytest
import json
from AotoInterfaceTest.common.RequestsMethod import RequestsMethod
from AotoInterfaceTest.common.DataProcee import Procee
from AotoInterfaceTest.common.Asert import Asert
from logging import config, getLogger
from AotoInterfaceTest.conf import logsettings
import allure
config.dictConfig(logsettings.LOGGING_DIC)

log = getLogger('log_msg')
req = RequestsMethod()
data = Procee()


@allure.feature('测试')
@pytest.mark.parametrize('datas',data.runCase_excel_Data())
def test_fk_api(datas):

     log.info(f'开始测试用例编号:{datas["用例编号"]}  *******************开始测试*****************')
     r = req.request(url=datas['请求URL'], method=datas['请求方式'], headers=json.loads(datas['headers']), data=datas['请求参数'])
     assert r.status_code == int(datas['预期结果'])
     log.info(f'用例编号:{datas["用例编号"]}  *************测试测试完成*************************')

if __name__ == '__main__':

    pytest.main(['-v', '-s', "test_Demo.py"])
  1. Assert_set目录(断言封装)

存储相关用例的断言封装,特殊接口无法采用公共断言方法时,可在此处单独设置封装,后期可能再创建子目录进行分类。

  1. Utils目录(工具类)

工具类封装,common中主要封装跟业务逻辑相关的方法,此目录可存放与业务无关的工具类,如随机生成字符串,excel解析等。

编号

脚本名称

脚本描述

1

__init__.py

2

json_analysis.py

对字典或者列表进行解析

从解析的数据中获取想要的value

3

random_str.py

随机生成指令类型的字符串

4

xls_to_dict.py

读取xls文件转为字典

  1. API目录

最底层api的封装,以接口请求参数的service_uri为基准,相同service_uri的接口封装在同一个文件中。

编号

脚本名称

脚本描述

1

request_method.py

请求方法封装

2

assert_response.py

公共断言

1、code断言

2、响应结果全部匹配

3、部分响应结构断言

3

get_token.py

获取身份令牌

  1. Conftest.py文件

用于封装多个不同目录下的用例执行时需要用到的前置和后置,即fixture函数,以及pytest的钩子函数。

编号

脚本名称

脚本描述

1

根目录层conftest.py

1、钩子函数pytest_addoption

2、cache:清理日志并获取公共的token、id等信息

2

用例层conftest.py

做当前用例目录的公共数据

  1. Pytest.ini文件

用于mark标记注册,当测试用例增多时,增加mark标记可以给用例设置执行的优先级,按mark标记执行。

  1. Main.py文件

程序执行入口,主要用于本地调试。

代码形式如下:

二、框架的使用流程

  1. 用例层编写

  1. 目录根据模块进行设置

  1. 目录下设置当前目录的conftest.py准备公共数据

  1. 用例脚本调用日志方法、yaml文件读取、请求方法和断言调用

  1. 数据层准备

  1. 公共数据yaml文件

  1. 用例数据yaml文件

  1. 执行脚本

main.py

4、查看报告

你可能感兴趣的:(python之接口自动化测试,python,pycharm,自动化)