成长之路-- 从0开始学python(17)--Excel结合测试用例使用&数据驱动

2023-11-06

一般自动化测试的流程

 

-准备测试数据(根据被测函数的参数)

-调用被测函数,得到实际结果

-断言

这样的方法可以完成测试,但是存在不少的缺点

-一个用例需要单独编写一个测试用例函数/方法,存在重复性代码(可以通过ddt解决)

-测试的数据都放在用例的方法里,如果哪个数据需要改动,那么全部方法里的相关数据都要改

 数据维护起来不方便(通过把数据存放到excel表格中管理)

所以,我们需要把数据单独放到excel表格中管理,之后有需要修改只需要在表格中修改便可

通过read_exce方法读取excel当中的数据,作为被测函数/方法的参数

1.把测试用例的数据放到表格中

如果被测函数的参数较多,写入excel时可以把被测函数的参数用字典的方式填入excel的一个单元格中,调用数据时候方便查看

之前我们封装的read_excel函数,得到的结果是一个列表嵌套元组

这样提取数据并不方便,比如只看到一个1,也很容易忘记是什么数据,所以需要在函数里继续对函数进行操作,转换成一个列表嵌套字典的形式,也方便我们查看数据和提取数据

from openpyxl import load_workbook

def read_excel(excel_name,sheet_name):
    #得到工作簿
    wb = load_workbook(excel_name)
    #得到工作表
    sheet = wb[sheet_name]
    #读取所有数据
    data = list(sheet.values) #得到一个列表,包括标题,值
    key = data[0]
    data_1 = [dict(zip(key, value))for value in data[1:]] #列表推导式,从列表第二个元素开始到最后都跟第一个元素合并字典
    return data_1

 然后再把这个函数封装到excel类里,方便之后时候

 

2.使用封装好的excel类里的read_excel方法

login_data = ExcelHandle(case_file,"login").read_excel()

从ExcelHandle类里获取对象,然后使用read_excel()方法,得到的结果是一个列表嵌套字典

 小套路:测试自己封装好的函数/方法,减少测试时候发生的错误

if __name__ == '__main__':
    data  = read_excel(r"E:\lemmon-public\lesson\lesson15_excel结合用例使用\cases01.xlsx",'Sheet1')
    print(data)

 点击旁边的按钮可以运行上面的函数,但是在其他模块调用这个函数的时候不会执行这段代码,这种方法可以自行测试编写的代码是否能运行成功

错误操作

当我们准备好测试数据之后.我们就需要把excel表格的数据导入测试用例函数

import unittest

from lesson.lesson15_excel结合用例使用.funcs_login import login
from lesson.lesson15_excel结合用例使用.read_excel import read_excel
data = read_excel(r"E:\lemmon-public\lesson\lesson15_excel结合用例使用\cases01.xlsx","Sheet1")

class TestLongin(unittest.TestCase):

    def test_login(self):
        for row in data: #遍历data列表,得出每个元素(字典)
            params_str = row['data'] #取字典中key为data的值,因为是从excel中获取 所以是字符串不是字典
            params = eval(params_str) #转换成字典
            username = params["username"] #从嵌套的字典里获取值
            password = params["password"]
            expected = row["expected"]
            actual = login(username,password) #调用被测函数,传入数据
            self.assertEqual(expected ,actual)

写for是为了减少重复编写测试用例方法,但是这样的操作存在两个问题

1.测试用例函数用for循环,unittest只发现了一个用例,实际上我们想要的是3个用例,不能在测试用例函数中用循环

2.代码有错误 username = params["username"]  TypeError: string indices must be integers

excel当中不存在字典,字典是python中的概念.如果单元格中有文本,读取出来基本上都是字符串

需要把字符串转换字典 eval()

通过eval()函数转换了数据类型后,我们就可以用代码获取字典里的数据,但是目前只解决了测试数据单独管理的问题,所以这时候需要用到参数化,数据驱动来实现多个测试用例函数

通过参数化(ddt)完成数据到用例的结合

参数化:用例函数参数. 一个测试函数当中会带参数,该参数往往就是测试用例数据,没有声明参数化,用例函数不能随便加入参数

数据驱动(data drive testing , ddt)

用法1:

-在unittestreport导入ddt,list_data

from unittestreport import ddt,list_data

-在类上面声明ddt,表示对这个类使用数据驱动

#在类上声明ddt
@ddt
class TestLogin(unittest.TestCase):

-在方法上面声明list_data(),参数输入要参数化的数据(读取excel得出的列表数据[{},{},{}])

    #在方法上面声明list_data
    @list_data(data)
    #在方法的参数输入一个变量
    def test_login(self,row):

-在测试用例方法传入参数,相当于遍历列表,每次取出列表的一个元素,也就是每一组测试用例的所有数据

-方法里获取被测函数需要的数据

