Pytest集成excel

2.10.1 反射函数

反射函数概念:它可以把字符串映射到实例的变量或者实例的方法然后可以去执行调用、修改等操作。它有四个重要的方法:
• getattr 获取指定字符串名称的对象属性
• setattr 为对象设置一个对象
• hasattr 判断对象是否有对应的对象(字符串)
• delattr 删除指定属性
在数据驱动中使用的是getattr方法,通过读取excel表格的数据确定关键字和参数,执行对应的代码。先看下语法:

func=(obj,method_name)
func(*args)
obj:关键字类对象
method_name:关键字方法
args:方法中需要的参数

示例:

class A:
    def func1(self):
        print("方法一")
    def func2(self,a:str=''):
        print("方法2"+a)
    def func3(self,a,b):
        print("两数之和为"+str(a+b))
#创建A类的对象
a=A()
method=input("请输入方法名")
params=input("请输入参数")
try:
    f=getattr(a,method)
except:
    print("方法不存在")
if params:
    f(*params)
else:
	f()

结果:

请输入方法名func2
请输入参数1
方法21

2.10.2 原始数据驱动

1.excel方法
需要安装的python库:
openpyxl、xlrd、xlwt
Excel.py:根据文件结尾xlsx、xls,设置打开或写入excel的对象
NewExcel.py:文件结尾xlsx的excel文件处理方法
OldExcel.py:文件结尾xls的excel文件处理方法
说明:这三个文件不是我写的 这里我把原代码放出来就不上注释了 抱歉!
Excle.py文件内容:

import os
from common.excel import NewExcel
from common.excel import OldExcel



def get_reader(srcfile=''):

    reader = None

    if not os.path.isfile(srcfile):
        print("%s not exist!" % (srcfile))
        return reader

    if srcfile.endswith('.xls'):
        reader = OldExcel.Reader()
        reader.open_excel(srcfile)
        return reader

    if srcfile.endswith('.xlsx'):
        reader = NewExcel.Reader()
        reader.open_excel(srcfile)
        return reader


def get_writer(srcfile, dstfile):

    writer = None
    if not os.path.isfile(srcfile):
        print("%s not exist!" % (srcfile))
        return writer

    if srcfile.endswith('.xls'):
        writer = OldExcel.Writer()
        writer.copy_open(srcfile, dstfile)
        return writer

    if srcfile.endswith('.xlsx'):
        writer = NewExcel.Writer()
        writer.copy_open(srcfile, dstfile)
        return writer

NewExcle.py文件内容:

import os, openpyxl
from shutil import copyfile
from openpyxl.styles import Font, PatternFill, Border, Side, Alignment, Protection



class Reader:


    def __init__(self):
        self.workbook = None
        self.sheet = None
        self.rows = 0
        self.r = 0

    # 打开excel
    def open_excel(self, srcfile):
        if not os.path.isfile(srcfile):
            print("%s not exist!" % (srcfile))
            return

        openpyxl.Workbook.encoding = "utf8"
        self.workbook = openpyxl.load_workbook(filename=srcfile)
        self.sheet = self.workbook[self.workbook.sheetnames[0]]
        self.rows = self.sheet.max_row
        self.r = 0
        return

    def get_sheets(self):
        sheets = self.workbook.sheetnames
        return sheets

    def set_sheet(self, name):
        self.sheet = self.workbook[name]
        self.rows = self.sheet.max_row
        self.r = 0
        return


    def readline(self):

        lines = []

        for row in self.sheet.rows:

            line = []

            for cell in row:
                if cell.value is None:
                    line.append('')
                else:
                    line.append(cell.value)

            lines.append(line)

        return lines


