对博客系统基本功能进行自动化测试(Junit + Selenium)
环境搭建:
- 浏览器:
- 本次测试使用Chrome浏览器
- 在jdk的bin目录下安装对应浏览器驱动(尽量选择与浏览器版本相近的驱动)chromedriver.storage.googleapis.com/index.html
- Junit依赖:
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api --><dependency><groupId>org.junit.jupiter</groupId><!--编写用例的基本注解--><artifactId>junit-jupiter-api</artifactId><version>5.9.1</version></dependency><dependency><!--参数化测试依赖--><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-params</artifactId><version>5.9.1</version></dependency><dependency><!--这个库提供JUnit平台的核心功能,比如共享的测试接口、注解和工具类--><groupId>org.junit.platform</groupId><artifactId>junit-platform-commons</artifactId><version>1.9.1</version> <!-- 请根据需要调整为与JUnit 5.9.1兼容的版本 --></dependency><!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-suite --><dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-suite</artifactId><version>1.9.1</version><scope>test</scope></dependency><dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-suite-api</artifactId><version>1.9.1</version></dependency><!--JUnit Jupiter的测试引擎,实现了JUnit Platform的TestEngine接口。它负责发现和执行使用JUnit Jupiter API编写的测试。--><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-engine</artifactId><version>5.9.1</version><scope>test</scope></dependency>
- Selenium依赖
<dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>3.141.59</version></dependency><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-support</artifactId><version>3.141.59</version></dependency>
测试用例:
网站:登陆页面
项目结构:
InitAndQuit进行测试初始化和收尾工作
TestItem包含对各个页面基本功能的自动化测试用例
初始化以及资源关闭:
/*** @ClassName InitAndQuit* @Description 初识化测试相关以及测试结束资源关闭* @Author 86153* @Date 2024/4/30 10:20* @Version 1.0**/
public class InitAndQuit {static WebDriver webDriver;@BeforeAllstatic void init() {webDriver = new ChromeDriver();}@AfterAllstatic void quit() {webDriver.quit();}
}
登录页面测试用例:
- 输入给定邮箱点击获取验证码:
//验证码private static String emailCode;//在注册页面点击获取验证码按钮@ParameterizedTest@CsvFileSource(resources = "login.csv")@Order(0)void loginTest(String account) throws InterruptedException {webDriver.get("http://8.130.70.131:8080/login.html");webDriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);webDriver.findElement(By.cssSelector("#username")).sendKeys(account);WebDriverWait wait = new WebDriverWait(webDriver,10);//这里 获取验证码 和 提交按钮为俩个一样的button,所以需要进行按钮的选择WebElement clickElement = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#submit")));List<WebElement> elements = webDriver.findElements(By.cssSelector("#submit"));elements.get(0).click();}
- 从邮箱中拿到验证码
/*邮箱登录拿到验证码*/@Test@Order(1)void getCaptcha() throws InterruptedException {webDriver.get("https://www.baidu.com/");webDriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);webDriver.findElement(By.cssSelector(".s_ipt")).sendKeys("https://mail.qq.com/");webDriver.findElement(By.cssSelector("#su")).click();webDriver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);//保存当前窗口的句柄String originalWindow = webDriver.getWindowHandle();webDriver.findElement(By.cssSelector("#\\31 > div > div:nth-child(1) > h3 > a")).click();//切换窗口Set<String> set = webDriver.getWindowHandles();for(String cur : set) {if(!cur.equals(originalWindow)) {webDriver.switchTo().window(cur);}}//登录邮箱//注意这里切换frame时要先去选择获取到frameWebElement iframe = webDriver.findElement(By.cssSelector("#QQMailSdkTool_login_loginBox_qq > iframe"));webDriver.switchTo().frame(iframe);WebElement iframe1 = webDriver.findElement(By.cssSelector("#ptlogin_iframe"));webDriver.switchTo().frame(iframe1);//点击用户头像进行登录(电脑登陆了QQ)webDriver.findElement(By.cssSelector("#img_out_3224881242")).click();sleep(10000);//进入对应邮件webDriver.findElement(By.cssSelector("#mailMainApp > div.frame_main.mail_app > div > div > div > div.mailList_listWrapper > div.mailList_group > div:nth-child(1) > div.mailList_group_item_cnt > table > tbody > tr:nth-child(1)")).click();//拿到验证码WebElement element = webDriver.findElement(By.cssSelector("#readmail_content_html > span"));String text = element.getText();emailCode = text;}
- 登录
//登陆页面测试@ParameterizedTest@CsvFileSource(resources = "login.csv")@Order(2)void loginTest(String account,String password) throws InterruptedException {//进入登陆页面webDriver.get("http://8.130.70.131:8080/login.html");//隐式等待webDriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);//输入账号密码验证码webDriver.findElement(By.cssSelector("#username")).sendKeys(account);webDriver.findElement(By.cssSelector("#password")).sendKeys(password);webDriver.findElement(By.cssSelector("#captcha")).sendKeys(emailCode);//显示等待WebDriverWait wait = new WebDriverWait(webDriver,10);//这里 获取验证码 和 提交按钮为俩个一样的button,所以需要进行按钮的选择WebElement clickElement = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#submit")));List<WebElement> elements = webDriver.findElements(By.cssSelector("#submit"));elements.get(1).click();//显示等待,等待弹窗出现//注意这里是个坑,弹窗不属于页面内的元素,不能使用隐式等待wait.until(ExpectedConditions.alertIsPresent());//弹窗选择webDriver.switchTo().alert().accept();//等待进入新页面webDriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);//校验urlString currentURL = webDriver.getCurrentUrl();Assertions.assertEquals("http://8.130.70.131:8080/myblog_list.html",currentURL);}
列表页测试用例:
//列表页自动化测试/*** 如果列表页博客数量不为0表示测试通过**/@Test@Order(3)void listTest() {webDriver.get("hhttp://8.130.70.131:8080/blog_list.html");webDriver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);int size = webDriver.findElements(By.cssSelector(".title")).size();System.out.println(size);Assertions.assertNotEquals(0,size);}
个人列表页测试用例:
//个人列表页测试@Test@Order(4)void selfListTest() {webDriver.get("http://8.130.70.131:8080/myblog_list.html");//文章数量不为0测试List<WebElement> list = webDriver.findElements(By.cssSelector(".title"));int size = webDriver.findElements(By.cssSelector(".title")).size();System.out.println(size);Assertions.assertNotEquals(0,list.size());//测试“主页”按钮webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)")).click();webDriver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);String curUrl = webDriver.getCurrentUrl();Assertions.assertEquals("http://8.130.70.131:8080/blog_list.html",curUrl);//回退到个人主页webDriver.navigate().back();//测试“写博客按钮”webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();webDriver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);curUrl = webDriver.getCurrentUrl();Assertions.assertEquals("http://8.130.70.131:8080/blog_add.html",curUrl);webDriver.navigate().back();/* //测试“注销”按钮webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();webDriver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);curUrl = webDriver.getCurrentUrl();Assertions.assertEquals("http://8.130.70.131:8080/login.html",curUrl);*/}
博客详情页测试用例:
//博客详情页测试@ParameterizedTest@Order(5)@CsvFileSource(resources = "detail.csv")void detailTest(String destUrl,String destPageTitle,String destBlogTitle) {//进入列表页webDriver.get("http://8.130.70.131:8080/blog_list.html");//点击文章详情按钮,进入博客详情页webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > a")).click();//校验页面url,页面title,博客题目webDriver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);String url = webDriver.getCurrentUrl();String pageTitle = webDriver.getTitle();String blogTitle = webDriver.findElement(By.cssSelector("#title")).getText();Assertions.assertEquals(destUrl,url);Assertions.assertEquals(destPageTitle,pageTitle);Assertions.assertEquals(destBlogTitle,blogTitle);}
编辑页测试用例:
//博客编辑页测试@ParameterizedTest@Order(6)@CsvFileSource(resources = "edit.csv")void editTest(String data,String title) {webDriver.get("http://8.130.70.131:8080/blog_add.html");webDriver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);/* //直接使用通过js设置文章标题((JavascriptExecutor)webDriver).executeScript("document.getElementById(\"title\").value=\"自动化测试\"");*/webDriver.findElement(By.cssSelector("#title")).sendKeys("自动化测试");//发布文章webDriver.findElement(By.cssSelector("body > div.blog-edit-container > div.title > button")).click();//这里有一个”是否继续添加博客“的弹窗,进行选择后才跳转WebDriverWait wait = new WebDriverWait(webDriver,5);wait.until(ExpectedConditions.alertIsPresent());webDriver.switchTo().alert().dismiss();webDriver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);//校验url跳转String cur_url = webDriver.getCurrentUrl();Assertions.assertEquals("http://8.130.70.131:8080/myblog_list.html",cur_url);//校验第一篇博客的发布时间,标题String publishDate = webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > div.date")).getText();String publishTitle = webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > div.title")).getText();Assertions.assertEquals(title,publishTitle);if(publishDate.contains(data)) {System.out.println("测试通过");}else {System.out.println("发布时间错误");}//删除博客webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > a:nth-child(6)")).click();webDriver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);//弹窗选择wait.until(ExpectedConditions.alertIsPresent());webDriver.switchTo().alert().accept();//校验第一篇博客是否被删除WebElement after_delete_title = webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > div.title"));Assertions.assertNotEquals(title,after_delete_title);}
注销:
//注销@Test@Order(7)void login_out() {webDriver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);//点击注销按钮webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();//显示等待alter弹窗出现WebDriverWait wait = new WebDriverWait(webDriver,5);wait.until(ExpectedConditions.alertIsPresent());//选择弹框并进行确定webDriver.switchTo().alert().accept();webDriver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);String cur_url = webDriver.getCurrentUrl();Assertions.assertEquals("http://8.130.70.131:8080/login.html",cur_url);}
相关文章:

对博客系统基本功能进行自动化测试(Junit + Selenium)
环境搭建: 浏览器: 本次测试使用Chrome浏览器在jdk的bin目录下安装对应浏览器驱动(尽量选择与浏览器版本相近的驱动)chromedriver.storage.googleapis.com/index.htmlJunit依赖: <!-- https://mvnreposit…...

《换你来当爹》:AI驱动的养成游戏,探索虚拟亲子关系的新模式
AI技术如何重塑我们对游戏互动的认知 在人工智能技术的浪潮下,一款名为《换你来当爹》的AI养成游戏,以其创新的互动模式和个性化体验,吸引了游戏爱好者的目光。这款游戏利用了先进的LLM技术,通过AI实时生成剧情和图片,…...

在idea中使用vue
一、安装node.js 1、在node.js官网(下载 | Node.js 中文网)上下载适合自己电脑版本的node.js压缩包 2、下载完成后进行解压并安装,一定要记住自己的安装路径 一直点击next即可,这部选第一个 3、安装成功后,按住winR输入…...

Linux系统编程:进程控制
1.进程创建 1.1 fork函数 fork()通过复制调用进程来创建一个新进程。新进程称为子进程,是调用进程的精确副本 进程,但以下几点除外: 子进程有自己的PID,此PID与任何现有进程组的ID不匹配子进程的父进程ID…...