import unittest
from unittestreport import ddt,list_data
from lesson.lesson15_excel结合用例使用 import funcs_login
from lesson.lesson15_excel结合用例使用 import read_excel
#data代表要运行的所有测试数据[{},{},{}]
data = read_excel.read_excel(r"E:\lemmon-public\lesson\lesson15_excel结合用例使用\cases01.xlsx","Sheet1")

#在类上声明ddt
@ddt
class TestLogin(unittest.TestCase):
    #在方法上面声明list_data
    @list_data(data)
    #在方法的参数输入一个变量
    def test_login(self,row):
        #row 代表每次从data这个list当中取出其中一组数据{},相当于 for row in data
        #源码:会自动生成一个新的test_login1函数
        params_str = row['data']
        params = eval(params_str)
        username = params["username"]
        password = params["password"]
        expected_str = row["expected"]  #excel里就算填字典,因为不识别,所以读取时候仍然是字符串
        expected = eval(expected_str)
        actual = funcs_login.login(username,password)
        self.assertEqual(expected ,actual)

用法2:

-通过ddt导入ddt,data

from ddt import ddt,data

-在类上面声明ddt

#在类上声明ddt
@ddt
class TestLogin(unittest.TestCase):

-在方法上面声明data(*测试数据[{},{},{}]) 参数要加*号

    #在方法上面声明data,参数要加*号
    @data(*excle)
    #在方法的参数输入一个变量
    def test_login(self,row):

-在方法里获取数据

import unittest
from ddt import ddt,data
from lesson.lesson15_excel结合用例使用.funcs_login import login
from lesson.lesson15_excel结合用例使用.read_excel import read_excel
#data代表要运行的所有测试数据[{},{},{}]
excle = read_excel(r"E:\lemmon-public\lesson\lesson15_excel结合用例使用\cases01.xlsx","Sheet1")

#在类上声明ddt
@ddt
class TestLogin(unittest.TestCase):
    #在方法上面声明data,参数要加*号
    @data(*excle)
    #在方法的参数输入一个变量
    def test_login(self,row):
        #row 代表每次从data这个list当中取出其中一组数据{},相当于 for row in data
        #远吗:会自动生成一个新的test_login1函数
        params_str = row['data']
        params = eval(params_str)
        username = params["username"]
        password = params["password"]
        expected_str = row["expected"]  #excel里就算填字典,因为不识别,所以读取时候仍然是字符串
        expected = eval(expected_str)
        actual = login(username,password)
        self.assertEqual(expected ,actual)

由此可见,对一个测试逻辑一致,数据不一致的用例通过参数化可以整合到一个自动化用例函数

用数据驱动和参数化后:用例函数只需要写一个,数据可以有多个甚至上万个,节省很多测试用例函数

拓展:测试结果写入excel

我们可以通过写入excel函数,把测试结果通过代码写入excel

1,首先要在测试用例类里继承之前封装好的excel类

@ddt
class TestLogin(unittest.TestCase,ExcelHandle):

2,设置夹具的前置条件

表示每次执行测试用例的时候,需要获得excel类的对象,相当于打开excel表格,因为之后要在测试用例类里使用excel类的方法

 def setUp(self) -> None:
        self.excel_info = ExcelHandle(case_file,"login")

在用例代码最后使用类的方法

self.excel_info.write_excel(row=info["case_id"] + 1, column=8, value=result)

也可以在测试用例类的外层先获取excel类的对象,这样可以不用继承ExcelHandle

excel_info =ExcelHandle(case_file,"login")

使用写入的方法

excel_info.write_excel(row=info["case_id"] + 1, column=8, value=result)

-注意事项:

excel当中不存在字典,字典是python中的概念.如果单元格中有文本,读取出来基本上都是字符串

参数化不能用for循环,因为for循环虽然可以执行多个数据,但是在自动化测试方法里,只会被当成一个用例

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

