当前位置: 首页 > ds >正文

【web 自动化】-6- 数据驱动DDT

一、参数化数据驱动测试

1. 核心概念:“数据驱动测试” 解决什么问题?

场景:测试 “后台登录” 时,用例流程固定(输入账号→密码→登录→断言 ),但需要测不同数据:

  • 正确账号密码(正例 )
  • 错误密码、空账号(反例 )

传统做法:写多个用例,重复流程代码,只改数据 → 冗余、难维护。

数据驱动测试:用一套流程代码 + 多组测试数据,让用例自动遍历数据执行 → 高效、覆盖全。

2. pytest 实现参数化的核心:@pytest.mark.parametrize

1. 基础用法(数据少直接写死)
import pytest# 测试数据:[(正例), (反例1), (反例2)]
test_data = [("admin", "123456", "登录成功"),  # 正例("admin", "wrong_pwd", "密码错误"),  # 反例("", "123456", "账号不能为空"),  # 反例
]# 参数化装饰器:把 test_data 拆成 username/password/assert_msg 传给用例
@pytest.mark.parametrize("username, password, assert_msg", test_data)
def test_login(username, password, assert_msg):# 模拟登录流程(实际会用 Selenium 操作浏览器)def mock_login(user, pwd):if user == "admin" and pwd == "123456":return "登录成功"elif user == "":return "账号不能为空"else:return "密码错误"# 执行登录result = mock_login(username, password)# 断言结果assert result == assert_msg

效果

  • test_login 会自动运行 3 次,每次用不同数据 → 1 套代码覆盖多场景。

3. 结合实际 Web 自动化(Selenium + 参数化)

1. 流程代码(POM 模式,复用之前的设计)
# pages/login_page.py(页面对象,封装登录操作)
from selenium.webdriver.common.by import Byclass LoginPage:def __init__(self, driver):self.driver = driverself.user_input = (By.ID, "username")self.pwd_input = (By.ID, "password")self.login_btn = (By.ID, "login-btn")self.msg = (By.CLASS_NAME, "msg")def input_username(self, user):self.driver.find_element(*self.user_input).send_keys(user)def input_password(self, pwd):self.driver.find_element(*self.pwd_input).send_keys(pwd)def click_login(self):self.driver.find_element(*self.login_btn).click()def get_msg(self):return self.driver.find_element(*self.msg).text
2. 参数化测试用例(数据驱动)
# tests/test_login.py
import pytest
from selenium import webdriver
from pages.login_page import LoginPage# 测试数据(实际可从 CSV/Excel 读取)
test_data = [("admin", "123456", "登录成功"),("admin", "wrong", "密码错误"),("", "123456", "账号不能为空"),
]@pytest.mark.parametrize("username, password, assert_msg", test_data)
def test_login_parametrize(username, password, assert_msg):# 1. 初始化浏览器driver = webdriver.Chrome()driver.get("http://your-login-url.com")driver.maximize_window()# 2. 初始化页面对象login_page = LoginPage(driver)# 3. 执行登录流程login_page.input_username(username)login_page.input_password(password)login_page.click_login()# 4. 获取结果并断言result = login_page.get_msg()assert result == assert_msg# 5. 关闭浏览器driver.quit()

关键点

  • @pytest.mark.parametrize 让用例自动遍历 test_data
  • 结合 POM 模式,流程代码(输入、点击、断言 )复用,只换数据。

 

4. 数据量大时:从 CSV/Excel 读取数据

从 CSV 读取
import csvdef get_csv_data():test_data = []with open("login_data.csv", "r", encoding="utf-8") as f:reader = csv.reader(f)next(reader)  # 跳过表头for row in reader:test_data.append((row[0], row[1], row[2]))return test_data# 参数化用例,数据来自 CSV
@pytest.mark.parametrize("username, password, assert_msg", get_csv_data())
def test_login_from_csv(username, password, assert_msg):# 同上,执行登录流程...

CSV 文件示例(login_data.csv)

username,password,assert_msg
admin,123456,登录成功
admin,wrong,密码错误
,123456,账号不能为空

 

5. “数据驱动” 的核心价值

  1. 高效覆盖场景:1 套流程代码 → 覆盖正例、反例(如密码错误、账号为空 )。
  2. 数据与代码分离:改数据只需改 CSV/Excel,不用动代码 → 非技术人员也能维护。
  3. 减少冗余:避免写多个重复用例,代码更简洁。

 

6. 文中提到的 “注意点” 解析

  1. 区分正反例:数据里要包含 “正确” 和 “错误” 场景(如正例用正确密码,反例用错误密码 )。
  2. 页面跳转 / 刷新:执行完登录后,需确保页面跳转正确(如断言 URL 变化 )。
  3. 页面处理结果:登录后可能有弹窗、提示信息,需用代码捕获并断言(如 get_msg 方法 )。

 