class Writer:

    def __init__(self):

        self.workbook = None

        self.wb = None

        self.sheet = None

        self.df = None

        self.row = 0

        self.clo = 0

    def copy_open(self, srcfile, dstfile):
    
        if not os.path.isfile(srcfile):
            print(srcfile + " not exist!")
            return

        if os.path.isfile(dstfile):
            print(dstfile + " file already exist!")

        self.df = dstfile

        self.workbook = openpyxl.load_workbook(filename=srcfile)

        copyfile(srcfile, dstfile)

        self.wb = openpyxl.load_workbook(filename=dstfile)
        return


    def get_sheets(self):

        sheets = self.workbook.sheetnames
        return sheets


    def set_sheet(self, name):

        self.sheet = self.wb[name]
        return


    def write(self, r, c, value, color=None):

        d = self.sheet.cell(row=r + 1, column=c + 1, value=value)

        if color:
            if color == 0:
                color = "FF000000"
            elif color == 1:
                color = "FFFFFFFF"
            elif color == 2:
                color = "FFFF0000"
            elif color == 3:
                color = "FF00FF00"
            elif color == 4:
                color = "FF0000FF"
            elif color == 5:
                color = "FFFFFF00"
            else:
                color = "FF000000"

        font = Font(name='Arial',
                    size=11,
                    bold=False,
                    italic=False,
                    vertAlign=None,
                    underline='none',
                    strike=False,
                    color=color)

        d.font = font
        return

    def save_close(self):
        self.wb.save(self.df)
        return

OldExcle.py文件内容:


import os, xlrd, xlwt
from xlutils.copy import copy

class Reader:
    def __init__(self):
        self.workbook = None
        self.sheet = None
        self.rows = 0
        self.r = 0

    def open_excel(self, srcfile):
        if not os.path.isfile(srcfile):
            print("%s not exist!" % (srcfile))
            return

        xlrd.Book.encoding = "utf8"

        self.workbook = xlrd.open_workbook(filename=srcfile)
        self.sheet = self.workbook.sheet_by_index(0)
        self.rows = self.sheet.nrows
        self.r = 0
        return

    def get_sheets(self):
        sheets = self.workbook.sheet_names()
        return sheets

    def set_sheet(self, name):
        self.sheet = self.workbook.sheet_by_name(name)
        self.rows = self.sheet.nrows
        self.r = 0
        return

    def readline(self):
        lines = []
        while self.r < self.rows:
            row1 = None
            row = self.sheet.row_values(self.r)
            self.r = self.r + 1
            i = 0
            row1 = row
            for strs in row:
                row1[i] = str(strs)
                i = i + 1
            lines.append(row1)

        return lines


class Writer:

    def __init__(self):
        self.workbook = None
        self.wb = None
        self.sheet = None
        self.df = None
        self.row = 0
        self.clo = 0
    def copy_open(self, srcfile, dstfile):
        if not os.path.isfile(srcfile):
            logger.error(srcfile + " not exist!")
            return
        if os.path.isfile(dstfile):
            print(dstfile + " file already exist!")

        self.df = dstfile
        self.workbook = xlrd.open_workbook(filename=srcfile, formatting_info=True)
        self.wb = copy(self.workbook)
        return

    def get_sheets(self):
        sheets = self.workbook.sheet_names()
        return sheets

    def set_sheet(self, name):
        self.sheet = self.wb.get_sheet(name)
        return

    def write(self, r, c, value, color=None):
        def _getCell(sheet, r, c):

            row = sheet._Worksheet__rows.get(r)
            if not row:
                return None

            cell = row._Row__cells.get(c)
            return cell

        cell = _getCell(self.sheet, r, c)
        if cell:
            idx = cell.xf_idx

        if color is None:
            self.sheet.write(r, c, value)
            if cell:
                ncell = _getCell(self.sheet, r, c)
                if ncell:
                    ncell.xf_idx = idx

        else:
            style = xlwt.XFStyle()
            font = xlwt.Font()  
            font.name = 'Arial'
            font.bold = True  
            # font.underline = True  
            # font.italic = True 
            font.colour_index = color 
            style.font = font
            borders = xlwt.Borders()
            borders.left = xlwt.Borders.THIN
            borders.right = xlwt.Borders.THIN
            borders.top = xlwt.Borders.THIN
            borders.bottom = xlwt.Borders.THIN
            style.borders = borders
            self.sheet.write(r, c, value, style)

        return
    def save_close(self):
        self.wb.save(self.df)
        return

2.读取excel用例,执行用例,将结果写入excel
示例代码:

