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

【个人项目】跑者天地—测试报告

1. 项目概述

背景:复习测试用例这一块知识,我选择以这个项目为例进行练习,系统梳理测试用例相关知识。

概述:本项目是一个基于Web的运动社交平台,用户可以在线分享跑步心得,结识兴趣相同的运动伙伴,共同追求健康生活。

相应技术栈:SpringBoot、HTML、CSS、JavaScript、Ajax、Json、MySQL,Token

2. 测试目的和工具

2.1 测试目的

        本测试报告为跑者天地项目的测试报告,目的在于总结测试阶段以及分析测试结果,描述系统是否符合需求。预期参考人员包括用户、测试人员、开发人员、项目管理者、其他质量管理人员。本次测试的目的在于确保系统功能测试和自动化测试正常无误,满足系统需要

2.2 测试工具

        本次测试使用的工具有Fiddler,Postman,开发者工具等,其中Fiddler用于抓包和模拟弱网环境,详细对HTTP请求进行分析,Postman用户模拟客户端向服务器发送请求,开发者工具用于白盒测试,从代码层出发,观察数据走向

3. 测试主要任务

        针对项目UI界面进行全面测试,分别对登录页面,注册页面,文章列表页面,文章详情页面,文章发布页面,个人中心页面,退出登录页面进行测试,确保各页面功能逻辑正确,界面布局合理,交互流畅。

3.1 设计测试用例

3.1.1 Xmind格式

1)登录页面

2)注册页面

3)文章列表页

4)文章详情页

5)文章发布页

6)个人中心页

7)退出登录页

3.1.2 Excel格式

1)登录页面

用例编号优先级测试标题测试环境测试类型前置条件测试步骤预期结果
1P0正常登录功能验证Win11+Chrome 139.0.7258.67功能测试存在有效账号1. 进入登录页面
2. 输入正确的账号,密码,验证码
3. 点击登录
跳转到文章列表页
2P0空输入异常处理Win11+Chrome 139.0.7258.67功能测试登录页加载完成1. 进入登录页面
2. 点击登录
提示“账号不能为空”
3P1验证码刷新有效性验证Win11+Chrome 139.0.7258.67功能测试登录页加载完成1. 进入登录页面
2. 点击验证码图片
3. 输入正确的账号,密码,验证码
4. 点击登录
跳转到文章列表页
4P0SQL注入攻击防护Win11+Chrome 139.0.7258.67功能测试登录页加载完成1. 进入登录页面
2. 输入正确的账号(' OR 1=1--)
3. 输入密码,验证码
4. 点击登录
登录失败
5P2界面内容溢出检测Win11+Chrome 139.0.7258.67界面测试登录页加载完成1. 输入30字符长账号
2. 输入50字符密码
3. 查看页面显示
无内容截断

2)注册页面

用例编号优先级测试标题测试环境测试类型前置条件测试步骤预期结果
1P0正常注册功能验证Win11+Chrome 139.0.7258.67功能测试进入注册页面1. 输入合规用户名
2. 输入11位手机号
3. 设置密码=确认密码
4. 勾选用户协议
5. 点击注册按钮
注册成功
2P0手机号格式异常验证Win11+Chrome 139.0.7258.67功能测试进入注册页面1. 输入用户名
2. 输入10位手机号
3. 设置有效密码
4. 勾选协议
提示"手机号格式错误"
3P0密码一致性验证Win11+Chrome 139.0.7258.67功能测试进入注册页面1. 输入用户名
2. 输入有效手机号
3. 密码与确认密码不同
4. 勾选协议
实时提示"两次密码不一致"
4P1协议未勾选注册拦截Win11+Chrome 139.0.7258.67功能测试进入注册页面1. 输入有效注册信息
2. 不勾选用户协议
3. 点击注册按钮
提示"请阅读并同意用户协议"
5P1SQL注入攻击防御验证Win11+Chrome 139.0.7258.67安全性测试进入注册页面1. 用户名输入:admin'--
2. 手机号输入:'; DROP TABLE users;--
3. 设置有效密码
4. 勾选协议
注册失败,数据库无异常
6P1特殊字符输入稳定性验证Win11+Chrome 139.0.7258.67功能测试进入注册页面1. 用户名输入:!@#$%^&*()
2. 手机号输入有效号码
3. 设置有效密码
4. 勾选协议
系统正常处理字符,无崩溃/卡死现象

3)文章列表页面