二、Csv

一、CSV 文件基础认知

  • 特点:文本格式存数据,表格形式展示(逗号分隔字段,换行分隔行 )。
  • 作用:把测试数据(如登录的用户名、密码、预期结果 )从代码中分离,便于维护和扩展。

二、get_csv_data():读取 CSV 数据

def get_csv_data():list1 = []# 打开 CSV 文件,指定编码为 UTF-8cl = csv.reader(open(r"D:\Project234_web\data\后台登录数据内容.csv", encoding="UTF-8"))for i in cl:list1.append(i)  # 逐行读取,存入列表return list1

  • 功能:读取 CSV 文件内容,返回一个二维列表。
    • 示例:若 CSV 内容是
      admin,123,登录成功  
      test,456,密码错误  
      

      返回 [["admin","123","登录成功"], ["test","456","密码错误"]]
  • 细节
    • csv.reader:按行解析 CSV,每行数据是一个列表。
    • 硬编码路径 r"D:\Project234_web\data\...":实际项目建议用动态路径(如 os.path 拼接 )。

 

三、pytest.mark.parametrize:参数化驱动测试

@pytest.mark.parametrize("username,password,assert_msg", get_csv_data())
def test_admin_parameterize(driver, username, password, assert_msg):# 1. 打开登录页driver.get("http://47.107.116.139/fangwei/m.php?m=Public&a=login&")driver.maximize_window()# 2. 初始化页面对象(POM 模式)page = BackgroundLoginPage(driver)# 3. 处理验证码(假设 save_code_img 是截图/识别验证码的逻辑)code = save_code_img(driver)# 4. 执行登录,获取返回信息msg = page.login(username, password, code)print(msg)assert msg == assert_msg 

  • 核心逻辑
    1. 参数化标记@pytest.mark.parametrize 会遍历 get_csv_data() 返回的列表,把每行数据拆分为 usernamepasswordassert_msg,传给测试用例。
    2. 数据驱动测试:相当于自动生成多组测试用例,每组用不同的 CSV 数据执行登录流程。

 

四、完整流程与价值

  1. 数据分离:测试数据存在 CSV,改数据不用动代码。
  2. 多组用例:一行 CSV 数据对应一条测试用例,自动执行多组登录场景(如正确 / 错误密码 )。
  3. 复用性get_csv_data() 可被其他用例调用,parametrize 让参数化逻辑通用。

 

三、Excel

一、核心目标

把测试数据(如登录账号、密码、预期结果 )存在 Excel 里,用代码读取后,驱动自动化测试(如登录流程 ),实现 “数据与代码分离”,让测试更灵活(改数据只需改 Excel,不用动代码 )。

二、依赖库:xlrd

  • 作用:Python 中用于读取 Excel(.xls.xlsx )文件的库。
  • 安装pip install xlrd(注意:xlrd 对新版 .xlsx 支持有限,若报错可换 openpyxl 等库 )。

三、代码逐行解析

# 使用Excel表格读取数据
import xlrd# 1. 打开Excel文件
xls = xlrd.open_workbook("D:\Project234_web\data\msjy3.xlsx")# 2. 获取指定Sheet(通过下标,0 表示第一个Sheet)
sheet = xls.sheet_by_index(0)# (可选)查看Sheet的列数、行数
# print(sheet.ncols)  # 输出列数
# print(sheet.nrows)  # 输出行数(包含表头)# 3. 遍历读取数据(跳过表头,从第1行开始)
list1 = []
for i in range(1, sheet.nrows):  # range(1, 行数):跳过第0行(表头)# 获取第i行的所有单元格值,返回列表row_data = sheet.row_values(i)  list1.append(row_data)  # 存入结果列表else:# 遍历结束后执行(可选:打印读取的结果)print(list1)

四、关键逻辑说明

  1. 打开 Excel 文件
    xlrd.open_workbook("路径"):传入 Excel 文件的绝对路径,加载整个工作簿。

  2. 选择 Sheet

    • sheet_by_index(0):通过下标选 Sheet(0 是第一个 Sheet )。
    • 也可用 sheet_by_name("Sheet1"):按 Sheet 名称选择(更直观 )。
  3. 读取数据

    • sheet.nrows:获取 Sheet 的总行数(包含表头 )。
    • range(1, sheet.nrows):从第 2 行开始遍历(下标从 0 开始,1 对应 Excel 的第 2 行 ),跳过表头。
    • sheet.row_values(i):获取第 i 行的所有单元格值,返回一个列表(如 ["admin", "123", "登录成功"] )。
  4. 数据存储
    把每行数据存入 list1,最终 list1 是二维列表,可用于 pytest.mark.parametrize 实现参数化测试。