Android 异常开机半屏重启代码分析
Android 的稳定性是 Android 性能的一个重要指标,它也是 App 质量构建体系中最基本和最关键的一环;如果应用经常崩溃,或者关键功能不可用,那显然会对我们的留存产生重大影响所以为了保障应用的稳定性,我们首先应该树立…...

Kafka从0到消费者开发
安装ZK Index of /zookeeper/zookeeper-3.9.2 下载安装包 一定要下载-bin的,不带bin的是源码,没有编译的,无法执行。-bin的才可以执行。 解压 tar -zxvf apache-zookeeper-3.9.2-bin.tar.gz 备份配置 cp zoo_sample.cfg zoo_sample.cfg-b…...

01-项目功能,架构设计介绍
稻草快速开发平台 开发背景就是通过此项目介绍使用SpringBoot Vue3两大技术栈开发一个拥有动态权限、路由的前后端分离项目,此项目可以继续完善,成为一个模板为将来快速开发做铺垫。 实现功能 开发流程 通过命令构建前端项目在VSCode中开发ÿ…...

bvh 好用强大的播放器源码
目录 效果图: 显示旋转角度: 显示骨骼名称 下载链接: 可以显示骨骼名称,旋转角度,自适应大小,支持3维npz数据可视化 python实现,提供源代码,修改和完善很方便。 根据3维npz生成…...
安阳在线知识付费系统,培训机构如何进行课程体系的设置?
校外培训不管是从招生还是课程体系都是截然不同的,在课程体系设置上,不同的层次设计也就不同。课程体系设计在功能诉求上可以分为入门课、核心课、高利润课、种子课四个类别。下面为大家介绍一下。 1、入门课 “入门课”就是最易、最省、最少障碍的满足家…...