用例编号优先级测试标题测试环境测试类型前置条件测试步骤预期结果
1P0发帖按钮跳转功能验证Win11+Chrome 139.0.7258.67功能测试已登录状态1. 进入文章列表页
2. 点击"立即发帖"按钮
成功跳转到文章编写页面
2P0浏览排序功能验证Win11+Chrome 139.0.7258.67功能测试列表有≥3篇文章1. 选择"最多浏览"排序模式
2. 记录前三篇文章浏览量
3. 验证排序顺序
文章按浏览量降序排列(浏览量高的在前)
3P0文章跳转功能验证Win11+Chrome 139.0.7258.67功能测试列表有≥1篇文章1. 点击任意文章标题
2. 检查页面跳转
成功跳转到对应文章详情页
4P1主页按钮刷新功能Win11+Chrome 139.0.7258.67功能测试列表有文章1. 修改列表内容
2. 点击顶部"主页"按钮
页面刷新并显示最新内容
5P1未登录URL访问验证Win11+Chrome 139.0.7258.67安全性测试未登录状态1. 直接输入文章列表URL访问跳转至登录页
6P1越权访问验证Win11+Chrome 139.0.7258.67安全性测试用户A已登录1. 修改URL中的用户ID为其他用户
2. 尝试访问
显示无权限,并返回登录页面

4)文章详情页面

用例编号优先级测试标题测试环境测试类型前置条件测试步骤预期结果
1P0文章内容加载验证Win11+Chrome 139.0.7258.67功能测试访问文章详情页1. 打开文章详情页正确显示文章标题、正文信息
2P0作者编辑功能验证Win11+Chrome 139.0.7258.67功能测试当前用户=文章作者1. 点击"编辑文章"按钮跳转至文章编辑页面
3P0浏览量增加验证Win11+Chrome 139.0.7258.67功能测试记录当前浏览量1. 刷新页面
2. 重新进入详情页
浏览量增加1
4P0主页按钮跳转验证Win11+Chrome 139.0.7258.67功能测试在文章详情页1. 点击顶部"主页"按钮跳转至文章列表页
5P1非作者删除权限拦截Win11+Chrome 139.0.7258.67安全性测试当前用户≠文章作者1. 尝试点击"删除文章"按钮提示"不是作者,无法删除"
6P1未登录访问拦截Win11+Chrome 139.0.7258.67安全性测试未登录状态1. 直接输入文章详情页URL访问跳转至登录页

5)文章发布页面

用例编号优先级测试标题测试环境测试类型前置条件测试步骤预期结果
1P0主页按钮跳转验证Win11+Chrome 139.0.7258.67功能测试在编写页面1. 点击顶部"主页"按钮跳转至文章列表页
2P0发布功能验证-标题缺失Win11+Chrome 139.0.7258.67功能测试已登录状态1. 输入文章内容
2. 留空标题
3. 点击发布
提示"标题不能为空",阻止发布
3P0发布功能验证-内容缺失Win11+Chrome 139.0.7258.67功能测试已登录状态1. 输入文章标题
2. 留空内容
3. 点击发布
提示"内容不能为空",阻止发布
4P0发布成功跳转验证Win11+Chrome 139.0.7258.67功能测试输入完整内容1. 输入标题和内容
2. 点击发布
发布成功,跳转至文章列表页
5P1Markdown渲染验证Win11+Chrome 139.0.7258.67功能测试输入Markdown格式1. 输入#标题
2. 输入**加粗**文本
3. 预览内容
正确渲染为HTML格式
6P1特殊字符处理验证Win11+Chrome 139.0.7258.67功能测试准备特殊字符1. 标题输入: @#$%^&*()
2. 内容输入: null字符
3. 点击发布
系统正常处理,无崩溃

6)个人中心页面

