当前位置: 首页 > 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;尤其是通过数据透视表的强大功能大…...

宝塔mysql数据库容量限制_宝塔数据库mysql-bin.000001占用磁盘空间过大

磁盘空间占用过多&#xff0c;排查后发现网站/www/wwwroot只占用7G&#xff0c;/www/server占用却高达8G&#xff0c;再深入排查发现/www/server/data目录下的mysql-bin.000001和mysql-bin.000002两个日志文件占去了1.5G空间。 百度后学到以下知识&#xff0c;做个记录。 mysql…...

LeetCode 2412.完成所有交易的初始最少钱数:【年度巨献】举例说明(讲明白),由难至简(手脚不乱),附Python一行版

【LetMeFly】2412.完成所有交易的初始最少钱数&#xff1a;【年度巨献】举例说明(讲明白)&#xff0c;由难至简(手脚不乱)&#xff0c;附Python一行版 文章目录 【LetMeFly】2412.完成所有交易的初始最少钱数&#xff1a;【年度巨献】举例说明(讲明白)&#xff0c;由难至简(手脚…...

多人-多agent协同可能会挑战维纳的反馈

在多人-多Agent协同系统中&#xff0c;维纳的经典反馈机制将面临新的挑战&#xff0c;而协同过程中的“算计”&#xff08;策略性决策与协调&#xff09;成为实现高效协作的核心。 1、非线性与动态性 维纳的反馈理论&#xff08;尤其是在控制理论中&#xff09;通常假设系统的动…...

Go学习:类型转换需注意的点 以及 类型别名

目录 1. 类型转换 2. 类型别名 1. 类型转换 在从前的学习中&#xff0c;知道布尔bool类型变量只有两种值true或false&#xff0c;C/C、Python、JAVA等编程语言中&#xff0c;如果将布尔类型bool变量转换为整型int变量&#xff0c;通常采用 “0为假&#xff0c;非0为真”的方…...

C语言中的局部变量和全局变量有什么区别?

在C语言中&#xff0c;局部变量和全局变量是两种具有不同作用域和存储期的变量。以下是它们之间的主要区别&#xff1a; 作用域 局部变量&#xff1a; 局部变量是在函数内部声明的变量。它们的作用域仅限于声明它们的函数内部。一旦函数执行完毕&#xff0c;局部变量就会超出…...

价值交换到底在交换什么

有人十多岁就很清醒&#xff0c;知道自己想要什么&#xff0c;要付出什么。有人20多岁清醒了&#xff0c;有人30多岁都不一定明白。 价值交换&#xff0c;四个字其实就可以解释大部分事情。价值交换和努力工作&#xff0c;勤劳没有任何关系。甚至努力和成功都不存在关系。 价值…...

C++传送锚点的内存寻址:内存管理

文章目录 1.C/C内存分布回顾2.C内存管理2.1 内存申请2.2 operator new与operator delete函数2.3 定位new表达式 3.关于内存管理的常见知识点3.1 malloc/free和new/delete的区别3.2 内存泄漏 希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力&#xff01; 继C语…...

Prompt提示词完整案例:让chatGPT成为“书单推荐”的高手

大家好&#xff0c;我是老六哥&#xff0c;我正在共享使用AI提高工作效率的技巧。欢迎关注我&#xff0c;共同提高使用AI的技能&#xff0c;让AI成功你的个人助理。 许多人可能会跟老六哥一样&#xff0c;有过这样的体验&#xff1a;当我们遇到一个能力出众或对事物有独到见解的…...

基于django的智能停车场车辆管理深度学习车牌识别系统

完整源码项目包获取→点击文章末尾名片&#xff01;...

【Proteus仿真】【51单片机】简易计算器系统设计

目录 一、主要功能 二、使用步骤 三、硬件资源 四、软件设计 五、实验现象 联系作者 一、主要功能 1、LCD1602液晶显示 2、矩阵按键​ 3、可以进行简单的加减乘除运算 4、最大 9999*9999 二、使用步骤 系统运行后&#xff0c;LCD1602显示数据&#xff0c;通过矩阵按键…...