网络编程:服务器模型-并发服务器-多进程
并发服务器概念: 并发服务器同一时刻可以处理多个客户机的请求 设计思路: 并发服务器是在循环服务器基础上优化过来的 (1)每连接一个客户机,服务器立马创建子进程或者子线程来跟新的客户机通信 (accept之后…...
React 基础案例
React的特点: 1、声明式编程 2、组件化开发 3、多平台适配yuan 原生实现: <h2 class"title"></h2><button class"btn">改变文本</button><script>let msg "Hello World";const titleEl d…...

【Python探索之旅】选择结构(条件语句)
文章目录 条件结构: 1.1 if单分支结构 1.2 if-else 多分支结构 1.3 if-elif 多重结构: 完结撒花 前言 Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块。 Python提供了顺序、选择、循环三…...

Recommender ~ Collaborative filtering
Using per-item features User j 预测 movie i: Cost Function: 仅求和用户投票过的电影。 常规规范化(usual normalization):1/2m 正则化项:阻止过拟合 在知晓X的前提下,如何学习w,b参数…...

我觉得POC应该贴近实际
今天我看到一位老师给我一份测试数据。 这是三个国产数据库。算是分布式的。其中有两个和我比较熟悉,但是这个数据看上去并不好。看上去第一个黄色的数据库数据是这里最好的了。但是即使如此,我相信大部分做数据库的人都知道。MySQL和PostgreSQL平时拿出…...

AI 情感聊天机器人工作之旅 —— 与复读机问题的相遇与别离
前言:先前在杭州的一家大模型公司从事海外闲聊机器人产品,目前已经离职,文章主要讨论在闲聊场景下遇到的“复读机”问题以及一些我个人的思考和解决方案。文章内部已经对相关公司和人员信息做了去敏,如仍涉及到机密等情况…...

如何使用ArcGIS Pro进行选房分析
无论是研究城市规划布局还是寻找理想的住房,都需要综合考虑购物、医疗、教育和休闲等多方面因素,此时我们的GIS软件就可以派上用场了,这里为大家介绍一下如何使用 ArcGIS Pro 进行选房分析,希望能对你有所帮助。 数据来源 教程所…...

android图标底色问题,debug与release不一致
背景 在android 8(sdk 26)之前的版本,直接使用图片文件作为图标,开发时比较容易控制图标,但是不同的安卓定制版本就不容易统一图标风格了。 在android 8及之后的版本,图标对应的是ic_launcher.xml&#x…...
如何提高自己的全局视野?
以下是一些可以帮助提高全局视野的方法: 1. 广泛学习不同领域知识:包括但不限于技术相关的各个领域、业务知识、行业动态等,拓宽知识面。 2. 参与大型项目:积极投身到复杂的、规模较大的项目中,在实践中感受和理解系…...

element ui的确认提示框文字样式修改
修改确认提示框文字样式修改,使用message属性修改: 例: js代码: this.$msgbox({title: 确定要删除吗?,message: this.$createElement(p, null, [this.$createElement(span, { style: color: red }, 该素材一旦删除,…...

Typescript 哲学 - ts模块使用最佳实践
ts的作用域 默认是全局(global),这也是为什么在 两个ts文件声明同一个变量报错变量名冲突,解决方法是使某个文件以模块的形式存在(文件顶层使用 export 、import ) In TypeScript, just as in ECMAScript 2…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...

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

MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...

聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇
根据 QYResearch 发布的市场报告显示,全球市场规模预计在 2031 年达到 9848 万美元,2025 - 2031 年期间年复合增长率(CAGR)为 3.7%。在竞争格局上,市场集中度较高,2024 年全球前十强厂商占据约 74.0% 的市场…...

Tauri2学习笔记
教程地址:https://www.bilibili.com/video/BV1Ca411N7mF?spm_id_from333.788.player.switch&vd_source707ec8983cc32e6e065d5496a7f79ee6 官方指引:https://tauri.app/zh-cn/start/ 目前Tauri2的教程视频不多,我按照Tauri1的教程来学习&…...
python打卡第47天
昨天代码中注意力热图的部分顺移至今天 知识点回顾: 热力图 作业:对比不同卷积层热图可视化的结果 def visualize_attention_map(model, test_loader, device, class_names, num_samples3):"""可视化模型的注意力热力图,展示模…...