用例编号优先级测试标题测试环境测试类型前置条件测试步骤预期结果
1P0编辑状态初始化验证Win11+Chrome 139.0.7258.67功能测试已登录状态1. 点击"编辑信息"按钮密码字段清空,其余信息可编辑
2P0必填项缺失验证Win11+Chrome 139.0.7258.67功能测试进入编辑状态1. 清空账号字段
2. 点击"保存修改"
提示"账号不能为空",阻止保存
3P0密码修改有效性验证Win11+Chrome 139.0.7258.67功能测试修改密码1. 输入新密码
2. 保存修改
3. 注销后使用新密码登录
新密码登录成功
4P0原始密码失效验证Win11+Chrome 139.0.7258.67功能测试已修改密码1. 使用旧密码尝试登录提示"密码错误",登录失败
5P1取消修改功能验证Win11+Chrome 139.0.7258.67功能测试进入编辑状态1. 修改部分信息
2. 点击"取消"按钮
信息恢复修改前状态
6P1未授权访问拦截Win11+Chrome 139.0.7258.67安全性测试未登录状态1. 直接输入个人中心URL访问跳转至登录页
7P1密码显示安全验证Win11+Chrome 139.0.7258.67安全性测试查看密码字段1. 检查密码输入框密码显示为掩码(*)
8P1SQL注入防御验证Win11+Chrome 139.0.7258.67安全性测试编辑状态1. 账号输入:admin'--
2. 尝试保存
拦截特殊字符,保存失败
9P2手机号格式校验Win11+Chrome 139.0.7258.67功能测试修改手机号1. 输入错误格式号码(如10位)实时提示"手机号格式错误"

7)退出登录页面

用例编号优先级测试标题测试环境测试类型前置条件测试步骤预期结果
1P0主页按钮跳转验证Win11+Chrome 139.0.7258.67功能测试在注销页面1. 点击顶部"主页"按钮跳转至文章列表页
2P0注销流程验证Win11+Chrome 139.0.7258.67功能测试已登录状态1. 点击"注销"按钮
2. 点击"确认退出"
3. 点击成功提示的"确定"
成功退出,跳转至登录页
3P0取消注销功能验证Win11+Chrome 139.0.7258.67功能测试打开注销确认框1. 点击"取消"按钮返回原页面,保持登录状态
4P1令牌删除验证Win11+Chrome 139.0.7258.67安全性测试已执行注销1. 检查localStorage/user_token字段是否存在身份令牌被清除
5P1未登录访问拦截Win11+Chrome 139.0.7258.67安全性测试未登录状态1. 直接输入注销页面URL访问跳转至登录页
6P1弱网注销处理Win11+Chrome 139.0.7258.67网络测试已登录状态1. 弱网环境下执行注销操作2秒内显示加载图标,超时提示

3.2 执行测试用例

考虑篇幅过长,这里只分享部分测试用例的执行

3.2.1 注册测试

正常注册

  1. 打开谷歌浏览器
  2. 输入网址 :http://127.0.0.1:8080/register.html
  3. 输入用户名,手机号码,密码,确认密码
  4. 勾选协议
  5. 点击注册按钮

结果:提示注册成功


异常注册

结果:将错误的原因直接显示出来

  1. 打开谷歌浏览器
  2. 输入网址 :http://127.0.0.1:8080/register.html
  3. 输入用户名,手机号码,密码,错误的确认密码
  4. 未勾选协议
  5. 点击注册

3.2.2 登录测试

正常登录

  1. 打开谷歌浏览器
  2. 输入网址 :http://127.0.0.1:8080/login.html
  3. 输入用户名,密码,验证码
  4. 点击登录

结果:跳转到文章列表页


异常登录

  1. 打开谷歌浏览器
  2. 输入网址 :http://127.0.0.1:8080/login.html
  3. 输入用户名,密码,验证码
  4. 点击登录

结果:登录失败并提示错误原因

3.2.3 文章发布测试

前置条件:已登录(满足)

发布成功

  1. 打开谷歌浏览器
  2. 输入网址 :http://127.0.0.1:8080/write.html
  3. 输入文章标题,内容,文章类别
  4. 点击发布

结果:跳转到文章列表页,可以观察到刚刚发布的文章


异常发布

  1. 打开谷歌浏览器
  2. 输入网址 :http://127.0.0.1:8080/write.html
  3. 未输入文章标题,输入内容,文章类别
  4. 点击发布

结果:发布失败并提示原因

3.2.4 修改文章

前置条件:文章的作者和登录用户一致(满足)

修改成功

  1. 打开谷歌浏览器
  2. 输入网址 :http://127.0.0.1:8080/update.html?articleId=59
  3. 输入新的标题
  4. 点击发布

结果:提示修改成功


修改失败

  1. 打开谷歌浏览器
  2. 输入网址 :http://127.0.0.1:8080/update.html?articleId=59
  3. 删除标题内容
  4. 点击发布

结构:提示修改失败

3.2.5 删除文章

删除成功

  1. 打开谷歌浏览器
  2. 输入网址 :http://127.0.0.1:8080/DetailPage.html?articleId=59 
  3. 前置条件:文章的作者和登录用户一致
  4. 点击删除文章按钮

结果:提示删除成功


