zoukankan      html  css  js  c++  java
  • pytest的配置相关流程包含日志功能:

    1.把软件开发规范的相关目录建立起来

    2、配置settings:

    import os
    import datetime
    import shutil
    import sys

    base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    # print(base_dir) #D:s27day69 b

    # 定义文件名字:
    file_name = "接口测试示例.xlsx"

    # 路径拼接:
    file_path = os.path.join(base_dir, "data", file_name)
    # print(file_path) #D:s27day69 bdata接口测试示例.xlsx

    # ---------------- 日志相关 --------------------
    # 日志级别
    LOG_LEVEL = 'debug'

    # 屏幕输出流
    LOG_STREAM_LEVEL = 'debug'

    # 文件输出流
    LOG_FILE_LEVEL = 'info'

    # 日志文件命名
    LOG_FILE_NAME = os.path.join(base_dir, 'logs', datetime.datetime.now().strftime('%Y-%m-%d') + '.log')

    # allure报告相关:
    report_path = os.path.join(base_dir, "report")
    result_path = os.path.join(base_dir, "report", "result")
    allure_html_path = os.path.join(base_dir, "report", "allure_html")
    command = "allure generate {} -o {} --clean".format(result_path, allure_html_path)

    # 要打包的根目录:
    zip_case_result_path = allure_html_path

    # 要打包的文件名:
    zip_file_name = "allure_report.zip"

    # 将打包文件存放哪去:
    zip_save_path = report_path

    # 邮箱相关:
    # 第三方 SMTP 服务
    # 设置服务器
    mail_host = "smtp.qq.com"

    # 用户名
    mail_user = "1320685524@qq.com"

    # 获取授权码
    mail_pass = "mpaocydzpzfjidge"

    # 发件人账号
    sender = '1320685524@qq.com'

    # 接收邮件,可设置为你的QQ邮箱或者其他邮箱和多个收件人
    receivers = ['1320685524@qq.com']

    # 邮件主题:
    subject = 'Python发送带附件的邮件示例'

    # 邮件正文内容
    send_content = '这是今天的测试用例报告,请下载附件并使用pycharm打开'

    # 邮件附件路径:
    send_file_path = os.path.join(zip_save_path, zip_file_name)
    send_file_name = zip_file_name

    if __name__ == '__main__':
    print(send_file_path)
    # os.remove(report_path)
    # shutil.rmtree(report_path)
    #查看路径:
    # print(sys.path)
    #查看包:
    # print(sys.modules)

    3.配置pytest.ini

    [pytest]
    addopts = -s -v --alluredir ./report/result
    testpaths = ./scripts
    python_files = test_*.py
    python_classes = Test*
    python_functions = test_*

    4.创建入口文件run.py

    if __name__ == '__main__':
    import pytest
    pytest.main()

    5.创建用例脚本文件test_case.py

    import pytest
    import allure
    from utils.ExcelHandler import Excel
    from utils.LogHandler import logger
    from utils.RequestHandler import RequestHandler
    from utils.AllureHandler import AllureHandler


    @pytest.mark.parametrize("d", Excel().get_excel_data())
    def test_case(d):
    print(d)
    result = RequestHandler(d).get_response()
    # logger().info(d)
    allure.dynamic.title(d["case_project"])
    allure.dynamic.description("<font color='red'>请求的URL:</font>{}<hr />"
    "<font color='red'>请求的类型:</font>{}<hr />"
    "<font color='red'>实际值:</font>{}<hr />"
    "<font color='red'>预期值:</font>{}<hr />"
    "".format(d["case_url"],
    d["case_method"],
    result[1],
    result[0],
    ))
    assert result[0] == result[1]

    # def teardown_module():
    # allure_obj = AllureHandler()
    """生成allure测试报告"""
    # allure_obj.execute_command()
    """打包文件"""
    # allure_obj.zip()
    """发送邮件"""
    # allure_obj.send_email()

    6.调通它们

    7.#参数化
    1.使用参数化
    2.获取Excel表格数据

    AllureHandler.py
    """
    执行allure命令生成报告
    打包allure报告
    发送压缩包
    """

    import os
    # 导入压缩文件用的模块
    import zipfile
    import smtplib
    import shutil
    import time
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart
    from email.header import Header
    from conf import settings
    from utils.LogHandler import logger
    from subprocess import call, Popen


    class AllureHandler(object):
    def __init__(self):
    """清空report目录,以便后续方便操作"""
    # shutil.rmtree(settings.report_path)
    pass

    def execute_command(self):
    """执行allure命令"""
    # time.sleep(5)
    logger().info("执行生成allure报告:{}".format(settings.command))
    # os.system(settings.command)
    # shell=True是可以识别字符串的命令:
    call(settings.command, shell=True)

    def zip(self):
    """打包allure报告"""
    # 日志:
    logger().info("打包文件名:{},打包到:{}".format(settings.zip_file_name, settings.zip_save_path))
    # 要压缩文件夹的根路径并拼接:
    base_dir = settings.zip_case_result_path
    zip_file_name = settings.zip_file_name
    # 保存打包文件的路径:
    f = zipfile.ZipFile(os.path.join(settings.zip_save_path, zip_file_name), 'w', zipfile.ZIP_DEFLATED)
    for dir_path, dir_name, file_names in os.walk(base_dir):
    # 要是不replace,就从根目录开始复制
    file_path = dir_path.replace(base_dir, '')
    # 实现当前文件夹以及包含的所有文件
    file_path = file_path and file_path + os.sep or ''
    for file_name in file_names:
    f.write(os.path.join(dir_path, file_name), file_path + file_name)
    f.close()

    def send_email(self):
    """将打包的allure文件发送给指定邮箱"""
    logger().info("正在向{}发送邮件,请稍后.......".format(settings.receivers))
    # 第三方SMTP服务
    # 设置服务器
    mail_host = settings.mail_host
    # 用户名
    mail_user = settings.mail_user
    # 获取授权码
    mail_pass = settings.mail_pass
    # 发件人账号
    sender = settings.sender
    # 接收邮件,可设置为你的QQ邮箱或者其他邮箱和多个收件人
    receivers = settings.receivers
    # 邮件主题:
    subject = settings.subject

    # 创建一个带附件的实例
    message = MIMEMultipart()

    # 发件人
    message['From'] = Header("我是发件人", 'utf-8')

    # 收件人
    message['To'] = Header("我是收件人", 'utf-8')

    # 邮件主题
    subject = settings.subject
    message['Subject'] = Header(subject, 'utf-8')

    # 邮件正文内容
    send_content = settings.send_content
    content_obj = MIMEText(send_content, 'plain', 'utf-8')
    message.attach(content_obj)

    # 构造附件1,发送当前目录下的 t1.txt 文件
    att1 = MIMEText(open(settings.send_file_path, 'rb').read(), "base64", "utf-8")

    # 基于流的模式
    att1["Content-Type"] = "application/octet-stream"

    # 文件描述、filename是附件中显示的名字
    att1["Content-Disposition"] = "attachment;filename = '{}'".format(settings.send_file_name)
    message.attach(att1)

    # 构造附件2,发送当前目录下的t2.py文件
    # att2 = MIMEText(open("t2.py", "rb").read(), "base64", "utf-8")
    #
    # # 基于流的模式
    # att2["Content-Type"] = "application/octet-stream"
    #
    # # 文件描述、filename是附件中显示的名字
    # att2["Content-Disposition"] = "attachment;filename = 't2.py'"
    # message.attach(att2)

    try:
    smtpObj = smtplib.SMTP()
    # 25 为 SMTP 端口号
    smtpObj.connect(mail_host, 25)
    smtpObj.login(mail_user, mail_pass)
    smtpObj.sendmail(sender, receivers, message.as_string())
    logger().info("向{}发送邮件成功".format(settings.receivers))
    except smtplib.SMTPException as e:
    logger().error("向{}发送邮件失败,可能的原因:{}".format(settings.receivers, e))
    ExcelHandler.py
    import xlrd
    from conf import settings
    from utils.LogHandler import logger

    class Excel(object):
    def get_excel_data(self):
    """获取excel表格数据"""
    logger().info("读取Excel表格{} {}".format(settings.file_name,settings.file_path))
    book = xlrd.open_workbook(filename=settings.file_path)
    sheet = book.sheet_by_index(0)
    # print(sheet.nrows) #8
    title = sheet.row_values(0)
    l = []
    for row in range(1, sheet.nrows):
    # print(sheet.row_values(row))
    l.append(dict(zip(title, sheet.row_values(row))))
    # print(l)
    return l

    if __name__ == '__main__':
    Excel().get_excel_data()

    8.#配置日志信息记录相关

    LogHandler.py

    import logging
    from conf import settings

    class LoggerHandler:
    """ 日志操作 """
    _logger_level = {
    'debug': logging.DEBUG,
    'info': logging.INFO,
    'warning': logging.WARNING,
    'error': logging.ERROR,
    'critical': logging.CRITICAL
    }
    def __init__(self, log_name, file_name, logger_level, stream_level='info', file_level='warning'):
    self.log_name = log_name
    self.file_name = file_name
    self.logger_level = self._logger_level.get(logger_level, 'debug')
    self.stream_level = self._logger_level.get(stream_level, 'info')
    self.file_level = self._logger_level.get(file_level, 'warning')
    # 创建日志对象
    self.logger = logging.getLogger(self.log_name)
    # 设置日志级别
    self.logger.setLevel(self.logger_level)
    if not self.logger.handlers:
    # 设置日志输出流
    f_stream = logging.StreamHandler()
    f_file = logging.FileHandler(self.file_name)
    # 设置输出流级别
    f_stream.setLevel(self.stream_level)
    f_file.setLevel(self.file_level)
    # 设置日志输出格式
    formatter = logging.Formatter(
    "%(asctime)s %(name)s %(levelname)s %(message)s"
    )
    f_stream.setFormatter(formatter)
    f_file.setFormatter(formatter)
    self.logger.addHandler(f_stream)
    self.logger.addHandler(f_file)
    @property
    def get_logger(self):
    """伪装成属性返回logger对象"""
    return self.logger

    def logger(log_name='接口测试'):
    return LoggerHandler(
    log_name=log_name,
    logger_level=settings.LOG_LEVEL,
    file_name=settings.LOG_FILE_NAME,
    stream_level=settings.LOG_STREAM_LEVEL,
    file_level=settings.LOG_FILE_LEVEL
    ).get_logger

    if __name__ == '__main__':
    logger().debug('aaaa')
    logger().info('aaaa')
    logger().warning('aaaa')


    9.#请求相关
    1.从参数中获取相关数据发请求
    2.做断言
    3.断言结果返回

    RequestHandler.py

    import requests
    import json
    from utils.LogHandler import logger
    from bs4 import BeautifulSoup


    class RequestHandler(object):
    def __init__(self, d):
    self.d = d

    def get_response(self):
    """获取请求结果"""
    return self.send_msg()

    def _response_application(self, response):
    """校验json类型的返回"""
    response = response.json()
    expect = json.loads(self.d.get("case_expect"))
    for k in expect:
    if expect[k] != response.get(k, "没有这个key:{}".format(k)):
    return {k: expect[k]}, {k: response.get(k, "没有这个key:{}".format(k))}
    return {k: expect[k]}, {k: response.get(k, "没有这个key:{}".format(k))}

    def _response_text(self, response):
    """校验文本类型的返回"""
    # response.title()
    soup = BeautifulSoup(response.text, "html.parser")
    title = soup.find(name="title").text
    # print(title.text)
    logger().info("文本类型的请求结果,预期值:{} | 实际值:{}".format(self.d.get("case_expect"), title))
    return title, self.d.get("case_expect")

    def send_msg(self):
    """发请求"""
    logger().info("请求URL:{},类型:{}".format(self.d.get("case_url"), self.d.get("case_method")))
    response = requests.request(
    method=self.d.get("case_method"),
    url=self.d.get("case_url"),
    # params=self._check_params(),
    # data=self._check_data()
    )
    header = response.headers["Content-Type"].split("/", 1)[0]
    # header = _response_application
    if hasattr(self, "_response_{}".format(header)):
    a = getattr(self, "_response_{}".format(header))
    result = a(response)
    logger().info("预期值:{} 实际值:{}".format(result[0], result[1]))
    return result

    def _check_params(self):
    """检查请求参数"""
    params = self.d.get("case_params")
    if params:
    return {}
    else:
    return {}

    def _check_data(self):
    pass


    if __name__ == '__main__':
    # r1 = requests.get("https://www.cnblogs.com/Neeo/articles/10951734.html")
    # print(r1.text)
    # print(r1.headers)
    # print(r1.title)
    pass
    # r2 = requests.get("https://www.v2ex.com/api/site/info.json")
    # print(r2.headers)

    # r3 = requests.post("https://cnodejs.org/api/v1/message/mark_all")
    # print(r3.headers)


    10.#生成测试报告

    使用 allure generate report/result -o report/allure_html --clean 生成allur报告

    执行命令的方法:

      os.system()

      subprocess


    11.#将allure测试报告打包


    12.#将压缩包fayd

    13.效果如下

  • 相关阅读:
    opencv.js小案例
    flutter获取状态栏高度
    Flutter自定义路由PageRouteBuilder
    Flutter控制屏幕旋转
    Flutter路由导航Navigator
    小程序组件中有bindinput监听报异常
    Flutter获取屏幕宽高和Widget大小
    正则表达式
    Python安装官方whl包、tar.gz包、zip包
    Python之mmap内存映射模块(大文本处理)说明
  • 原文地址:https://www.cnblogs.com/zhang-da/p/12234860.html
Copyright © 2011-2022 走看看