欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python+unittest+读取Excel+request+ddt+yaml配置文件接口自动化框架

程序员文章站 2022-06-23 21:25:00
unittest+读取Excel+request+ddt+yaml配置文件接口自动化框架一级目录梳理一下关于如何搭建ddt数据驱动自动化测试框架二级目录封装一些常用的方法三级目录## 运行all_run.py文件一级目录梳理一下关于如何搭建ddt数据驱动自动化测试框架二级目录封装一些常用的方法三级目录## 运行all_run.py文件梳理一下关于如何搭建ddt数据驱动自动化测试框架cases: 主要为了存放测试用例common:存放公共方法,列如封装的请求方法,读取excel,读取配置等等方法...

python+unittest+读取Excel+request+ddt+yaml配置文件接口自动化框架

梳理一下关于如何搭建ddt数据驱动自动化测试框架

python+unittest+读取Excel+request+ddt+yaml配置文件接口自动化框架
cases: 主要为了存放测试用例
common:存放公共方法,列如封装的请求方法,读取excel,读取配置等等方法,都放在了这里
config:存放配置文件,常用的有.conf .ini .yaml 我这里使用的是.yaml文件
Logs:存放日志
report:存放生成的测试报告

首先考虑一下场景,编写自动化框架,其目的是什么
1.去除繁重的手工化.
2.方便使用
3.快速定位问题
4.测试过程数据可视化
根据以上的想法,所以本次编写的自动化框架,用到了
1.:unittest库.因为unittest是一个python标准库,所以不需要下载,只需要import导入即可,用来管理用例
2. requests 只要发送请求,是离不开一个python三方库,request库
3.openexcel 读取excel表格数据,因为openexcel库的原因,不能使用xsl格式的表格,也是一个三方库
4.logging 生成日志
5.ddt 数据驱动
6.HTMLTestRunner 生成测试报告
7.以及写入过程当中使用到的os和datatime

封装一些常用的方法
python+unittest+读取Excel+request+ddt+yaml配置文件接口自动化框架
1.http_req.py
定义了一个基础万能方法,后续关于请求方法,可以放到这个文件,便于管理

# encoding: utf-8
"""
@author:辉辉
@email: 
@Wechat: 不要静音
@time: 2020/11/20 10:44
"""

"""
定义关于requests的请求方法

"""

import requests


class Requests_methods:

    def req_url(self, method, url, data=None, json=None, **kwargs):
        """
        定义请求方法,requests.requests里是可以定义请求方式,列如get.post等,
        :param method: 请求方法
        :param url: 请求路径
        :param data: 表单数据
        :param json: json格式数据
        :param kwargs: 其他参数
        :return: 返回一个json数据
        """
        req = requests.request(method=method, url=url, data=data, json=json, **kwargs)

        if not isinstance(req,dict):
            return req
        return req.json()


if __name__ == '__main__':

    url = 'http://www.baidu.com'
    res = Requests_methods().req_url('get', url, )
    print(res)

2.read_excel方法封装
这里封装的是关于excel操作的方法,因为封装的方法相对独立,所以后续可以灵活添加其余方法

# encoding: utf-8
"""
@author:辉辉
@email: 
@Wechat: 不要静音
@time: 2020/11/20 11:11
"""

import openpyxl

"""

读取Excel表格
1.打开表格
2.读取表头
3.读取所有内容

"""
from class_2.common.read_ymal import yaml_data

# file_path = '../config/data.yaml'
filename = yaml_data.return_data()
file_name= filename['filename']
print(file_name)

class ExcelMethod:
    """定义一个类方法,"""

    def __init__(self):
        """路径名字是固定的,所以定义为实例属性"""
        self.filename = file_name

    def open_excel(self, name):
        """
        打开excel表格,
        :param name: 文件sheet名字
        :return:
        """
        wb = openpyxl.load_workbook(self.filename)
        sheet = wb[name]
        return sheet

    def red_title(self, name):
        """
        读取excel表格第一行表头,并返回一个列表
        :param name:
        :return:
        """
        sheet1 = self.open_excel(name)
        row = sheet1[1]
        title_list = []
        for sheet in row:
            # print(sheet)
            title_list.append(sheet.value)
        return title_list

    def red_all(self, name):
        """
        读取excel表格里除了表头以外所有数据,并返回一个列表嵌套字典
        :param name:
        :return:
        """
        row = self.open_excel(name)
        data_row = list(row.rows)
        title = self.red_title(name)
        print(title)
        data_list = []
        for data in data_row[1:]:
            data_dict = []
            for item in data:
                #     data_dict[title[i]] = data_dict[item.value]
                data_dict.append(item.value)
            data_list.append(dict(zip(title, data_dict)))
        return data_list


if __name__ == '__main__':
#     filename = r'F:\cases.xlsx'
    eb = ExcelMethod().red_all('Sheet1')
    print(eb)

3.read_yaml.py
读取yaml文件,基础方法,看注释即可

# encoding: utf-8
"""
@author:辉辉
@email: 
@Wechat: 不要静音
@time: 2020/11/20 13:59
"""

import yaml

"""
读取yaml配置文件
"""