五、与自动化测试结合(延伸)

读取 Excel 数据后,可结合 pytest 参数化,让测试用例自动遍历 Excel 数据执行:

import pytest# (上面的Excel读取代码,封装成 get_excel_data 函数)
def get_excel_data():import xlrdxls = xlrd.open_workbook("D:\Project234_web\data\msjy3.xlsx")sheet = xls.sheet_by_index(0)list1 = []for i in range(1, sheet.nrows):list1.append(sheet.row_values(i))return list1# 参数化测试用例,遍历 Excel 数据
@pytest.mark.parametrize("username, password, assert_msg", get_excel_data())
def test_login(username, password, assert_msg):# 这里写自动化测试逻辑(如:打开登录页、输入账号密码、断言结果)print(f"测试:{username} / {password},预期:{assert_msg}")# 实际执行:driver.get(...) / driver.find_element(...) 等

 

六、优缺点与替代方案

优点:
  • 数据直观:Excel 表格比 CSV 更易编辑、维护(支持合并单元格、样式 )。
  • 适合非技术人员:运营 / 产品可直接改 Excel 数据,无需动代码。
缺点:
  • 库的局限性xlrd 对新版 .xlsx 兼容性差(如 Excel 2007+ 格式 ),复杂表格可能解析异常。
  • 性能一般:大文件(万行级 )读取较慢。
替代方案:
  • 用 openpyxl 库(支持 .xlsx,功能更全 )。
  • 用 pandas 库(pd.read_excel 更简洁,适合数据分析场景 )。

简单说,这是 “Excel 数据驱动测试” 的基础实现:用 xlrd 读 Excel 数据,存成列表后,可结合 pytest 让测试用例自动遍历数据执行,提升测试效率和数据可维护性 。

四、自动化生成缺陷报告

需要使用第三方库:

  • allure
    • 测试报告生成的框架
  • 安装 allure 项目包
    • allure-2.8.1
  • 配置环境变量
    • 一定要先安装 java 的 sdk(环境)
    • jdk-17_windows-x64_bin.exe
  • 参考 java 环境安装.docx
    • java 环境配置
    • allure 环境配置
  • python 环境中安装 allure-pytest
    • pip install allure-pytest
  • 在 pytest.ini 配置文件中,添加缺陷报告的输出路径
    • addopts = -vs --alluredir report
  • 用例执行完成之后,才能生成测试报告
    • 输入命令: allure generate report/-o report/html
  • 可以查看项目下面的 report 文件夹里面的 html 文件中的 index.html

五、POM 与 KDT 设计模式对比

一、POM 设计模式(Page Object Model)

核心结构:
  • Page 类:封装页面元素定位和操作方法
  • Test 类:调用 Page 类方法实现测试逻辑
# pages/login_page.py (登录页面对象)
from selenium.webdriver.common.by import Byclass LoginPage:# 元素定位器USERNAME_INPUT = (By.ID, "username")PASSWORD_INPUT = (By.ID, "password")LOGIN_BUTTON = (By.ID, "login-button")def __init__(self, driver):self.driver = driverdef input_username(self, username):self.driver.find_element(*self.USERNAME_INPUT).send_keys(username)def input_password(self, password):self.driver.find_element(*self.PASSWORD_INPUT).send_keys(password)def click_login(self):self.driver.find_element(*self.LOGIN_BUTTON).click()def login(self, username, password):self.input_username(username)self.input_password(password)self.click_login()# tests/test_login.py (测试用例)
def test_successful_login(driver):login_page = LoginPage(driver)login_page.login("admin", "password123")# 断言登录成功后的元素存在assert "Welcome" in driver.page_source

 

二、KDT 设计模式(Keyword Driven Testing)

核心结构:
  • 关键字库:封装基础操作(如点击、输入)
  • 测试数据:用表格(Excel/CSV)存储测试步骤
  • 执行引擎:解析表格数据,调用关键字执行测试
