excel读写测试数据
首先在同一文件夹下创建一个名为cases的xlsx格式的excel文件
该excel中有张名为yuan的sheet,其中的数据如下:
一、读取excel中的数据
1、将excel表格加载为工作簿对象
2、选定其中的某张表单
3、读取指定的格子对象
例如,读取其中第一行第二列的case_name:
import openpyxl
wb = openpyxl.load_workbook("cases.xlsx")
sh = wb["yuan"]
c12 = sh.cell(row=1, column=2).value
print(c12) #得到结果:case_name
二、写入数据
例如,在第一行第五列写入:python666
import openpyxl
wb = openpyxl.load_workbook("cases.xlsx")
sh = wb["yuan"]
sh.cell(row=1, column=5, value="python666")
wb.save("cases.xlsx")
注意,最后要save操作才能将数据存入excel中,此外,写入数据时务必保持excel是关闭状态,否则会写不进去
三、获取表单的最大行和最大列
import openpyxl
wb = openpyxl.load_workbook("cases.xlsx")
sh = wb["yuan"]
max_row = sh.max_row
max_column = sh.max_column
print(max_row, max_column) #得到结果:6 4
四、rows
rows:按行获取表单中的格子对象,一行的格子对象放在一个元组中
import openpyxl
wb = openpyxl.load_workbook("cases.xlsx")
sh = wb["yuan"]
res = list(sh.rows)
print(res)
得到的结果如下:
[(<Cell 'yuan'.A1>, <Cell 'yuan'.B1>, <Cell 'yuan'.C1>, <Cell 'yuan'.D1>, <Cell 'yuan'.E1>),
(<Cell 'yuan'.A2>, <Cell 'yuan'.B2>, <Cell 'yuan'.C2>, <Cell 'yuan'.D2>, <Cell 'yuan'.E2>),
(<Cell 'yuan'.A3>, <Cell 'yuan'.B3>, <Cell 'yuan'.C3>, <Cell 'yuan'.D3>, <Cell 'yuan'.E3>),
(<Cell 'yuan'.A4>, <Cell 'yuan'.B4>, <Cell 'yuan'.C4>, <Cell 'yuan'.D4>, <Cell 'yuan'.E4>),
(<Cell 'yuan'.A5>, <Cell 'yuan'.B5>, <Cell 'yuan'.C5>, <Cell 'yuan'.D5>, <Cell 'yuan'.E5>),
(<Cell 'yuan'.A6>, <Cell 'yuan'.B6>, <Cell 'yuan'.C6>, <Cell 'yuan'.D6>, <Cell 'yuan'.E6>)] #为方便看将结果从一行分成了若干行
可以通过两层for循环将其中的值取出来:
import openpyxl
wb = openpyxl.load_workbook("cases.xlsx")
sh = wb["yuan"]
res = list(sh.rows)
for item in res:
for i in item:
print(i.value, end=" ")
print("")
得到结果如下:
case_id case_name expected data None
1 账号密码正确 {"code": 0, "msg": "登陆成功"} ["python", "123456"] None
2 账号正确,密码错误 {"code": 1, "msg": "账号或密码不正确"} ["python", "12345"] None
3 账号错误,密码正确 {"code": 1, "msg": "账号或密码不正确"} ["pyth", "123456"] None
4 账号为空 {"code": 1, "msg": "所有参数不能为空"} [None, "123456"] None
5 密码为空 {"code": 1, "msg": "所有参数不能为空"} ["python", None] None
五、columns
columns:按列获取表单中的格子对象,一列的格子对象放在一个元组中
使用方式同rows
六、获取指定行或列中的数据
结合rows、columns以及列表的取值或切片操作即可
例如:获取第二列到第三列的内容
import openpyxl
wb = openpyxl.load_workbook("cases.xlsx")
sh = wb["yuan"]
res = list(sh.columns)
for item in res[1:3]:
print("这是第{}列中的数据:".format(res.index(item) + 1))
for i in item:
print(i.value, end=";")
print("")
得到结果如下:
这是第2列中的数据:
case_name;账号密码正确;账号正确,密码错误;账号错误,密码正确;账号为空;密码为空;
这是第3列中的数据:
expected;{"code": 0, "msg": "登陆成功"};{"code": 1, "msg": "账号或密码不正确"};{"code": 1, "msg": "账号或密码不正确"};{"code": 1, "msg": "所有参数不能为空"};{"code": 1, "msg": "所有参数不能为空"};
七、封装读取excel代码
注:从excel中读取的数据,除了数值外,均为字符串格式
需求:将上面excel中的内容读取出来,返回的形式就如同测试用例中列表嵌套字典的形式:
[{"expected": {"code": 0, "msg": "登陆成功"}, "data": ["python", "123456"]},
{"expected": {"code": 1, "msg": "账号或密码不正确"}, "data": ["python", "12345"]},
{"expected": {"code": 1, "msg": "账号或密码不正确"}, "data": ["pyth", "123456"]},
{"expected": {"code": 1, "msg": "所有参数不能为空"}, "data": [None, "123456"]},
{"expected": {"code": 1, "msg": "所有参数不能为空"}, "data": ["python", None]},
]
对该功能进行封装:
import openpyxl
class HandleExcel:
def __init__(self, filename, sheetname):
self.filename = filename
self.sheetname = sheetname
def read_data(self):
wb = openpyxl.load_workbook(self.filename)
sh = wb[self.sheetname]
res = list(sh.rows)
case_data = []
key = []
for item in res[0]:
key.append(item.value)
for item in res[1:]:
value = []
for i in item:
value.append(i.value)
case_every = dict(zip(key, value))
case_data.append(case_every)
return case_data
if __name__ == "__main__":
wb1 = HandleExcel("cases.xlsx", "yuan")
res_data = wb1.read_data()
print(res_data)
封装后,调用一下看看print出的效果:
[{'case_id': 1, 'case_name': '账号密码正确', 'expected': '{"code": 0, "msg": "登陆成功"}', 'data': '["python", "123456"]'}, {'case_id': 2, 'case_name': '账号正确,密码错误', 'expected': '{"code": 1, "msg": "账号或密码不正确"}', 'data': '["python", "12345"]'}, {'case_id': 3, 'case_name': '账号错误,密码正确', 'expected': '{"code": 1, "msg": "账号或密码不正确"}', 'data': '["pyth", "123456"]'}, {'case_id': 4, 'case_name': '账号为空', 'expected': '{"code": 1, "msg": "所有参数不能为空"}', 'data': '[None, "123456"]'}, {'case_id': 5, 'case_name': '密码为空', 'expected': '{"code": 1, "msg": "所有参数不能为空"}', 'data': '["python", None]'}]
已经基本变成了需求的样式,唯一的区别在于:由于读取excel中的内容除了数值以外均是字符串,所以每个字典中的值的类型变成了数值或是字符串
在定义测试用例方法的过程中,可对上述问题进行解决,取出键对应的值后通过eval将其变为python中的有效格式:
import unittest
from ddt import ddt, data
from exercise04_ddt.funcdemo_unittest import login_check
from exercise05_excel.python_excel读取封装 import HandleExcel
@ddt
class LoginTestCase(unittest.TestCase):
excel = HandleExcel("cases.xlsx", "yuan")
res_data = excel.read_data() # res_data就是列表嵌套字典的测试用例所需数据形式,但是字典中的值都是数值或字符串类型
@data(*res_data)
def test_login(self, case):
expected = eval(case["expected"])
data = eval(case["data"])
res = login_check(*data)
self.assertEqual(expected, res)
八、封装写入excel代码
封装写入excel的代码如下:
import openpyxl
class HandleExcel:
def __init__(self, filename, sheetname):
self.filename = filename
self.sheetname = sheetname# 封装写入excel的代码
def write_data(self, row, column, value):
wb = openpyxl.load_workbook(self.filename)
sh = wb[self.sheetname]
sh.cell(row=row, column=column, value=value)
wb.save(self.filename)
利用封装好的功能代码,可以实现读取excel中的测试用例数据,并将测试结果写入excel中:
import unittest
from ddt import ddt, data
from exercise04_ddt.funcdemo_unittest import login_check
from exercise05_excel.python_excel读取和写入封装 import HandleExcel
@ddt
class LoginTestCase(unittest.TestCase):
excel = HandleExcel("cases.xlsx", "yuan")
res_data = excel.read_data() # res_data就是列表嵌套字典的测试用例所需数据形式,但是字典中的值都是数值或字符串类型
@data(*res_data)
def test_login(self, case):
expected = eval(case["expected"])
data = eval(case["data"])
res = login_check(*data)
row = case["case_id"] + 1
try:
self.assertEqual(expected, res)
except AssertionError as e:
self.excel.write_data(row=row, column=5, value="用例未通过")
raise e
else:
self.excel.write_data(row=row, column=5, value="用例通过")
注意:通过异常捕获,对用例通过与未通过进行了分开的写入处理,但由于在捕获了异常后将不会再报断言异常,而unittest又是通过断言是否异常来判断测试用例是否通过的,所以在捕获异常、写入数据后进行主动抛出异常