商品信息管理自动化测试
目录
前言
一、思维导图
二、代码编写
1.在pom.xml文件中添加相关依赖
2.自动化代码编写
三、代码测试
小结
前言
1. 针对商品信息管理项目进行测试,商品信息管理项目主要有商品列表页、部门列表页、员工列表页,主要功能:对商品信息的增删改查的功能。对于商品信息管理的测试主要就是对主要功能进行测试,按照页面以及测试用例的思维导图进行自动化脚本的编写及测试。
2.自动化测试一般步骤:
1)使用Xmind编写web自动化测试用例
2)创建自动化项目,根据测试用例实现脚本的编写及测试
一、思维导图
web自动化测试用例思维导图
二、代码编写
- 根据思维导图进行测试用例的代码编写,每个页面一个测试类,然后在各个测试类中进行测试用例的编写。
- 注意公共属性需要单独放一个类,方便进行代码复用。
- 创建启动以及截图会频繁进行复用,所以创建方法进行封装。
- 注意添加隐式等待,为了确保页面正确加载显示
1.在pom.xml文件中添加相关依赖
<!--引入驱动管理依赖-->
<dependency><groupId>io.github.bonigarcia</groupId><artifactId>webdrivermanager</artifactId><version>5.8.0</version><scope>test</scope></dependency>
<!--引入selenium依赖-->
<dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>4.0.0</version>
</dependency>
<!--引入屏幕截图依赖-->
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version>
</dependency>
2.自动化代码编写
代码只展示主要部分
1.创建驱动对象和截屏会频繁使用,将其封装成方法
// 创建驱动对象
void createDriver() {if (driver == null) {// 1. 使用驱动管理程序打开谷歌浏览器驱动;WebDriverManager.chromedriver().setup();// 添加浏览器配置-创建的驱动对象允许浏览器访问所有链接ChromeOptions options = new ChromeOptions();options.addArguments("--remote-allow-origins=*");driver = new ChromeDriver(options);}
}/*** 截屏并保存到指定目录下* 文件名格式:./src/test/images/2025-01-29/FirstTest_130725.png*/
private void getScreenshot(String str) throws IOException {SimpleDateFormat sim1 = new SimpleDateFormat("yyyy-MM-dd");// 日期 2025-01-29SimpleDateFormat sim2 = new SimpleDateFormat("HHmmssSS");// 时间戳 13时07分25秒25毫秒String dirTime = sim1.format(System.currentTimeMillis());// 日期目录 2025-01-29String fileTime = sim2.format(System.currentTimeMillis());// 时间戳 13时07分25秒25毫秒
// ./src/test/images/2025-01-29/FirstTest_130725.pngString fileName = "./src/test/images/"+dirTime + "/"+str + "_" +fileTime + ".png";// 文件名System.out.println("截图文件名(fileName):" + fileName);// 拍截屏文件并保存到指定目录下File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);FileUtils.copyFile(srcFile, new File(fileName));
}
2. 测试商品搜索功能
- 测试页面能否正常打开
- 测试能否依据名字查询商品信息
- 测试能否依据品牌查询商品信息
/*** 测试 商品根据名字进行搜索的功能* @throws IOException*/
void retrieveProduct() throws IOException, InterruptedException {createDriver();driver.get("http://localhost:90/#/product");// 获取商品页面中的输入框元素WebElement element = driver.findElement(By.cssSelector("body > div > section > section > main > form > div:nth-child(1) > div > div > input"));// 输入框输入内容 床上桌element.sendKeys("床上桌");// 点击搜索按钮driver.findElement(By.cssSelector("body > div > section > section > main > form > div:nth-child(2) > div > button")).click();Thread.sleep(1000);// 截屏并保存到指定目录下getScreenshot("ProductPageTest");//显示商品的详细信息,点击确定按钮driver.findElement(By.cssSelector("body > div:nth-child(2) > section > section > main > div:nth-child(2) > div > div.el-dialog__footer > div > button.el-button.el-button--primary")).click();// 删除输入框中的内容 床上桌element.clear();driver.quit();
}
3.测试新增商品功能
- 测试新增商品按钮功能能否正常使用
- 测试填写新增商品的所有信息能否新增成功
- 测试填写部分新增商品的信息能否新增成功
- 测试不填写新增商品信息能否新增成功
/*** 测试 新增商品* @throws IOException* @throws InterruptedException*/
void createProduct() throws IOException, InterruptedException {createDriver();driver.get("http://localhost:90/#/product");// 点击新增按钮driver.findElement(By.cssSelector("body > div > section > section > main > div.el-row > button")).click();// 获取 名字输入框元素WebElement nameInput = driver.findElement(By.cssSelector("body > div:nth-child(2) > section > section > main > div:nth-child(4) > div > div.el-dialog__body > form > div:nth-child(1) > div > div > input"));// 输入内容 插头nameInput.clear();nameInput.sendKeys("插头");// 获取 价格输入框元素WebElement priceInput = driver.findElement(By.cssSelector("body > div:nth-child(2) > section > section > main > div:nth-child(4) > div > div.el-dialog__body > form > div:nth-child(2) > div > div > input"));// 输入内容 100priceInput.clear();priceInput.sendKeys("100");// 获取 品牌输入框元素WebElement descInput = driver.findElement(By.cssSelector("body > div:nth-child(2) > section > section > main > div:nth-child(4) > div > div.el-dialog__body > form > div:nth-child(3) > div > div > input"));// 输入内容descInput.clear();descInput.sendKeys("公牛");// 获取库存输入框元素WebElement stockInput = driver.findElement(By.cssSelector("body > div:nth-child(2) > section > section > main > div:nth-child(4) > div > div.el-dialog__body > form > div:nth-child(4) > div > div > input"));// 输入内容 100stockInput.clear();stockInput.sendKeys("100");// 点击确定按钮driver.findElement(By.cssSelector("body > div:nth-child(2) > section > section > main > div:nth-child(4) > div > div.el-dialog__footer > div > button.el-button.el-button--primary")).click();// 显示等待1秒,直到确定按钮被点击,然后刷新页面WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(1));wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("body > div:nth-child(2) > section > section > main > div:nth-child(4) > div > div.el-dialog__footer > div > button.el-button.el-button--primary")));// 刷新页面driver.navigate().refresh();
// Thread.sleep(1000);// 截屏并保存到指定目录下getScreenshot("ProductPageTest");// 断言新增的商品是否存在
// WebElement product = driver.findElement(By.xpath("//td[contains(text(),'插头')]"));
// assert product != null;driver.quit();
}
4.测试修改商品信息功能
- 测试编辑按钮功能能否正常使用
- 测试修改商品的所有信息能否修改成功
- 测试修改商品的部分信息能否修改成功
/*** 测试 修改商品的价格* @throws IOException* @throws InterruptedException*/
void updateProduct() throws IOException, InterruptedException {createDriver();driver.get("http://localhost:90/#/product");
// Thread.sleep(1000);
// 隐式等待1秒driver.manage().timeouts().implicitlyWait(Duration.ofMillis(1000));// 点击编辑按钮driver.findElement(By.xpath("/html/body/div/section/section/main/div[4]/div[3]/table/tbody/tr[1]/td[5]/div/button[1]")).click();// 获取 价格输入框元素WebElement priceInput = driver.findElement(By.cssSelector("body > div:nth-child(2) > section > section > main > div:nth-child(7) > div > div.el-dialog__body > form > div:nth-child(2) > div > div > input"));// 修改价格为 20priceInput.clear();priceInput.sendKeys("20");// 点击确定按钮driver.findElement(By.cssSelector("body > div:nth-child(2) > section > section > main > div:nth-child(7) > div > div.el-dialog__footer > div > button.el-button.el-button--primary")).click();// 显示等待1秒,直到确定按钮被点击,然后刷新页面WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(1));wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("body > div:nth-child(2) > section > section > main > div:nth-child(7) > div > div.el-dialog__footer > div > button.el-button.el-button--primary")));// 刷新页面driver.navigate().refresh();// 截屏并保存到指定目录下getScreenshot("ProductPageTest");// 断言修改后的价格是否正确
// WebElement product = driver.findElement(By.xpath("//td[contains(text(),'20')]"));
// assert product != null;driver.quit();
}
5.测试删除商品功能
- 测试删除按钮是否能够正常使用
- 测试点击删除按钮再确认删除能否删除成功
- 测试点击删除按钮再取消删除能否取消删除成功
- 测试删除成功后刷新页面是否能够显示非删除数据
/*** 测试 删除商品* @throws IOException* @throws InterruptedException*/
void deleteProduct() throws IOException, InterruptedException {createDriver();driver.get("http://localhost:90/#/product");// 点击删除按钮driver.findElement(By.xpath("/html/body/div/section/section/main/div[4]/div[3]/table/tbody/tr[1]/td[5]/div/button[2]")).click();// 点击确定按钮
// driver.findElement(By.cssSelector("body > div:nth-child(2) > section > section > main > div:nth-child(6) > div > div.el-dialog__footer > div > button.el-button--primary")).click();// 显示等待1秒,直到确定按钮被点击,然后刷新页面WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(1));wait.until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div/section/section/main/div[4]/div[3]/table/tbody/tr[1]/td[5]/div/button[2]")));// 刷新页面driver.navigate().refresh();// 截屏并保存到指定目录下getScreenshot("ProductPageTest");// 断言删除后的商品是否不存在
// WebElement product = driver.findElement(By.xpath("//td[contains(text(),'头')]"));
// assert product == null;driver.quit();
}
三、代码测试
所有测试用例通过,但发现测试耗时有些长,说明性能还有优化的空间。
小结
- 一定要关注测试用例的执行顺序问题
- 对于页面的检查一定要到位,如检查元素是否存在确保页面的正确性
- 驱动关闭的位置要注意,只有最后一个用例结束之后才进行关闭
- 为了把所有的用例的执行结果保存下来,方便后续查错或查看,此时就需要进行该方法的定义即封装一个屏幕截图的方法
- 注意屏幕截图保存的方式:动态时间戳并进行时间格式化,然后期望按照某种维度(天、周)以文件夹的方式进行保存
- 在定位元素时,当复制的cssSelector的值比较长时建议复制xpath,因为cssSelector的值比较长就可能会导致定位元素失败
- 可以适当关注用例执行时间,如果时间过长就需要考虑是我们自己写的测试用例的问题还是程序真的有性能问题
相关文章:

商品信息管理自动化测试
目录 前言 一、思维导图 二、代码编写 1.在pom.xml文件中添加相关依赖 2.自动化代码编写 三、代码测试 小结 前言 1. 针对商品信息管理项目进行测试,商品信息管理项目主要有商品列表页、部门列表页、员工列表页,主要功能:对商品信息的…...

Redis实战(黑马点评)——redis存储地理信息、位图、HyperLogLog 用法
Redis存储geo数据类型基本介绍 geo 就是 geolocation 的简写形式,代表地理坐标。redis 在 3.2 版本中加入了对 geo 的支持,允许存储地理坐标信息,帮助我们根据经纬度来检索数据。常见的命令有: geoadd:添加一个地理空…...
判断1到100之间有多少个素数,并输出所有的素数。
def is_prime(num): #判断一个数是否素数if num<1:return False #因为1和负数都不是素数for i in range(2,int(num**0.5)1): #从2开始到根号num的整数结束,因为一个数num不是素数,那么把必定有一个小于或等于根号num的因素if num%i0:return False #如…...

JAVA:利用 Content Negotiation 实现多样式响应格式的技术指南
1、简述 Content Negotiation(内容协商) 是 RESTful 服务的重要特性,允许客户端和服务器根据请求的不同特性动态选择适合的响应格式。它是一种在 HTTP 协议中实现的机制,通过它,服务器能够根据客户端需求返回适合的内…...
layui Table单元格编辑支持Enter键换行,包括下拉框单元格
layui Table表格编辑支持Enter键换行 可编辑单元格 $(".layui-table td").keydown(function (e) {// console.log("111",e);var index $(this).index(),tr $(this).parent(tr),isKeydown (event.type "keydown");if (e.code "Enter&q…...
Swoole的MySQL连接池实现
在Swoole中实现MySQL连接池可以提高数据库连接的复用率,减少频繁创建和销毁连接所带来的开销。以下是一个简单的Swoole MySQL连接池的实现示例: 首先,确保你已经安装了Swoole扩展和PDO_MySQL扩展(或mysqli,但在这个示…...

无人机红外热成像:应急消防的“透视眼”
无人机红外热成像:应急消防的“透视眼” 亲爱的小伙伴们,每年一到夏天,应急消防的战士们就像上紧了发条的闹钟,时刻准备应对各种灾害。炎热天气让火灾隐患“蹭蹭”往上涨,南北各地还有防洪救灾、台风、泥石流等灾害轮…...
【redis】Redis操作String类型key的发生了什么?
关于Redis操作(添加、删除、修改、查询)String类型key的完整过程,包括引用源码数据、时序图、磁盘IO读写、数据长度限制和故障处理机制。 数据结构 Redis对象(robj) typedef struct redisObject {unsigned type:4; …...

hdfs之读写流程
写入流程: 客户端Client想将文件a.txt上传至hdfs,首先向Namenode发送请求进行权限校验,Namenode通过后会计算出来三个节点,并将这三个节点告知客户端,客户端将输入进行切割成块,一个一个的块进行传输&…...

研发的立足之本到底是啥?
0 你的问题,我知道! 本文深入T型图“竖线”的立足之本:专业技术 技术赋能业务能力。研发在学习投入精力最多,也误区最多。 某粉丝感发展遇到瓶颈,项目都会做,但觉无提升,想跳槽。于是&#x…...

Baklib揭示内容中台与人工智能技术的创新协同效应
内容概要 在当今信息爆炸的时代,内容的高效生产与分发已成为各行业竞争的关键。内容中台与人工智能技术的结合,为企业提供了一种新颖的解决方案,使得内容创造的流程更加智能化和高效化。 内容中台作为信息流动的核心,能够集中管…...

智慧消防营区一体化安全管控 2024 年度深度剖析与展望
在 2024 年,智慧消防营区一体化安全管控领域取得了令人瞩目的进展,成为保障营区安全稳定运行的关键力量。这一年,行业在政策驱动、技术创新应用、实践成果及合作交流等方面呈现出多元且深刻的发展态势,同时也面临着一系列亟待解决…...
自定义数据集,使用 PyTorch 框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测
在本文中,我们将展示如何使用 NumPy 创建自定义数据集,利用 PyTorch 实现一个简单的逻辑回归模型,并在训练完成后保存该模型,最后加载模型并用它进行预测。 1. 创建自定义数据集 首先,我们使用 NumPy 创建一个简单的…...
UE5 特效
能帮到你的话,就给个赞吧 😘 文章目录 post processexposurebloomvignettesaturationunbound material材质蓝图alt z base colorconstant3Vector roughnessconstant metallicconstant pbrroughnessmetallicmake more realmake some areas rougher than o…...
CMAKE工程编译好后自动把可执行文件传输到远程开发板
# 设置 CMake 最低版本要求 cmake_minimum_required(VERSION 3.10)# 设置项目名称 project(MyProject)# 添加可执行文件,这里以项目名作为可执行文件的名称 add_executable(${PROJECT_NAME} main.cpp)# 设置开发板信息 set(DEVELOPMENT_BOARD_IP "192.168.1.10…...

Windows 程序设计7:文件的创建、打开与关闭
文章目录 前言一、文件的创建与打开CreateFile1. 创建新的空白文件2. 打开已存在文件3. 打开一个文件时,如果文件存在则打开,如果文件不存在则新创建文件4.打开一个文件,如果文件存在则打开文件并清空内容,文件不存在则 新创建文件…...
策略模式 - 策略模式的使用
引言 在软件开发中,设计模式是解决常见问题的经典解决方案。策略模式(Strategy Pattern)是行为型设计模式之一,它允许在运行时选择算法的行为。通过将算法封装在独立的类中,策略模式使得算法可以独立于使用它的客户端…...

具身智能研究报告
参考: (1)GTC大会&Figure:“具身智能”奇点已至 (2)2024中国具身智能创投报告 (3)2024年具身智能产业发展研究报告 (4)具身智能行业深度:发展…...

Windows安装Milvus
安装Milvus 安装Docker前置条件: 安装Mlivus方案一方案二 Attu管理端 安装Docker 系统:Windows 11 家庭中文版 Mlivus:V2.3.0 Attu: V2.3.10 前置条件: 启用“适用于 Linux 的 Windows 子系统”可选功能,才能在 Win…...

Excel分区间统计分析(等步长、不等步长、多维度)
在数据分析过程中,可能会需要统计不同数据区间的人数、某个数据区间的平均值或者进行分组区间统计,本文从excel函数到数据透视表的方法,从简单需求到复杂需求,采用不同的方法进行讲解,尤其是通过数据透视表的强大功能大…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...

UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...