class ReadYaml:
    """读取yaml配置文件"""
    def __init__(self,file_name):
        """
        初始化,并设置实例属性路径名字
        :param file_name:
        """
        self.file_name = file_name

    def read_yaml(self):
        """
        读取yaml文件,返回数据
        :return:
        """
        with open(self.file_name, encoding='utf-8')as f:
            data = yaml.load(f, Loader=yaml.FullLoader)

        return data

    def return_data(self,data_name=None):
        """
        返回数据,如果属性名字为空,则默认返回所有数据
        :param data_name:属性名字
        :return:
        """
        data_ret = self.read_yaml()

        if data_name is None:
            return data_ret
        else:

            return data_ret[data_name]


yaml_data = ReadYaml(file_name=r'C:\Users\Administrator\test_api_new\class_2\config\data.yaml')
if __name__ == '__main__':
    data = yaml_data.return_data()
    print(data)

4.file_log.py
生成日志
因为这里要多次使用.logging,所以使用了父类继承,从写了方法,避免日志打印行列不精准,同时为了不出现多个初始化导致产生新的日志文件,这里在类里进行了类属性初始化,

# encoding: utf-8
"""
@author:辉辉
@email: 
@Wechat: 不要静音
@time: 2020/11/20 14:37
"""
"""
生成log文件
"""
import logging

from class_2.common.read_ymal import yaml_data

log_name = yaml_data.return_data(data_name='logname')
levels = yaml_data.return_data(data_name='level')
filename = r'../Logs/log.txt'
"""
读取yaml文件
1.先读取logname
2.读取level
3.设置log地址

"""


class FileLogs(logging.Logger):
    """  定义日志类  """

    def __init__(self, name, file, level='DEBUG',
                 fmt="%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s"):
        super().__init__(name)
        # 超继承,继承父类初始化实例
        self.setLevel(level)
        file_headers = logging.FileHandler(file)
        file_headers.setLevel(level)
        self.addHandler(file_headers)
        fmt = logging.Formatter(fmt)
        file_headers.setFormatter(fmt)


logger = FileLogs(log_name, filename, levels)
# 类里初始化,防止多次初始化
if __name__ == '__main__':
    logger = FileLogs(log_name, filename, levels)
    logger.info('哼,无聊的姿势又增加了')

5.在cases文件下新建测试用例模块.test_login.py

# encoding: utf-8
"""
@author:辉辉
@email: 
@Wechat: 不要静音
@time: 2020/11/20 16:00
"""
import unittest

import ddt

from class_2.common.file_log import logger
from class_2.common.http_req import Requests_methods
from class_2.common.read_excel import ExcelMethod

name = 'Sheet1'
"""
定义一个excel表格名称
"""

# print(data)
# 使用ddt驱动
@ddt.ddt()
class TestLogin(unittest.TestCase):
	""" 使用类属性方法,定义读取Excel"""
    data = ExcelMethod().red_all(name)

    # requests = Requests_methods()
	#将excel表格数据读取出来放到@ddt.data(*data)里,进行多次循环跑用例
    @ddt.data(*data)
    def test_login(self, data):
        req = Requests_methods().req_url(data['method'],
                                         data['url'],
                                         )
		#断言code=预期结果
        self.assertEqual(req.status_code, data['预期结果'])
        logger.info('正在进行用例测试')


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

6.编写all_run.py文件,执行所有脚本

# encoding: utf-8
"""
@author:辉辉
@qq:372148872
@Wechat: 不要静音
@time: 2020/11/20 15:38
"""
import datetime
import os
import unittest

from HTMLTestRunner_new import HTMLTestRunner
from class_2.common.file_log import logger
"""
生成测试报告


首先,读取cases路径
其次生成case读取器
然后生成HTML实例化
"""
"""
使用os去定位当前文件的决定路径
进行拼接查找cases目录
"""
dir_path = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(dir_path, 'cases')

# 生成case查找器
load_test = unittest.TestLoader()
#匹配所有以test_开头的.py文件
suit = load_test.discover(file_path, 'test_*.py')


"""
这里进行路径重新拼接,生成HTML报告存放路径
"""

report_path = os.path.join(dir_path, 'report')
# 使用os.path.exists去判断路径是否存在.如果不存在,则创建
if not os.path.exists(report_path):
    os.mkdir(report_path)
#  为了每次生成报告不重复,将当前时间与report进行拼接生成报告名字
times = datetime.datetime.now().strftime('%Y-%m-%d %H-%M-%S')
print(times)

# print(time)
file_name = times + 'report.html'
file_path = os.path.join(report_path,file_name)
# print(file_path)
with open(file_path, 'wb') as f:
#使用HTMLTestRunner生成报告,HTMLTestRunner,生成的报告为全英文,为了方便观看,我将源码down到本地,进行了源码修改,并添加了tester关键字参数
    run = HTMLTestRunner(f,title='接口测试报告',description='调试使用',tester='Test')
    logger.info('生成测试用例')
    run.run(suit)

接下来.我们运行all_run.py文件
python+unittest+读取Excel+request+ddt+yaml配置文件接口自动化框架
运行成功.
python+unittest+读取Excel+request+ddt+yaml配置文件接口自动化框架
生成了日志以及测试报告
python+unittest+读取Excel+request+ddt+yaml配置文件接口自动化框架
python+unittest+读取Excel+request+ddt+yaml配置文件接口自动化框架
到此.框架的初步模型便搭建好了.剩余的只是填充各种方法了.

本文地址:https://blog.csdn.net/nbt_silent1/article/details/109855239