1、excel操作
excel操作的相关库 :xlxd、xlwt、openpyxl、pandas
安装命令:
pip install -i https://pypi.douban.com/simple openpyxl==2.6.2
a.workbook,往往用于创建一个新的excel文件,几乎不用
from openpyxl import workbook
b.load_workbook,往往对已存在的excel进行读写操作
c.openpyxl只能处理xlsx格式的excel文件
d.只能使用办公软件来创建xlsx格式的excel文件,不能使用pycharm来创建
e.excel对象 -> sheet表单对象 -> cell单元格对象 -> 行和列、值属性
f.如果excel文件不存在,那么会FileNotFoundError
res = load_workbook("testcase11.xlsx")
1、load_workbook函数,来加载excel文件
a.第一个参数为excel文件名
b.如果excel文件不存在,那么会FileNotFoundError
c.返回Workbook对象,就相当于excel对象
2、active默认读取第一个表单
a.返回Worksheet,相当于sheet表单对象
ws = wb.active
Worksheet对象['sheet表单名'],能获取到指定表单对象
ws = wb['login']
3、读取指定单元格的数据
a.cell方法,获取单元格,返回Cell对象
b.Cell对象相当于cell单元格对象
c.可以使用Cell对象中的value来获取单元格的值# 在读取数据时,除了excel中的整型、小数、True、False,分别读取出来为int、float、boolean外,其他的数据都为字符串类型
one_cell = ws.cell(1, 1)
读excel操作的基本步骤:excel对象 -> sheet表单对象 -> cell单元格对象 -> 行和列、值属性
# 导入包 from openpyxl import load_workbook # 创建excel对象 wb = load_workbook("testcase.xlsx") # sheet对象,sheet对象名称为login ws = wb['login'] # 获取cell单元格对象 one_cell = ws.cell(1, 1) # 获取1行1列的值 cell_value = one_cell.value # 获取login表格中的所有数据 for row in range(1, ws.max_row+1): for column in range(1, ws.max_column+1): one_cell = ws.cell(row, column) print(f"单元格【{row},{column}】中的值为{one_cell.value} 类型为{type(one_cell.value)}")
写excel的基本步骤:excel对象 -> sheet表单对象 -> cell单元格对象 ->写入cell->excel对象保存
a.Workbook对象.save("excel文件名")
b.如果文件名与源文件不相同,那么会将源文件进行拷贝(赋值) wb.save("1.xlsx")
c.PermissionError: [Errno 13] Permission denied: 'testcase.xlsx'
对exel文件修改之后,要保存,一定要将excel文件关闭
from openpyxl import load_workbook # 1、load_workbook函数,来加载excel文件 excel_filename = "testcase.xlsx" wb = load_workbook(excel_filename) # 2、active默认读取第一个表单 ws = wb['login'] # 3、写入指定单元格的数据 one_cell = ws.cell(4, 1) one_cell.value = 3 # 4、保存excel wb.save(excel_filename)
2、excel封装
封装操作excel的类
1、需要传递的参数,即属性为excel文件名和sheet名
2、读数据,不传sheet名,默认第一个sheet,表头作为key,其他作为value,返回列表,列表中以各字典为元素(key = headers_list[column - 1] one_row_dict[key] = one_cell_value)
3、写数据,传入行列以及传入的值data
写入值的方法一:
one_cell = ws.cell(row, column)
one_cell.value = data
写入值的方法二:
ws.cell(row, column, value=data)
另外记得要保存
wb.save(self.filename)
from openpyxl import load_workbook class HandleExcel: def __init__(self, filename, sheetname=None): self.filename = filename self.sheetname = sheetname def read_data(self): """ 读数据 :return: """ wb = load_workbook(self.filename) if self.sheetname is None: ws = wb.active else: ws = wb[self.sheetname] testcases_list = [] headers_list = [] # 存放表头信息 for row in range(1, ws.max_row + 1): # 存放每一行的用例数据 one_row_dict = {} for column in range(1, ws.max_column + 1): one_cell_value = ws.cell(row, column).value # if one_cell_value is None: # continue if row == 1: headers_list.append(one_cell_value) else: key = headers_list[column - 1] one_row_dict[key] = one_cell_value if row != 1: testcases_list.append(one_row_dict) return testcases_list def write_data(self, row, column, data): """ 写操作 :param row: 指定在某一行写 :param column: 指定在某一列写 :param data: 待写入的数据 :return: """ # 将数据写入到excel中,不能与读取操作公用一个Workbook对象 # 如果使用同一个Workbook对象,只能将最后一次写入成功,会出现意想不到的结果 wb = load_workbook(self.filename) if self.sheetname is None: ws = wb.active else: ws = wb[self.sheetname] # 第一种写入方式: # one_cell = ws.cell(row, column) # one_cell.value = data # 第二种写入方式: ws.cell(row, column, value=data) wb.save(self.filename) if __name__ == '__main__': excel_filename = "testcase.xlsx" sheet_name = "login" do_excel = HandleExcel(excel_filename, sheet_name) print(do_excel.read_data()) # do_excel.write_data(3, 6, 2)
3、ddt模块
步骤:
1、引入ddt模块
2、使用ddt.ddt作为类的装饰器
3、使用ddt.data函数来装饰用例的实例方法,@ddt.data(用例1字典, 用例2字典, 用例3字典, ...)
# a.第一个参数:往往需要将序列类型(字符串、列表、元组)拆包
# b.ddt模块,会自动(动态)创建多个实例方法,实例方法名往往为test_register_用例的索引号(序号)
# c.每次循环会将data中的位置参数依次传给实例方法
import unittest
# ddt模块引入,建议安装1.2.1版本 import ddt from handle_request import HandleRequest from handle_excel import HandleExcel excel_filename = "testcase.xlsx" sheet_name = "login" do_excel = HandleExcel(excel_filename, sheet_name) testcase = do_excel.read_data() # 使用ddt.ddt作为类的装饰器 @ddt.ddt class TestLogin(unittest.TestCase): @classmethod def setUpClass(cls): cls.do_request = HandleRequest() headers_dict = { "X-Lemonban-Media-Type": "lemonban.v2", "User-Agent": "Mozilla/5.0 LookSky" } cls.do_request.add_headers(headers_dict) @classmethod def tearDownClass(cls): cls.do_request.close() @ddt.data(*testcase)
# @ddt.data(用例1字典, 用例2字典, 用例3字典, ...)
def test_login(self, testcase_dict): # 发起请求 res = self.do_request.send(testcase_dict["method"], testcase_dict["url"], json=testcase_dict["data"]) # 提取响应数据,然后断言结果 try: self.assertIn(testcase_dict["expected_value"], res.text, testcase_dict["name"]) except AssertionError as e: raise e if __name__ == '__main__': unittest.main()
4、数据(用例数据)驱动
a.往往一个接口拥有多条用例
b.每一条用例执行时,仅仅只有用例的数据(参数)不同,而用例的执行逻辑几乎一致
c.为了减少代码量,让框架更加简洁,所以会让用例数据(excel)与用例执行逻辑进行分离,这种机制称为数据驱动
d.会把data拆包之后的形参依次传给test_register实例方法的第二个形参