成长之路-- 从0开始学python(17)--Excel结合测试用例使用&数据驱动 的相关文章

  • python 可以检测它运行在哪个操作系统下吗?

    python 可以检测操作系统 然后为文件系统构建 if else 语句吗 我需要将 Fn 字符串中的 C CobaltRCX 替换为 FileSys 字符串 import os path csv from time import strf
  • 在 Python 中使用 XPath 和 LXML

    我有一个 python 脚本 用于解析 XML 并将某些感兴趣的元素导出到 csv 文件中 我现在尝试更改脚本以允许根据条件过滤 XML 文件 等效的 XPath 查询将是 DC Events Confirmation contains T
  • 如何更改充当按钮的范围的文本

    我正在为自定义 Web 应用程序编写自动化测试 我遇到了无法更改跨度文本的问题 我尝试过使用 driver execute script 但没有运气 如果我更好地了解 javascript 这确实会有帮助 据我所知 您无法单击跨度 并且列表
  • 在 Python 中使用 sec 函数的反函数

    我正在创建一个程序 用于计算从一定高度范围和设定初始速度发射射弹的最佳角度 在我需要使用的最终方程中 存在一个反 sec 函数 它导致了一些麻烦 我已经导入了数学并尝试使用 asec 无论如何 但是数学似乎无法计算反秒函数 我也明白 sec
  • Python 中 genfromtxt() 的可变列数?

    我有一个 txt具有不同长度的行的文件 每一行都是代表一条轨迹的一系列点 由于每条轨迹都有自己的长度 因此各行的长度都不同 也就是说 列数从一行到另一行不同 据我所知 genfromtxt Python 中的模块要求列数相同 gt gt g
  • 使用正则表达式解析 Snort 警报文件

    我正在尝试使用 Python 中的正则表达式从 snort 警报文件中解析出源 目标 IP 和端口 和时间戳 示例如下 03 09 14 10 43 323717 1 2008015 9 ET MALWARE User Agent Win9
  • 将一个时间序列插入到 pandas 中的另一个时间序列中

    我有一组定期测量的值 说 import pandas as pd import numpy as np rng pd date range 2013 01 01 periods 12 freq H data pd Series np ran
  • 如何使用 openpyxl 对工作簿中的 Excel 工作表/选项卡进行排序

    我需要按字母数字对工作簿中的选项卡 工作表进行排序 我在用openpyxl https openpyxl readthedocs io en default 操作工作表 您可以尝试排序workbook sheets list workboo
  • VSCode pytest 测试发现失败

    Pytest 测试发现失败 用户界面指出 Test discovery error please check the configuration settings for the tests 输出窗口显示 Test Discovery fa
  • 如何为多组精灵创建随机位置?

    我尝试使用 blit 和 draw 方法进行 for 循环 并为 PlayerSprite 和 Treegroup 使用不同的变量 for PlayerSprite in Treegroup surface blit PlayerSprit
  • 使用 genfromtxt 导入 numpy 中缺失值的 csv 数据

    我有一个 csv 文件 看起来像这样 实际文件有更多的列和行 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 假设文件的名称是info csv如果我尝试使用导入它 data numpy genfromtxt i
  • Pandas:根据列名进行列的成对乘法

    我有以下数据框 gt gt gt df pd DataFrame ap1 X 1 2 3 4 as1 X 1 2 3 4 ap2 X 2 2 2 2 as2 X 3 3 3 3 gt gt gt df ap1 X as1 X ap2 X a
  • 在 Mac 上安装 Pygame 到 Enthought 构建中

    关于在 Mac 上安装 Pygame 有许多未解答的问题 但我将在这里提出我的具体问题并希望得到答案 我在 Mac 上安装 Pygame 时遇到了难以置信的困难 我使用 Enthought 版本 EPD 7 3 2 32 位 它是我的默认框
  • urllib2.urlopen() 是否实际获取页面?

    当我使用 urllib2 urlopen 时 我在考虑它只是为了读取标题还是实际上带回整个网页 IE 是否真的通过 urlopen 调用或 read 调用获取 HTML 页面 handle urllib2 urlopen url html
  • 负整数的Python表示

    gt gt gt x 4 gt gt gt print b format x x 4 100 gt gt gt mask 0xFFFFFFFF gt gt gt print b format x mask x mask 4294967292
  • Python模块单元测试的最佳文件结构组织?

    遗憾的是 我发现有太多方法可以在 Python 中保存单元测试 而且它们通常没有很好的文档记录 我正在寻找一种 终极 结构 它可以满足以下大部分要求 be discoverable by test frameworks including
  • Scrapy 蜘蛛无法工作

    由于到目前为止没有任何效果 我开始了一个新项目 python scrapy ctl py startproject Nu 我完全按照教程操作 创建了文件夹和一个新的蜘蛛 from scrapy contrib spiders import
  • Pandas 在特定列将数据帧拆分为两个数据帧

    I have pandas我组成的 DataFrameconcat 一行由 96 个值组成 我想将 DataFrame 从值 72 中分离出来 这样 一行的前 72 个值存储在 Dataframe1 中 接下来的 24 个值存储在 Data
  • PyQt 中的线程和信号问题

    我在 PyQt 中的线程之间进行通信时遇到一些问题 我使用信号在两个线程 发送者和监听者 之间进行通信 发送者发送消息 期望被监听者接收 但是 没有收到任何消息 谁能建议可能出了什么问题 我确信这一定很简单 但我已经环顾了几个小时但没有发现
  • 使用“pythonw”(而不是“python”)运行应用程序时找不到模块

    我尝试了这个最小的例子 from flask import Flask app Flask name app route def hello world return Hello World if name main app run deb

随机推荐