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

对博客系统基本功能进行自动化测试(Junit + Selenium)

环境搭建:

  1. 浏览器:
    1. 本次测试使用Chrome浏览器
    2. 在jdk的bin目录下安装对应浏览器驱动(尽量选择与浏览器版本相近的驱动)chromedriver.storage.googleapis.com/index.html
  2. 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>
  3. 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)

环境搭建&#xff1a; 浏览器&#xff1a; 本次测试使用Chrome浏览器在jdk的bin目录下安装对应浏览器驱动&#xff08;尽量选择与浏览器版本相近的驱动&#xff09;chromedriver.storage.googleapis.com/index.htmlJunit依赖&#xff1a; <!-- https://mvnreposit…...

《换你来当爹》:AI驱动的养成游戏,探索虚拟亲子关系的新模式

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

在idea中使用vue

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

Linux系统编程:进程控制

1.进程创建 1.1 fork函数 fork&#xff08;&#xff09;通过复制调用进程来创建一个新进程。新进程称为子进程&#xff0c;是调用进程的精确副本 进程&#xff0c;但以下几点除外&#xff1a; 子进程有自己的PID&#xff0c;此PID与任何现有进程组的ID不匹配子进程的父进程ID…...

Android 异常开机半屏重启代码分析

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

Kafka从0到消费者开发

安装ZK Index of /zookeeper/zookeeper-3.9.2 下载安装包 一定要下载-bin的&#xff0c;不带bin的是源码&#xff0c;没有编译的&#xff0c;无法执行。-bin的才可以执行。 解压 tar -zxvf apache-zookeeper-3.9.2-bin.tar.gz 备份配置 cp zoo_sample.cfg zoo_sample.cfg-b…...

01-项目功能,架构设计介绍

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

bvh 好用强大的播放器源码

目录 效果图&#xff1a; 显示旋转角度&#xff1a; 显示骨骼名称 下载链接&#xff1a; 可以显示骨骼名称&#xff0c;旋转角度&#xff0c;自适应大小&#xff0c;支持3维npz数据可视化 python实现&#xff0c;提供源代码&#xff0c;修改和完善很方便。 根据3维npz生成…...

安阳在线知识付费系统,培训机构如何进行课程体系的设置?

校外培训不管是从招生还是课程体系都是截然不同的&#xff0c;在课程体系设置上&#xff0c;不同的层次设计也就不同。课程体系设计在功能诉求上可以分为入门课、核心课、高利润课、种子课四个类别。下面为大家介绍一下。 1、入门课 “入门课”就是最易、最省、最少障碍的满足家…...

网络编程:服务器模型-并发服务器-多进程

并发服务器概念&#xff1a; 并发服务器同一时刻可以处理多个客户机的请求 设计思路&#xff1a; 并发服务器是在循环服务器基础上优化过来的 &#xff08;1&#xff09;每连接一个客户机&#xff0c;服务器立马创建子进程或者子线程来跟新的客户机通信 &#xff08;accept之后…...

React 基础案例

React的特点&#xff1a; 1、声明式编程 2、组件化开发 3、多平台适配yuan 原生实现&#xff1a; <h2 class"title"></h2><button class"btn">改变文本</button><script>let msg "Hello World";const titleEl d…...

【Python探索之旅】选择结构(条件语句)

文章目录 条件结构&#xff1a; 1.1 if单分支结构 1.2 if-else 多分支结构 1.3 if-elif 多重结构&#xff1a; 完结撒花​ 前言 Python条件语句是通过一条或多条语句的执行结果&#xff08;True或者False&#xff09;来决定执行的代码块。 Python提供了顺序、选择、循环三…...

Recommender ~ Collaborative filtering

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

我觉得POC应该贴近实际

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

AI 情感聊天机器人工作之旅 —— 与复读机问题的相遇与别离

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

如何使用ArcGIS Pro进行选房分析

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

android图标底色问题,debug与release不一致

背景 在android 8&#xff08;sdk 26&#xff09;之前的版本&#xff0c;直接使用图片文件作为图标&#xff0c;开发时比较容易控制图标&#xff0c;但是不同的安卓定制版本就不容易统一图标风格了。 在android 8及之后的版本&#xff0c;图标对应的是ic_launcher.xml&#x…...

如何提高自己的全局视野?

以下是一些可以帮助提高全局视野的方法&#xff1a; 1. 广泛学习不同领域知识&#xff1a;包括但不限于技术相关的各个领域、业务知识、行业动态等&#xff0c;拓宽知识面。 2. 参与大型项目&#xff1a;积极投身到复杂的、规模较大的项目中&#xff0c;在实践中感受和理解系…...

element ui的确认提示框文字样式修改

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

Typescript 哲学 - ts模块使用最佳实践

ts的作用域 默认是全局&#xff08;global&#xff09;&#xff0c;这也是为什么在 两个ts文件声明同一个变量报错变量名冲突&#xff0c;解决方法是使某个文件以模块的形式存在&#xff08;文件顶层使用 export 、import &#xff09; In TypeScript, just as in ECMAScript 2…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

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

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

MySQL的pymysql操作

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

聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇

根据 QYResearch 发布的市场报告显示&#xff0c;全球市场规模预计在 2031 年达到 9848 万美元&#xff0c;2025 - 2031 年期间年复合增长率&#xff08;CAGR&#xff09;为 3.7%。在竞争格局上&#xff0c;市场集中度较高&#xff0c;2024 年全球前十强厂商占据约 74.0% 的市场…...

Tauri2学习笔记

教程地址&#xff1a;https://www.bilibili.com/video/BV1Ca411N7mF?spm_id_from333.788.player.switch&vd_source707ec8983cc32e6e065d5496a7f79ee6 官方指引&#xff1a;https://tauri.app/zh-cn/start/ 目前Tauri2的教程视频不多&#xff0c;我按照Tauri1的教程来学习&…...

python打卡第47天

昨天代码中注意力热图的部分顺移至今天 知识点回顾&#xff1a; 热力图 作业&#xff1a;对比不同卷积层热图可视化的结果 def visualize_attention_map(model, test_loader, device, class_names, num_samples3):"""可视化模型的注意力热力图&#xff0c;展示模…...