# keywords/webdriver_keywords.py (关键字库)
from selenium.webdriver.common.by import Byclass WebDriverKeywords:def __init__(self, driver):self.driver = driverdef open_url(self, url):self.driver.get(url)def input_text(self, locator_type, locator_value, text):element = self.driver.find_element(getattr(By, locator_type.upper()), locator_value)element.send_keys(text)def click_element(self, locator_type, locator_value):element = self.driver.find_element(getattr(By, locator_type.upper()), locator_value)element.click()def assert_text(self, expected_text):assert expected_text in self.driver.page_source# engine/keyword_engine.py (执行引擎)
import pandas as pdclass KeywordEngine:def __init__(self, driver):self.driver = driverself.keywords = WebDriverKeywords(driver)def execute_test(self, test_file):# 读取Excel测试用例df = pd.read_excel(test_file)# 逐行执行测试步骤for index, row in df.iterrows():keyword = getattr(self.keywords, row["Keyword"])args = row[1:].dropna().tolist()keyword(*args)# tests/test_login_kdt.py (测试用例)
def test_successful_login_kdt(driver):engine = KeywordEngine(driver)engine.execute_test("tests/data/login_test.xlsx")
测试数据 Excel 示例(login_test.xlsx):
KeywordParameter1Parameter2Parameter3
open_urlhttp://example.com
input_textidusernameadmin
input_textidpasswordpassword123
click_elementidlogin-button
assert_textWelcome

三、对比分析

维度POMKDT
代码结构按页面组织,每个 Page 类对应一个页面按功能组织,关键字库和执行引擎分离,测试数据外部化(Excel/CSV)
变化应对页面元素变化需修改对应 Page 类修改 Excel 中的测试步骤或参数,无需改代码
用例编写测试人员编写 Python 代码非技术人员可通过 Excel 编写测试步骤
复用性页面方法可复用,但跨页面复用需组合调用关键字可自由组合,复用性更高
复杂度适合中小型项目,页面数量可控适合大型、流程复杂项目,尤其需频繁变更测试步骤的场景

四、实际应用建议

  • 选 POM 的场景

  • 页面结构稳定,元素定位变化少
  • 测试团队技术能力强,偏好维护代码而非表格
  • 需要精细控制页面交互细节

  • 选 KDT 的场景

  • 业务流程复杂且频繁变更
  • 需要产品 / 运营人员参与编写测试用例
  • 希望通过配置文件而非代码快速调整测试逻辑

  • 混合模式

    • 复杂项目可结合两种模式:核心页面用 POM 封装,业务流程用 KDT 编排
    • 例如:
      # KDT 中调用 POM
      def execute_pom_action(self, page_name, action, *args):page_class = getattr(pages, page_name)page = page_class(self.driver)action_method = getattr(page, action)action_method(*args)
      

 

五、关键差异总结

场景POM 实现KDT 实现
页面元素 ID 变更修改对应 Page 类中的定位器无需修改代码,调整 Excel 中的定位参数
新增测试用例编写新的测试函数,调用 Page 方法在 Excel 中新增测试步骤行
跨项目复用复制 Page 类到新项目导出关键字库和 Excel 模板到新项目
非技术人员参与测试需要培训 Python只需熟悉 Excel 表格填写

通过以上对比可以看出,KDT 更适合需求快速变化、需多方协作的场景,而 POM 更适合结构稳定、技术主导的项目。根据你的项目特性选择,能显著提升自动化测试的效率和可维护性。

http://www.xdnf.cn/news/16061.html

相关文章:

  • AWS Certified Cloud Practitioner 认证考试 测试题与解析
  • CSS实现背景色下移10px
  • 自动化与安全 - 将 Terraform 集成到 CI/CD
  • rancher上使用rke在华为云多网卡的服务器上安装k8s集群问题处理了
  • 使用Trae简单编写一个登陆页面
  • 智能合约安全 - 重入攻击 - 常见漏洞(第一篇)
  • AUTOSAR进阶图解==>AUTOSAR_SWS_COMManager
  • 【JS逆向基础】数据库之MongoDB
  • c#转python第四天:生态系统与常用库
  • 近期工作感想:职业规划篇
  • Web开发 04
  • 【企业架构】TOGAF概念之一
  • Android系统5层架构
  • XSS知识总结
  • kafka生产端和消费端的僵尸实例以及解决办法
  • `MYSQL`、`MYSQL_RES` 和 `MYSQL_FIELD`的含义与使用案例
  • 【硬件】GalaxyTabPro10.1(SM-T520)刷机/TWRP/LineageOS14/安卓7升级全过程
  • 浅谈 Vue 的双向数据绑定
  • Java 字符集(Charset)详解:从编码基础到实战应用,彻底掌握字符处理核心机制
  • 【数据结构】双向循环链表的实现
  • 基于机器视觉的迈克耳孙干涉环自动计数系统设计与实现
  • Node.js:函数、路由、全局对象
  • Docker Compose 配置
  • 如何5分钟快速搭建智能问答系统
  • 详解如何解决Mysql主从复制延迟
  • LINUX720 SWAP扩容;新增逻辑卷;逻辑卷扩容;数据库迁移;gdisk
  • Ajax简单介绍及Axios请求方式的别名
  • 复杂度+包装类型+泛型
  • 统计与大数据分析和数字经济:专业选择指南
  • spring-cloud使用