删除失败

  1. 打开谷歌浏览器
  2. 输入网址 :http://127.0.0.1:8080/DetailPage.html?articleId=57
  3. 前置条件:文章的作者和登录用户不一致
  4. 点击删除文章按钮

结果:提示无法删除

3.2.6 修改个人信息测试

前置条件:已登录(满足)

修改成功

  1. 打开谷歌浏览器
  2. 输入网址 :http://127.0.0.1:8080/me.html
  3. 点击编辑信息按钮
  4. 输入新的密码123123
  5. 点击保存修改

结果:提示修改成功

3.3 自动化测试

3.3.1 自动化测试环境

  • 操作系统:Windows11
  • 浏览器:谷歌浏览器 
  • 浏览器版本:139.0.7258.128(正式版本) (64 位)
  • 数据库:MySQL 8.0
  • 测试工具:selenium,JUnit 5.9.1

3.3.2 自动化测试用例

3.3.3 自动化代码编写

1)导入依赖
        <dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>4.0.0</version></dependency><dependency><groupId>io.github.bonigarcia</groupId><artifactId>webdrivermanager</artifactId><version>5.5.3</version></dependency>
2)创建测试包和类

为了避免自动化混乱,从页面为模块进行分类,每个页面创建单独的类进行管理,类中提供多个方法,对页面中的属性和功能进行测试

3)创建公共类

Utils 公共类中包含一些公共方法,比如创建驱动,截屏操作,关闭驱动操作

