接口测试 unittest+request+ddt+openpyxl 接口自动化在写入文件时仅能成功写入一张表

小雩 · 2021年11月27日 · 最后由 小雩 回复于 2021年11月27日 · 1929 次阅读

遇到一个问题困扰了很久,希望大佬们能解答一下,万分感谢!
问题是这样的:
1.首先我使用 Excel 管理测试用例,一个接口使用的一个 sheet,类似这样

2.然后使用 openpyxl 来读写这个 Excel,代码如下:

excel_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "testdata", "case.xlsx")


class OperateExcel:
    def __init__(self, sheet_name):
        """
        初始化数据
        """
        self.path = excel_path
        self.wb = openpyxl.load_workbook(self.path)
        self.ws = self.wb[sheet_name]

    def read_excel(self):
        """
        将所有用例按字典格式转化后加入到列表data_all
        :return: data_all
        """
        # 通过遍历行读取Excel数据并将每行加入到一个列表row_list,ws.rows相当于一个生成器
        data_list = []
        for row in self.ws.rows:
            row_list = []
            for cell in row:
                row_list.append(cell.value)
            data_list.append(row_list)
        # 将第一行与非第一行进行字典转化,并加入到列表data_all
        data_all = []
        for i in data_list[1:]:
            x = dict(zip(data_list[0], i))
            data_all.append(x)
        self.wb.close()
        return data_all

    def write_excel(self, row, actually, result):
        """
        将actually和result分别写入H和I列的第row行
        :param row:要写入的行
        :param result:要传入的测试结果,如:pass,failed,blocked
        :param actually:要写入的数据
        :return:
        """
        self.ws["H{}".format(row)] = actually
        self.ws["I{}".format(row)] = result
        self.wb.save(self.path)
        self.wb.close()

    def write_header(self, header):
        """
        将header写入excel
        :param header: header值
        :return:
        """
        for i in range(2, self.ws.max_row + 1):
            self.ws["E{}".format(i)] = header
        self.wb.save(self.path)
        self.wb.close()

3.然后编写测试用例文件,一个接口一个 py

# 调用鉴权接口获取token
token = get_token("test_account2")
# 实例化操作Excel
excel = OperateExcel("add_bankcard")
# 将token写入Excel的header
excel.write_header(token)
log.info("向Excel中写入header")


@ddt
class AddBankCard(unittest.TestCase):
    # 读取add_bankcard获取测试数据
    cases = excel.read_excel()

    def setUp(self):
        log.info("................开始执行用例................")

    @data(*cases)
    def test_add_bankcard(self, case):
        """
        新增银行卡
        """
        log.info("当前执行用例:{}".format(case["标题"]))
        test_response = RequestType().get_request(case["请求方式"], case["URL"], json.loads(case["header"]),
                                                  json.loads(case["param"]))
        # 将返回值转化为json格式,并获取msg值
        test_actually = json.loads(test_response)["msg"]
        try:
            # 断言期望与实际返回是否一致
            self.assertEqual(case["预期返回"], test_actually)
        except AssertionError as e:
            # 断言失败则将返回写入Excel并将测试结果置为failed
            # excel.write_excel(case["id"] + 1, test_response, "failed")
            log.error("断言失败{}".format(e))
            raise
        finally:
            # 将返回与测试结果写入Excel
            excel.write_excel(case["id"] + 1, test_response, "pass")
            log.info("当前预期结果:{},实际返回结果:{}".format(case["预期返回"], test_actually))

    def tearDown(self):
        pass

4.最后利用 unittest 框架将所有 py 文件中测试用例加入到测试套件中

# 测试用例路径
case_path = os.path.join(os.path.dirname(os.path.abspath(".")), "testcases")
# 测试报告路径
report_path = os.path.join(os.path.dirname(os.path.abspath(".")), "reports")
# 测试套件实例化
test_suite = unittest.TestSuite()
test_loader = unittest.TestLoader()
# 收集器TestLoader方法discover收集测试用例
test_discover = test_loader.discover(case_path, pattern="*.py", top_level_dir=None)
# 将空用例排除
for case in test_discover:
    if case == []:
        pass
    else:
        test_suite.addTests(case)

if __name__ == "__main__":
    result = BeautifulReport(test_suite)
    result.report(filename="Test Report", description="接口测试报告", report_dir=report_path)

然后问题就出现了,所有用例都执行了我也打印出了接口返回结果都没问题,然而接口返回结果只有第一张表将数据写入成功了,第二张表只写入了 header,实际返回和测试结果一直都是空。
如若我将第二张表的测试用例贴到第一张表格就能全部将结果写入,两张表格则无法使用 write_excel 写入第二张表

共收到 1 条回复 时间 点赞

已找到问题
产生该问题的原因在于我将打开 Excel 这个写到初始化函数中,导致我在调用写函数时没有拿到最新的 sheet_name,仍用的之前打开的 sheet_name
附上修改后代码:

excel_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "testdata", "case.xlsx")


class OperateExcel:
    def __init__(self, sheet_name, file_name=excel_path):
        """
        初始化数据
        """
        self.file = file_name
        self.sheet_name = sheet_name

    def read_excel(self):
        """
        将所有用例按字典格式转化后加入到列表data_all
        :return: data_all
        """
        wb = openpyxl.load_workbook(self.file)
        ws = wb[self.sheet_name]
        # 通过遍历行读取Excel数据并将每行加入到一个列表row_list,ws.rows相当于一个生成器
        data_list = []
        for row in ws.rows:
            row_list = []
            for cell in row:
                row_list.append(cell.value)
            data_list.append(row_list)
        # 将第一行与非第一行进行字典转化,并加入到列表data_all
        data_all = []
        for i in data_list[1:]:
            x = dict(zip(data_list[0], i))
            data_all.append(x)
        wb.close()
        return data_all

    def write_excel(self, row, actually, result):
        """
        将actually和result分别写入H和I列的第row行
        :param row:要写入的行
        :param result:要传入的测试结果,如:pass,failed,blocked
        :param actually:要写入的数据
        :return:
        """
        wb = openpyxl.load_workbook(self.file)
        ws = wb[self.sheet_name]
        # self.ws.cell(row=row, column=8).value = actually
        # self.ws.cell(row=row, column=9).value = result
        ws["H{}".format(row)] = actually
        ws["I{}".format(row)] = result
        wb.save(self.file)
        wb.close()

    def write_header(self, header):
        """
        将header写入excel
        :param header: header值
        :return:
        """
        wb = openpyxl.load_workbook(self.file)
        ws = wb[self.sheet_name]
        for i in range(2, ws.max_row + 1):
            ws["E{}".format(i)] = header
        wb.save(self.file)
        wb.close()
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册