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

商品信息管理自动化测试

目录

前言

一、思维导图

二、代码编写

1.在pom.xml文件中添加相关依赖

         2.自动化代码编写

三、代码测试

小结


前言

1. 针对商品信息管理项目进行测试,商品信息管理项目主要有商品列表页、部门列表页、员工列表页,主要功能:对商品信息的增删改查的功能。对于商品信息管理的测试主要就是对主要功能进行测试,按照页面以及测试用例的思维导图进行自动化脚本的编写及测试。

2.自动化测试一般步骤:

1)使用Xmind编写web自动化测试用例

2)创建自动化项目,根据测试用例实现脚本的编写及测试

一、思维导图

web自动化测试用例思维导图

二、代码编写

  1. 根据思维导图进行测试用例的代码编写,每个页面一个测试类,然后在各个测试类中进行测试用例的编写。
  2. 注意公共属性需要单独放一个类,方便进行代码复用。
  3. 创建启动以及截图会频繁进行复用,所以创建方法进行封装。
  4. 注意添加隐式等待,为了确保页面正确加载显示

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();
}

三、代码测试

所有测试用例通过,但发现测试耗时有些长,说明性能还有优化的空间。

小结

  1. 一定要关注测试用例的执行顺序问题
  2. 对于页面的检查一定要到位,如检查元素是否存在确保页面的正确性
  3. 驱动关闭的位置要注意,只有最后一个用例结束之后才进行关闭
  4. 为了把所有的用例的执行结果保存下来,方便后续查错或查看,此时就需要进行该方法的定义即封装一个屏幕截图的方法
  5. 注意屏幕截图保存的方式:动态时间戳并进行时间格式化,然后期望按照某种维度(天、周)以文件夹的方式进行保存
  6. 在定位元素时,当复制的cssSelector的值比较长时建议复制xpath,因为cssSelector的值比较长就可能会导致定位元素失败
  7. 可以适当关注用例执行时间,如果时间过长就需要考虑是我们自己写的测试用例的问题还是程序真的有性能问题

相关文章:

商品信息管理自动化测试

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

Redis实战(黑马点评)——redis存储地理信息、位图、HyperLogLog 用法

Redis存储geo数据类型基本介绍 geo 就是 geolocation 的简写形式&#xff0c;代表地理坐标。redis 在 3.2 版本中加入了对 geo 的支持&#xff0c;允许存储地理坐标信息&#xff0c;帮助我们根据经纬度来检索数据。常见的命令有&#xff1a; geoadd&#xff1a;添加一个地理空…...

判断1到100之间有多少个素数,并输出所有的素数。

def is_prime(num): #判断一个数是否素数if num<1:return False #因为1和负数都不是素数for i in range(2,int(num**0.5)1): #从2开始到根号num的整数结束&#xff0c;因为一个数num不是素数&#xff0c;那么把必定有一个小于或等于根号num的因素if num%i0:return False #如…...

JAVA:利用 Content Negotiation 实现多样式响应格式的技术指南

1、简述 Content Negotiation&#xff08;内容协商&#xff09; 是 RESTful 服务的重要特性&#xff0c;允许客户端和服务器根据请求的不同特性动态选择适合的响应格式。它是一种在 HTTP 协议中实现的机制&#xff0c;通过它&#xff0c;服务器能够根据客户端需求返回适合的内…...

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连接池可以提高数据库连接的复用率&#xff0c;减少频繁创建和销毁连接所带来的开销。以下是一个简单的Swoole MySQL连接池的实现示例&#xff1a; 首先&#xff0c;确保你已经安装了Swoole扩展和PDO_MySQL扩展&#xff08;或mysqli&#xff0c;但在这个示…...

无人机红外热成像:应急消防的“透视眼”

无人机红外热成像&#xff1a;应急消防的“透视眼” 亲爱的小伙伴们&#xff0c;每年一到夏天&#xff0c;应急消防的战士们就像上紧了发条的闹钟&#xff0c;时刻准备应对各种灾害。炎热天气让火灾隐患“蹭蹭”往上涨&#xff0c;南北各地还有防洪救灾、台风、泥石流等灾害轮…...

【redis】Redis操作String类型key的发生了什么?

关于Redis操作&#xff08;添加、删除、修改、查询&#xff09;String类型key的完整过程&#xff0c;包括引用源码数据、时序图、磁盘IO读写、数据长度限制和故障处理机制。 数据结构 Redis对象&#xff08;robj&#xff09; typedef struct redisObject {unsigned type:4; …...

hdfs之读写流程

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

研发的立足之本到底是啥?

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

Baklib揭示内容中台与人工智能技术的创新协同效应

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

智慧消防营区一体化安全管控 2024 年度深度剖析与展望

在 2024 年&#xff0c;智慧消防营区一体化安全管控领域取得了令人瞩目的进展&#xff0c;成为保障营区安全稳定运行的关键力量。这一年&#xff0c;行业在政策驱动、技术创新应用、实践成果及合作交流等方面呈现出多元且深刻的发展态势&#xff0c;同时也面临着一系列亟待解决…...

自定义数据集,使用 PyTorch 框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测

在本文中&#xff0c;我们将展示如何使用 NumPy 创建自定义数据集&#xff0c;利用 PyTorch 实现一个简单的逻辑回归模型&#xff0c;并在训练完成后保存该模型&#xff0c;最后加载模型并用它进行预测。 1. 创建自定义数据集 首先&#xff0c;我们使用 NumPy 创建一个简单的…...

UE5 特效

能帮到你的话&#xff0c;就给个赞吧 &#x1f618; 文章目录 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)# 添加可执行文件&#xff0c;这里以项目名作为可执行文件的名称 add_executable(${PROJECT_NAME} main.cpp)# 设置开发板信息 set(DEVELOPMENT_BOARD_IP "192.168.1.10…...

Windows 程序设计7:文件的创建、打开与关闭

文章目录 前言一、文件的创建与打开CreateFile1. 创建新的空白文件2. 打开已存在文件3. 打开一个文件时&#xff0c;如果文件存在则打开&#xff0c;如果文件不存在则新创建文件4.打开一个文件&#xff0c;如果文件存在则打开文件并清空内容&#xff0c;文件不存在则 新创建文件…...

策略模式 - 策略模式的使用

引言 在软件开发中&#xff0c;设计模式是解决常见问题的经典解决方案。策略模式&#xff08;Strategy Pattern&#xff09;是行为型设计模式之一&#xff0c;它允许在运行时选择算法的行为。通过将算法封装在独立的类中&#xff0c;策略模式使得算法可以独立于使用它的客户端…...

具身智能研究报告

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

Windows安装Milvus

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

Excel分区间统计分析(等步长、不等步长、多维度)

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

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...

Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?

Pod IP 的本质与特性 Pod IP 的定位 纯端点地址&#xff1a;Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址&#xff08;如 10.244.1.2&#xff09;无特殊名称&#xff1a;在 Kubernetes 中&#xff0c;它通常被称为 “Pod IP” 或 “容器 IP”生命周期&#xff1a;与 Pod …...

【C++】纯虚函数类外可以写实现吗?

1. 答案 先说答案&#xff0c;可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...