#关键字对象
web=Web()
def runcase(obj,line,i):
    """
    :param obj:关键字对象
    :param line:参数
    :param i: 写入的行
    :return:
    """
    #思路,先判断哪一行是要进行反射的,
    #如果第一个或者第二个有值则不执行反射
    print(line)
    if len(line[0])>1 or len(line[1])>1:
        return
    try:
        func=getattr(obj,line[3])
        print(line[3])
        writer.write(i,7,"PASS",3)
    except Exception as e:
        print('关键字%s不存在' % line[3])
        writer.write ( i, 7, "FALl", 2 )
        return

    params=line[4:]
    params=params[:params.index('')]
    if params:
        func(*params)
    else:
        func()
#打开文件
reader=get_reader("../lib/电商项目用例.xlsx")
#写入文件
writer=get_writer("../lib/电商项目用例.xlsx","../lib/result-电商项目用例.xlsx")
#获取内容,获取sheet页 然后输出每一个sheet页每一行的数据,在把每一行的数据进行遍历
#调用get_sheets方法调用
#执行成功写入pass
sheets=reader.get_sheets()
for i in range (0,len(sheets)):
    #遍历sheets名称,挨个读取
    reader.set_sheet(sheets[i])
    #保证读取和写入都在同一个sheet页
    writer.set_sheet(sheets[i])
    lines=reader.readline()
    #输出每一行的信息
    for i in range(1,len(lines)):
        runcase(web,lines[i],i)

#保存结果
writer.save_close()

2.10.3 pytest集成excel

思路:将excel中的用例保存到列表cases中,使用pytest参数化调用cases,再用反射的方式执行cases。就实现了excel驱动pytest。
代码供参考:

保存用例到cases:


class Conf:
    def __init__(self,reader_path="./../lib/电商项目用例.xlsx",writer_path="./../lib/result-电商项目用例.xlsx"):
    #读取excel文件
        self.reader=get_reader(reader_path)
        #self.writer=get_writer(reader_path,writer_path)
    #获取sheet名称
        self.sheetname=self.reader.get_sheets()
    #设置cases 保存所有用例
        self.cases=[]

        self.get_Case()


    def get_Case(self):
        #设置要读取的sheet页
        for i in range(0,len(self.sheetname)):
            self.reader.set_sheet(self.sheetname[i])
            case=[]
            #读取行
            lines=self.reader.readline()
            for i in range (1,len(lines)):
                line=lines[i]
                # 如果一个数据有值 我们不做任何操作
                if  len(line[0])>1:
                    pass
                #如果第二个数据有值我们开始保存case,这是一个case的开始   登录失败的用例
                elif len(line[1])>1:
                    #如果不是第一行 到了第二个用例的时候
                    if i >2 :
                        #我们要把上一个用例保存到cases里面
                        self.cases.append(case)
                        #将case置空保存第二条用例
                        case=[]
                    case.append(line)
                #如果没有值 就直接在case后面增加,直到下一次 len(line[1])>1
                else:
                    case.append(line)
            #把最后一个用例保存到cases
            self.cases.append(case)
        #输出case
        # for i  in  range (0,len(self.cases)):
        #     print(self.cases[i])

conf=None

用例部分代码:

class Test_web():
    """web自动化测试类"""

    def setup_class(self):
        self.web=Web()

    allure.step()

    @pytest.mark.parametrize("case_params",excel_conf.conf.cases)
    def test_case(self,case_params):
        for i  in range (0,len(case_params)):
            line=case_params[i]
            #判断那行执行
            if len(line[0]) > 1 or len(line[1]) > 1:
                continue
            #获取一行的数据
            try:
                func =getattr(self.web,line[3])
                params = line[4:]
                params = params[:params.index('')]
                func(*params)
            except:
                print(line[3]+"方法不存在")

if __name__=='__main__':
    excel_conf.conf=Conf()
    os.system('rd /s/q result')
    os.system('rd /s/q reports')
    pytest.main(['-s', 'pytest_example/test_web.py','--alluredir', 'result'])
    os.system('allure generate result -o reports --clean')

再使用pytest生成allure报告,这里就不介绍allure的设计了(我比较懒)。

上一篇:Python复选框与删除元素


下一篇:RH358管理DNS和DNS服务器--DNS服务概述