package org.example.runningforum.common;import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Duration;public class Utils {public static WebDriver driver;public Utils(String url){driver = createDriver();driver.get(url);}/** 创建谷歌浏览器驱动* */public static WebDriver createDriver(){if(driver == null){//初始化驱动管理
//            WebDriverManager.chromedriver().setup();//设置浏览器属性ChromeOptions options = new ChromeOptions();options.addArguments("--remote-allow-origins=*");//创建驱动对象driver = new ChromeDriver();//添加隐式等待driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));}return driver;}public static void getScreenShot(String className,String methodName) throws IOException {SimpleDateFormat ymd = new SimpleDateFormat("yyyy-MM-dd");SimpleDateFormat hms = new SimpleDateFormat("HH-mm-ss-SS");String dirPath = ymd.format(System.currentTimeMillis());String fileName = className+"-"+methodName+"-"+hms.format(System.currentTimeMillis());String filePath = "./running-forum/src/test/java/org/example/runningforum/image/"+dirPath+"/"+fileName+".png";File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);FileUtils.copyFile(srcFile,new File(filePath));}public  void closeDriver(){if(driver!=null){driver.quit();}}
}
4)注册界面

自动化主要有三个核心方法

  • 验证界面加载是否正确
  • 验证注册成功
  • 验证注册失败
package org.example.runningforum.tests;import org.example.runningforum.common.Utils;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;import java.io.IOException;public class Register extends Utils {public static String url = "http://127.0.0.1:8080/register.html";public Register() {super(url);}/** 检查界面是否加载完毕* */public void registerPageRight(){driver.findElement(By.cssSelector("#username"));driver.findElement(By.cssSelector("#mobile"));driver.findElement(By.cssSelector("#password"));driver.findElement(By.cssSelector("#confirmPassword"));driver.findElement(By.cssSelector("#terms"));}/** 检查页面注册功能 —— 注册成功* */public void registerSuccess() throws IOException, InterruptedException {String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();driver.navigate().refresh();driver.findElement(By.cssSelector("#username")).sendKeys("user1");driver.findElement(By.cssSelector("#mobile")).sendKeys("19635264587");driver.findElement(By.cssSelector("#password")).sendKeys("123456");driver.findElement(By.cssSelector("#confirmPassword")).sendKeys("123456");//勾选用户协议driver.findElement(By.cssSelector("#terms")).click();getScreenShot(getClass().getName(),methodName);driver.findElement(By.cssSelector("#registerButton")).click();//必须强制等待Thread.sleep(500);Alert alert = driver.switchTo().alert();String alertText = alert.getText();assert alertText.equals("注册成功");//在警告的时候,不能进行其他操作alert.accept();getScreenShot(getClass().getName(),methodName);}/** 检查页面注册功能 —— 注册失败* */public void registerFail() throws IOException, InterruptedException {String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();driver.navigate().refresh();driver.findElement(By.cssSelector("#username")).sendKeys("user1");driver.findElement(By.cssSelector("#mobile")).sendKeys("19635264587");driver.findElement(By.cssSelector("#password")).sendKeys("123456");driver.findElement(By.cssSelector("#confirmPassword")).sendKeys("123456");//勾选用户协议driver.findElement(By.cssSelector("#terms")).click();getScreenShot(getClass().getName(),methodName);driver.findElement(By.cssSelector("#registerButton")).click();Thread.sleep(500);Alert alert = driver.switchTo().alert();String alertText = alert.getText();assert alertText.equals("用户名被使用");alert.accept();getScreenShot(getClass().getName(),methodName);}
}
5)登录界面

自动化测试主要有三个核心方法

  • 验证界面加载是否正确
  • 验证登录成功
  • 验证登录失败
package org.example.runningforum.tests;import org.example.runningforum.common.Utils;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;import java.io.IOException;public class LoginPage extends Utils {public static String url = "http://127.0.0.1:8080/login.html";public LoginPage() {super(url);}/** 检查元素是否加载完毕* */public void loginPageRight(){driver.findElement(By.cssSelector("#username"));driver.findElement(By.cssSelector("#password"));driver.findElement(By.cssSelector("#inputCaptcha"));}/** 验证登录功能--成功登录* */public void loginSuccess() throws IOException {//获取方法名String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();//刷新,保证输入框没有元素driver.navigate().refresh();//输入信息driver.findElement(By.cssSelector("#username")).sendKeys("user1");driver.findElement(By.cssSelector("#password")).sendKeys("123456");//获取验证码String text = driver.findElement(By.cssSelector("#verificationCodeImg")).getText();driver.findElement(By.cssSelector("#inputCaptcha")).sendKeys(text);//截图getScreenShot(getClass().getName(), methodName );//点击登录driver.findElement(By.cssSelector("#submit")).click();//检验是否跳转到列表页String expect = driver.findElement(By.cssSelector("body > div.container > div.welcome-banner > h1")).getText();//使用断言判断assert expect.equals("欢迎来到跑者天地");//截图getScreenShot(getClass().getName(), methodName );}/** 验证登录功能--登录失败* */public void loginFail() throws IOException {//获取方法名String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();//刷新,保证输入框没有元素driver.navigate().refresh();//输入信息driver.findElement(By.cssSelector("#username")).sendKeys("admin");driver.findElement(By.cssSelector("#password")).sendKeys("123");//获取验证码String text = driver.findElement(By.cssSelector("#verificationCodeImg")).getText();driver.findElement(By.cssSelector("#inputCaptcha")).sendKeys(text);//截图getScreenShot(getClass().getName(), methodName );Alert alert = driver.switchTo().alert();String alertText = alert.getText();assert alertText.equals("账号或密码错误");}}
6)文章列表页面

自动化测试主要测试:

  • 界面加载是否正确
  • 是否根据浏览量排序文章
  • 是否根据文件发布时间排序文章
package org.example.runningforum.tests;import org.example.runningforum.common.Utils;
import org.openqa.selenium.By;import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;public class ListPage extends Utils {public static String url = "http://127.0.0.1:8080/index.html?currentPage=1";public ListPage() {super(url);}/** 验证界面加载* */public  void listPageRight(){driver.findElement(By.cssSelector("body > div.container > div.welcome-banner > h1"));driver.findElement(By.cssSelector("#sortSelector"));driver.findElement(By.cssSelector("body > div.container > div.welcome-banner > a"));driver.findElement(By.cssSelector("#header-container > header > div > div > nav > ul > li:nth-child(1) > a"));}/** 验证列表界面功能 —— 功能正常* */public  void listSuccess() throws InterruptedException {listPageRight();driver.navigate().refresh();//验证最新发布driver.findElement(By.cssSelector("#sortSelector > option:nth-child(1)")).click();String timeStr1 = driver.findElement(By.cssSelector("#card-body > div:nth-child(1) > div.post-content > div > span:nth-child(2)")).getText();String timeStr2 = driver.findElement(By.cssSelector("#card-body > div:nth-child(2) > div.post-content > div > span:nth-child(2)")).getText();//比较时间DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH-mm");// 解析为 LocalDateTime 对象LocalDateTime time1 = LocalDateTime.parse(timeStr1, formatter);LocalDateTime time2 = LocalDateTime.parse(timeStr2, formatter);int comparison = time1.compareTo(time2);assert comparison>0;driver.findElement(By.cssSelector("#sortSelector > option:nth-child(2)")).click();Thread.sleep(500);Integer count1 = Integer.valueOf(driver.findElement(By.cssSelector("#card-body > div:nth-child(1) > div.post-content > div > span:nth-child(3) ")).getText());Integer count2 = Integer.valueOf(driver.findElement(By.cssSelector("#card-body > div:nth-child(2) > div.post-content > div > span:nth-child(3) ")).getText());assert count1>count2;}}
7)文章发布页面

自动化测试主要验证:

  • 发布界面是否加载正确
  • 发布功能是否正常
package org.example.runningforum.tests;import org.example.runningforum.common.Utils;
import org.openqa.selenium.By;public class WritePage extends Utils {public static String url = "http://127.0.0.1:8080/write.html";public WritePage() {super(url);}/** 验证页面加载* */public void writePageRight(){driver.navigate().refresh();String title = driver.findElement(By.cssSelector("body > div.content-edit > div.create-post-header > h1")).getText();assert "创作新文章".equals(title);driver.findElement(By.cssSelector("#title"));driver.findElement(By.cssSelector("#editor > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll > div.CodeMirror-sizer > div > div > div > div.CodeMirror-code > div > pre > span > span"));}/** 发布成功* */public void WriteSuccess(){driver.navigate().refresh();driver.findElement(By.cssSelector("#title")).sendKeys("跑步技巧");driver.findElement(By.cssSelector("#submit")).click();String text = driver.findElement(By.cssSelector("body > div.container > div.welcome-banner > h1")).getText();assert "欢迎来到跑者天地".equals(text);}}
8)修改文章页面

自动化测试主要验证:

  • 界面是否加载正确
  • 修改文章内容是否成功
package org.example.runningforum.tests;import org.example.runningforum.common.Utils;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;public class UpdatePage extends Utils {public static String url = "http://127.0.0.1:8080/update.html?articleId=45";public UpdatePage() {super(url);}/** 验证界面记载* */public void updatePageRight(){String text = driver.findElement(By.cssSelector("body > div.content-edit > div.create-post-header > h1")).getText();assert "修改文章".equals(text);text = driver.findElement(By.cssSelector("#submit")).getText();assert "发布文章".equals(text);}/** 验证功能 — 成功* */public void updateSuccess() throws InterruptedException {driver.findElement(By.cssSelector("#title")).clear();driver.findElement(By.cssSelector("#title")).sendKeys("新标题");WebElement element = driver.findElement(By.cssSelector("#editor > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll > div.CodeMirror-sizer > div > div > div > div.CodeMirror-code > div > pre > span > span"));Actions actions = new Actions(driver);//先选中位置actions.doubleClick(element).perform();//全选操作actions.sendKeys(Keys.chord(Keys.COMMAND, "a")).perform();//删除内容actions.keyDown(Keys.DELETE).perform();//添加内容actions.sendKeys("运动对身体好").perform();driver.findElement(By.cssSelector("#submit")).click();Thread.sleep(500);String alertText = driver.switchTo().alert().getText();assert "修改成功".equals(alertText);driver.switchTo().alert().accept();//判断是否修改成功String newContent = driver.findElement(By.cssSelector("#card-body > div:nth-child(1) > div.post-content > p")).getText();assert "运动对身体好".equals(newContent);}
}
9)个人信息页面

自动化测试主要验证:

  • 界面是否加载正确
  • 个人信息修改是否成功
  • 修改途中取消修改,是否成功
package org.example.runningforum.tests;import org.example.runningforum.common.Utils;
import org.openqa.selenium.By;public class MePage extends Utils {public static String url = "http://127.0.0.1:8080/me.html";public MePage() {super(url);}/** 检验界面加载* */public void mePageRight(){String text = driver.findElement(By.cssSelector("body > div.container > div > div.card-header > h1")).getText();assert "跑者信息中心".equals(text);text = driver.findElement(By.cssSelector("#edit-btn")).getText();assert "编辑信息".equals(text);}/** 检验编辑功能——编辑成功* */public void mePageSuccess(){driver.navigate().refresh();driver.findElement(By.cssSelector("#edit-btn")).click();String password = driver.findElement(By.cssSelector("#password-input")).getText();assert password == null;driver.findElement(By.cssSelector("#password-input")).sendKeys("123456");driver.findElement(By.cssSelector("#save-btn")).click();String text = driver.findElement(By.cssSelector("#notification-text")).getText();assert text.equals("用户信息更新成功!");}/** 检验功能——取消编辑* */public void mePageFail(){driver.navigate().refresh();driver.findElement(By.cssSelector("#edit-btn")).click();String password = driver.findElement(By.cssSelector("#password-input")).getText();assert password == null;driver.findElement(By.cssSelector("#password-input")).sendKeys("123456");driver.findElement(By.cssSelector("#cancel-btn")).click();String text = driver.findElement(By.cssSelector("#notification-text")).getText();assert text.equals("已取消修改");}
}
10)注销界面

自动化测试主要验证:

  • 界面是否加载正确
  • 注销功能是否成功
  • 点击取消注销是否返回首页
package org.example.runningforum.tests;import org.checkerframework.checker.units.qual.A;
import org.example.runningforum.common.Utils;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;public class LogoutPage extends Utils {public static String url = "http://127.0.0.1:8080/logout.html";public LogoutPage() {super(url);}/** 验证页面加载* */public void loginOutPageRight(){driver.navigate().refresh();String text = driver.findElement(By.cssSelector("body > div.container > div > div > div > h2")).getText();assert text.equals("您确定要退出登录吗?");text = driver.findElement(By.cssSelector("#logout-btn")).getText();assert text.equals("确认退出");}/** 验证功能——成功* */public  void loginOutSuccess(){driver.navigate().refresh();driver.findElement(By.cssSelector("#logout-btn")).click();Alert alert = driver.switchTo().alert();String alertText = alert.getText();assert alertText.equals("您已成功退出登录");alert.accept();//是否退回登录页面String text = driver.findElement(By.cssSelector("body > div.container > div.login-dialog > h3")).getText();assert text.equals("用户登录");}/** 验证功能——失败* */public  void loginOutFail(){driver.navigate().refresh();driver.findElement(By.cssSelector("#cancel-btn")).click();//是否退回列表页面String text = driver.findElement(By.cssSelector("body > div.container > div.welcome-banner > h1")).getText();assert text.equals("欢迎来到跑者天地");}
}
11)文章详情页面

自动化测试主要验证:

  • 界面是否加载正确
  • 验证删除文章和修改文章功能是否正常
package org.example.runningforum.tests;import org.example.runningforum.common.Utils;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;public class DetailPage extends Utils {public static String url = "http://127.0.0.1:8080/DetailPage.html?articleId=11";public DetailPage() {super(url);}/** 验证界面加载* */public void detailPageRight(){driver.findElement(By.cssSelector("#article-header1 > h1"));driver.findElement(By.cssSelector("#header-container > header > div > div > nav > ul > li:nth-child(1) > a"));String text = driver.findElement(By.cssSelector("#article-header1 > div > div.article-stats > button.action-btn.edit-btn")).getText();assert text.equals("编辑文章");String title = driver.findElement(By.cssSelector("#article-header1 > h1")).getText();assert title != null;}/** 验证功能——操作失败* */public  void detailFail() throws InterruptedException {driver.navigate().refresh();driver.findElement(By.cssSelector("#article-header1 > div > div.article-stats > button.action-btn.edit-btn")).click();Thread.sleep(500);Alert alert = driver.switchTo().alert();String alertText = alert.getText();assert alertText.equals("不是作者,无法修改");alert.accept();driver.findElement(By.cssSelector("#article-header1 > div > div.article-stats > button.action-btn.delete-btn")).click();Thread.sleep(500);alertText = alert.getText();assert alertText.equals("不是作者,无法删除");alert.accept();}/** 验证功能——操作成功* */public  void detailSuccess(){driver.navigate().refresh();driver.findElement(By.cssSelector("#article-header1 > div > div.article-stats > button.action-btn.edit-btn")).click();String text = driver.findElement(By.cssSelector("body > div.content-edit > div.create-post-header > h1")).getText();assert text.equals("修改文章");driver.navigate().back();driver.findElement(By.cssSelector("#article-header1 > div > div.article-stats > button.action-btn.delete-btn")).click();Alert alert = driver.switchTo().alert();String alertText = alert.getText();assert alertText.equals("删除成功");alert.accept();}
}

3.3.4 自动化测试的执行

1)运行代码
package org.example.runningforum;import org.apache.catalina.AccessLog;
import org.example.runningforum.tests.*;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;@SpringBootTest
class RunningForumApplicationTests {public static void main(String[] args) throws IOException, InterruptedException {//注册Register register = new Register();register.registerPageRight();
//        register.registerSuccess();;register.registerFail();//登录LoginPage loginPage = new LoginPage();loginPage.loginPageRight();loginPage.loginSuccess();
//        loginPage.loginFail();//列表页面ListPage listPage = new ListPage();listPage.listPageRight();listPage.listSuccess();//详细页面DetailPage detailPage = new DetailPage();detailPage.detailPageRight();detailPage.detailFail();
//        detailPage.detailSuccess();//写文章页面WritePage writePage = new WritePage();writePage.writePageRight();writePage.WriteSuccess();//修改页面UpdatePage updatePage = new UpdatePage();updatePage.updatePageRight();updatePage.updateSuccess();//个人页面MePage mePage = new MePage();mePage.mePageRight();mePage.mePageFail();mePage.mePageSuccess();//退出登录LogoutPage logoutPage = new LogoutPage();logoutPage.loginOutPageRight();
//        logoutPage.loginOutFail();logoutPage.loginOutSuccess();logoutPage.closeDriver();}}

从注册用户,登录账号,验证列表界面,验证文章详情页面,验证发布文章界面,验证修改文章界面,验证其功能是否正确,验证个人信息页面,验证其是否可以修改,最后验证注销页面,退出登录,这一系列流程,模拟用户的真实使用,将核心功能覆盖,并对其进行自动化测试

2)自动化测试预览

4. 测试结果

4.1 出现的bug

由于篇幅问题,只说明其中1个

经过实际测试发现预期结果与实际结果大部分一致!需要提交修改的bug如下:

在自动化部测试的时候,系统报出元素定位失败的错误,经过一系列的检查,发现代码并不存在错误,位置定位正确,通过增加3秒强制等待,又回归正常,可以访问到元素,原因分析:页面渲染需要一定的时间,而后端中代码执行速度较快,页面无法快速显现而报错

4.2 bug提交

bug编号:01

运行环境:Windows11 + 谷歌浏览器 139.0.7258.128(正式版本) (64 位)

bug级别:P0

bug标题:自动化测试,发布文章页面出现元素定位异常

前置条件:登录状态下

bug步骤:

  1. 打开谷歌浏览器
  2. 输入网址:http://127.0.0.1:8080/write.html
  3. 问题元素cssSelector路径:#submit

bug的状态:已解决

自动执行预期结果:

自动化执行实际结果:

5. 总结

通过对这个项目的测试,加强了我对测试知识的掌握,从中也收获了很多测试方面的心得

  • 在执行测试用例的时候,注意测试用例的执行顺序,不同的执行顺序可能会让原本正常的结果出现异常
  • 保存好现场的截图,并分类好测试的时间,类名和方法,帮助测试人员更好的进行回溯,定位问题
  • 使用单例模式创建驱动,省去不必要的开销
  • 测试用例不是越多越好,要做到对功能的覆盖率最大化
  • 合理运用等待,可以帮助定位问题和提高自动化运行效率
  • 对测试的对象做好分类,避免出现自动化混乱的情况
http://www.dtcms.com/a/336696.html

相关文章:

  • 深入解析二维数组传参的本质
  • 运动场和光流-动手学计算机视觉17
  • 正则表达式实用面试题与代码解析专栏
  • 【Nginx】限流设置
  • 二三层交换转发业务~基础汇总
  • Mysql笔记-错误条件\处理程序
  • SSM从入门到实践:1.1 Spring框架概述与IoC容器入门
  • 堆(Heap):高效的优先级队列实现
  • duiLib 解决点击标题栏中按钮无响应问题
  • ROS2基础
  • C语言零基础第19讲:自定义类型—联合体和枚举
  • 解锁Java开发神器:XXL-Job从入门到精通
  • BT_LE_ADV_CONN_ONE_TIME 参数详解
  • Spring 创建 Bean 的 8 种主要方式
  • [创业之路-556]:创新的本质是赚不确定性带来的潜在价值,把不确定性逐步转化确定性,周而复始。
  • 产品设计.Ai产品经理
  • 48.Seata认识、部署TC服务、微服务集成
  • 网络中的一些基本概念
  • Conda 环境 在AI 私有化部署 有怎么用?
  • 微信小程序 小白gps工具v0.01 使用说明
  • react echarts图表监听窗口变化window.addEventListener(‘resize’)与ResizeObserver()
  • python -基础(5)组合数据类型
  • 每日两道算法题:DAY3
  • java常见的数据加密
  • 当 AI 开始 “理解” 情感:情感计算技术正在改写人机交互规则
  • Linux 服务:iSCSI 存储服务配置全流程指南
  • 廖雪峰-Java教程-Part02
  • C#高级语法_委托
  • 力扣第463场周赛
  • 17-线程