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

《博客系统测试报告》

一、引言

1.1 编写目的

       本次博客系统测试报告旨在全面评估博客系统的整体质量,通过对博客系统各项功能(如个人博客列表、分页功能、文章发布、编辑、删除,用户注册登录等)非功能特性的严格测试,发现系统中存在的缺陷和不足。报告期望为个人博客系统提供详细、准确的测试结果和分析,为后续系统的开发和维护工作提供有力依据,以确保博客系统能够稳定、高效地运行。

1.2  背景

  1. 本个人博客系统是基于前后端分离模式开发的学习实践项目,主要用于练习主流技术栈的整合与实战。
  2. 后端采用 Java 生态,基于 Spring Boot 框架搭建,整合了 Spring MVC 处理请求响应、Spring AOP 实现日志与事务管理,并使用 Redis 优化数据访问性能,数据库选用 MySQL 存储博客内容及用户信息。
  3. 前端通过 HTML、CSS 和 JavaScript 实现基础交互,包含登录页、注册页、博客列表页、博客详情页、编辑页等核心页面,整体架构简洁清晰,覆盖了个人博客的基础功能。

1.3 核心功能实现 

  • 用户模块:实现了用户注册登录(含密码加密)、注销功能,通过拦截器实现强制登录校验,确保未登录用户无法访问编辑等敏感操作。
  • 博客模块:支持博客的创建、编辑、删除,编辑页通过模拟键盘操作(如 Ctrl+A 全选清除)提升交互体验,博客详情页可展示标题、内容、浏览量、发布时间及作者信息。
  • 技术实践:尝试了前后端数据交互(如表单提交、JSON 数据传输)、浏览器弹窗处理(Alert)及简单的自动化测试(使用 Selenium 编写测试用例验证核心流程)。
  • 待完善点:头像功能暂未实现、用户信息文章数、分类数、未与后端同步、缺少仓库链接、为实现评论点赞功能;

 二、测试范围

2.1 功能测试

本次测试覆盖了个人博客系统的核心功能模块,结合自动化测试与手动验证,确保基础功能的可用性和用户交互的流畅性。

  • 用户注册:验证用户名/ 密码格式校验、重复注册提示;
  • 登录功能:验证账号密码正确性、登录状态保持(Cookie/Session);
  • 强制登录:未登录用户访问编辑页 / 个人中心,是否跳转至 登录页面;
  • 文章发布:标题 / 内容输入、Markdown 格式支持、提交按钮交互;
  • 文章编辑: 修改已发布文章的标题 / 内容, 验证修改后是否实时更新;
  • 文章删除:删除操作后的二次确认、删除后列表是否同步更新;
  • 分页功能:验证个人列表页、主页的首页、尾页、上一页、下一页功能;

2.2 非功能测试

2.2.1 性能测试

  • 页面加载性能测试: 测试首页、博客详情页、登录页面等核心页面的加载速度与响应时间。
  • 并发访问性能测试:模拟多用户同时访问首页、浏览文章、注册、发布文章等操作,检测系统高并发下的性能表现。
  • 数据库操作性能测试:验证数据库在大量数据查询和高频写入操作时的处理效率与稳定性。
  • 压力测试:进行长时间高负载压力测试及弱网环境下的性能测试,评估系统稳定性和容错能力。

2.2.2 界面测试

  • 登录界面:检查页面布局、文本错别、加载报错、输入框长度、按钮位置及设计风格是否合规。
  • 注册界面:验证表单布局合理性,保证标签与输入框对应;检查文本完整性与提示清晰度;测试响应式设计适配效果;确保视觉元素对齐;检查颜色对比度合规性。
  • 个人列表界面:审查信息展示布局,避免多余空白或拥挤;检查静态元素;确保字体样式一致;测试无博客时访问列表页的显示情况。
  • 博客列表界面:保证列表项布局统一,分页控件正常显示。
  • 博客详情界面:确保内容排版合理,发布时间和阅读量正确展示。
  • 博客编辑界面:检查 MarkDown 编辑器布局、发布按钮功能及占位符提示。

2.2.3 安全测试

  • 身份认证与授权安全测试:检测弱密码使用、防范暴力破解攻击、保障会话管理安全、防止权限越界访问。
  • 数据传输安全测试:验证 HTTPS 协议应用,确保数据传输过程中的完整性。
  • 数据存储安全测试:检查数据库加密状态,测试数据库备份与恢复功能的有效性。
  • 输入验证与漏洞防范测试:开展 SQL 注入攻击测试和 XSS 攻击防范验证,避免系统存在安全漏洞。

2.2.4 易用性测试

  • 导航与操作便捷性:检验导航栏(含登录、注册按钮)易用性,测试系统在多设备上的操作适配情况。
  • 输入与反馈友好性:查看表单输入提示是否明确、实时输入校验是否生效、操作反馈是否清晰。
  • 信息可读性与理解性:评估文本排版可读性和错误信息的易懂程度。
  • 用户引导和帮助:测试新用户引导功能、检查帮助文档入口是否便捷、验证操作撤销与恢复功能是否可用。

2.2.5 兼容性测试

浏览器兼容性测试:测试 Chrome、Firefox、Safari、Edge 新旧版本访问兼容性

操作系统兼容性测试:验证博客系统在 Windows 7/10/11 和 macOS Monterey 系统的访问兼容性。

三、测试环境

3.1 硬件环境and软件环境

服务器端硬件配置
设备类型配置参数用途
开发服务器(本地)CPU:Intel Core i5-10400(6 核 12 线程)
内存:16GB DDR4
硬盘:512GB SSD
系统:Windows 10 64 位
运行后端服务(Spring Boot)、数据库(MySQL 8.0)、缓存(Redis)

客户端设备(前端测试)
设备类型      型号 / 配置操作系统浏览器版本屏幕分辨率
笔记本电脑拯救者 R7000P
CPU:AMD Ryzen 7 5800H with Radeon Graphics  3.20 GHz
显卡:NVIDIA GeForce RTX 3050 Ti Laptop GPU
Windows 10 专业版

Chrome 135.0.7049.96(正式版本) (64 位)

Microsoft Edge版本 126.0.2592.61 (正式版本) (64 位)

1920×1080(默认)

3.2 测试工具

工具
工具优势
JAVA强类型语言,生态成熟,适合大型测试框架扩展(如 JUnit、TestNG)。
IDEA智能代码补全、调试工具强大,支持 Maven/Gradle 依赖管理,提升开发效率。
Selenium主流 Web 自动化测试框架,支持跨浏览器(Chrome/Firefox/Safari)、多语言(Java/Python)。
WebDriverManager自动管理浏览器驱动,无需手动下载 / 配置chromedriver.exe,自动匹配版本,跨平台兼容(Windows/macOS/Linux)。

Selenium 是一款开源的 Web 自动化测试工具,支持跨浏览器(Chrome/Firefox/Safari 等)和多编程语言(Java/Python/C# 等),广泛用于 Web 应用的功能测试与回归测试。

IntelliJ IDEA 是一款由 JetBrains 公司开发的智能集成开发环境(IDE),专为 Java、Kotlin 以及多种其他编程语言设计。它具备智能代码补全、实时语法检查、高效调试等功能,还拥有丰富的插件生态。凭借强大的代码分析与重构能力,能显著提升开发效率,是开发者的得力助手。

四、 测试计划

4.1 测试用例

4.2 功能测试

4.2.1 各功能模块测试概述

功能测试概述
功能模块测试用例总数通过用例数失败用例数通过率
注册测试770100%
登录测试98188.9%

个人列表测试 

13130100%

博客编辑测试

76185.7%
主页测试660100%

4.2.2 详细测试结果

针对每个功能模块,详细描述测试过程中发现的问题,包括问题描述、出现的页面或操作步骤、预期结果、实际结果、问题严重程度(如严重、一般、轻微)和问题优先级(如高、中、低)。

(1)注册功能

        测试结果

测试结果
测试编号测试场景操作步骤预期结果实际结果是否符合预期问题描述(若不符)严重程度优先级
REG-01正常注册-跳转

1. 进入注册页面 

2. 用户名输入testuser01,密码和确认密码输入 123.com

3. 点击提交按钮

4. 弹窗点击确认按钮

1. 系统提示:恭喜:注册成功!是否要跳转到登陆页面?

2. 跳转到登录页面

1. 系统提示 “注册成功”;
2. 成功跳转到登录页面。
REG-02正常注册-不跳转

1. 进入注册页面 

2. 用户名输入testuser02,密码和确认密码输入 123.com

3. 点击提交按钮

4. 弹窗点击取消按钮

1. 系统提示:恭喜:注册成功!是否要跳转到登陆页面?

2. 在注册页面

1. 系统提示 “注册成功”;
2. 还在注册界面
REG-03用户名为空注册1. 进入注册页;
2. 用户名留空,密码输入123.com,确认密码输入 123.com;
3. 点击 “注册” 按钮。
系统提示 “请先输入用户名!”,注册失败,页面停留在注册页。提示 “请先输入用户名!”,注册失败,页面停留在注册页。
REG-04密码为空注册

1. 进入注册页;

2. 用户名输入testuser04,密码清空,确认密码清空;
3. 点击 “注册” 按钮。

系统提示 “请先输入密码!”,注册失败,页面停留在注册页。提示 “请先输入密码!”,注册失败,页面停留在注册页。
REG-05用户名已存在

1. 进入注册页;
2. 用户名输入已注册过的 admin,密码输入 123.com,确认密码输入 123.com
3. 点击 “注册” 按钮。

系统提示 “该用户已存在,请重新输入!”,注册失败。

系统提示 “该用户已存在,请重新输入!”,注册失败。

REG-06密码和确认密码不同1. 进入注册页;
2. 用户名输入 testuser06,密码输入 123.com,确认密码输入 123123;
3. 点击 “注册” 按钮。
系统提示 “两次密码不一致,请重新输入!”,注册失败。系统提示 “两次密码不一致,请重新输入!”,注册失败。
REG-07      退出注册按钮

1. 进入注册页;

2. 点击退出;

页面跳转到登录页面跳转到登录页面

        部分操作截图

 注册页面


                

REG-01


(2)登录功能
测试结果
测试编号测试场景操作步骤预期结果实际结果是否符合预期问题描述(若不符)严重程度优先级
LOG-01正常登录-跳转

1. 进入登录页面 

2. 用户名输入admin,密码输入 admin

3. 点击提交按钮

1. 系统验证通过,跳转到个人博客页

2. 页面显示用户信息和博客列表

1. 成功跳转到个人博客页;
2.显示用户名和博客信息。
LOG-02     用户名为空    

1. 进入登录页面 

2. 用户名清空,密码输入 admin

3. 点击提交按钮

1. 系统弹窗提示:请先输入用户名!

2. 页面停留在登录页

显示输入用户名弹窗,页面停留在登录页
LOG-03用户名不存在

1. 进入登录页面 

2. 用户名输入admin100,密码输入 admin

3. 点击提交按钮

1. 弹窗显示:用户名不存在,

2. 页面停留在登录页面

弹窗提示用户名或密码错误,与预期提示不符提示信息不准确,未明确指出用户名不存在一般
LOG-04密码错误

1. 进入登录页面 

2. 用户名输入admin,密码输入 admin123

3. 点击提交按钮

系统弹出提示框,显示 “用户名或密码错误”,页面停留在登录页。弹窗提示用户名或密码错误,页面停留在登录页
LOG-05点击注册1. 进入登录页面;
2. 点击 “注册” 按钮。
页面跳转到注册页面。页面成功跳转到注册页面。
LOG-06点击主页或 LOGO / 知我博客(未登录)1. 处于登录页面;
2. 点击主页链接、LOGO 或 “知我博客” 文字。
页面跳转到博客主页(未登录状态)。页面成功跳转到博客主页,显示未登录状态的内容。
LOG-07登录状态保持 - 长时间未操作后点击个人列表页1. 使用正确账号密码登录系统;
2. 等待超过系统设定的无操作时长;
3. 点击个人列表页链接;
页面跳转到登录页面。页面跳转到登录页面。
LOG-08强制登录 - 未登录访问编辑页1. 不进行登录操作;
2. 直接在地址栏输入编辑页的 URL 并访问。
页面跳转到登录页面。页面跳转到登录页面。
LOG-09强制登录 - 未登录访问个人编辑页1. 不进行登录操作;
2. 直接在地址栏输入个人编辑页的 URL 并访问。
页面跳转到登录页面。页面跳转到登录页面。

        操作截屏

登录界面

LOG-02:用户名为空 

LOG-03:用户名不存在

LOG-04: 密码错误

(3)个人博客页
测试结果
测试编号测试场景操作步骤预期结果实际结果是否符合预期问题描述(若不符)严重程度优先级
BLOG-01文章数验证1. 登录账号,进入个人博客页;
2. 查看页面显示的文章数。
显示的文章数与用户实际已发布的文章数量一致。页面显示文章数为 15,但实际用户已发布文章数为 15。
BLOG-02检验已发布文章标题、发布时间、摘要正常显示1. 登录账号,进入个人博客页;
2. 查看每篇已发布文章的标题、发布时间和摘要。
标题、发布时间和摘要没有乱码,正常显示。没有出现乱码
BLOG-03分页按钮 - 点击首页按钮1. 登录账号,进入个人博客页且当前不在第一页;
2. 点击 “首页” 按钮。
页面跳转到第一页。跳转到第一页
BLOG-04分页按钮 - 点击上一页按钮1. 登录账号,进入个人博客页且当前不在第一页;
2. 点击 “上一页” 按钮。
页面跳转到上一页。跳转到上一页
BLOG-05分页按钮 - 点击尾页按钮1. 登录账号,进入个人博客页且当前不在最后一页;
2. 点击 “尾页” 按钮。
页面跳转到最后一页。跳转到最后一页
BLOG-06分页按钮 - 点击下一页按钮1. 登录账号,进入个人博客页且当前不在最后一页;
2. 点击 “下一页” 按钮。
页面跳转到下一页。跳转到下一页
BLOG-07文章操作 - 点击查看全文按钮1. 登录账号,进入个人博客页;
2. 随机选择一篇文章,点击 “查看全文” 按钮。
页面跳转到博客详情页,显示文章标题、发布时间、内容、阅读量等信息。显示博客标题、发布时间、内容、阅读量
BLOG-08文章操作 - 点击修改文章按钮

1. 登录账号,进入个人博客页;
2. 随机选择一篇文章,点击 “修改文章” 按钮。

3. 修改文章标题和内容点击修改

4. 确认修改提示窗

1. 页面跳转到博客编辑页;

2. 显示文章的标题和内容

3. 修改后点击提交。

4. 文章标题和内容摘要展示在个人列表页。

5. 文章发布时间发生改变

1. 成功跳转到博客编辑页,成功显示文章标题和内容;

2. 个人列表页文章更新,发布时间更新

BLOG-09文章操作 - 点击删除文章按钮1. 登录账号,进入个人博客页;
2. 随机选择一篇文章,点击 “删除文章” 按钮;
3. 确认删除提示框。
文章从个人列表页删除。文章从个人列表页消失
BLOG-10点击我的主页1. 登录账号,进入个人博客页;
2. 点击 “我的主页” 按钮。
页面跳转到我的列表页第一页。跳转到我的列表页第一页
BLOG-11点击写博客1. 登录账号,进入个人博客页;
2. 点击 “写博客” 按钮。
页面跳转到博客编辑页。跳转到写博客页面,标题和内容为空
BLOG-12点击退出登录1. 登录账号,进入个人博客页;
2. 点击 “退出登录” 按钮。
退出登录状态,页面跳转到登录页面。退出登录状态,并跳转到登录页面
BLOG-13点击主页或 LOGO / 知我博客1. 登录账号,进入个人博客页;
2. 点击主页链接、LOGO 或 “知我博客” 文字。
页面跳转到主页(已登录状态)页面跳转到主页,登录状态

部分操作截屏

个人列表页


BLOG-02:检验已发布文章标题、发布时间、摘要正常显示


 

BLOG-08:文章操作 - 点击修改文章按钮


BLOG-07:文章操作 - 点击查看全文按钮

(4)文章编辑页
测试结果
测试编号测试场景操作步骤预期结果实际结果是否符合预期问题描述(若不符)严重程度优先级
EDIT-01标题 / 内容正常输入并发布1. 登录后进入编辑页;
2. 输入标题 “测试文章”,内容 “正文内容”;
3. 点击 “发布文章” 按钮。
1. 系统提示 “发布成功”;
2. 跳转至博客详情页,显示标题和内容。
发布成功,跳转至博客列表页,内容正确显示。发布成功后没有跳转到博客详情页一般
EDIT-02MarkDown 格式支持验证1. 在内容区输入 MarkDown 格式文本:# 一级标题\n- 列表项1\n[链接](https://example.com)
2. 发布后查看详情页。
详情页显示正确渲染的 MarkDown 内容:一级标题加粗、列表项缩进、链接可点击。详情页正确渲然MarkDown内容
EDIT-03标题为空发布1. 登录后进入编辑页;
2. 内容区输入 “正文内容”,标题留空;
3. 点击 “发布文章” 按钮。
系统提示 “标题不能为空”,阻止发布,页面停留在编辑页。提示:请先输入标题!页面停留在编辑页
EDIT-04内容为空发布1. 登录后进入编辑页;
2. 输入标题 “测试标题”,内容区留空;
3. 点击 “发布” 按钮。
系统提示 “请输入文章内容!”,阻止发布,页面停留在编辑页。提示:请输入文章内容!页面停留在编辑页
EDIT-05点击“我的主页”1. 登录账号,进入个人博客页;
2. 点击 “我的主页” 按钮。
页面跳转到我的列表页第一页。跳转到我的列表页第一页
EDIT-06点击“退出登录”1. 登录账号,进入个人博客页;
2. 点击 “退出登录” 按钮。
退出登录状态,页面跳转到登录页面。退出登录状态,并跳转到登录页面
EDIT-07点击主页或 LOGO / 知我博客1. 登录账号,进入个人博客页;
2. 点击主页链接、LOGO 或 “知我博客” 文字。
页面跳转到主页(已登录状态)页面跳转到主页,登录状态

部分操作截屏

博客编辑页


EDIT-02:MarkDown 格式支持验证


EDIT-04:内容为空发布


(5)主页
测试结果
测试编号测试场景操作步骤预期结果实际结果是否符合预期问题描述(若不符)严重程度优先级
MAIN-01文章标题 / 时间 / 摘要正常显示1. 进入主页面(未登录 / 已登录);
2. 查看所有显示的文章条目。
标题、发布时间、摘要无乱码,格式正确(如时间为 “YYYY-MM-DD HH:mm”,摘要截断合理)。所有文章没有乱码、时间格式也都正确
MAIN-02点击首页按钮

1. 进入主页面(未登录 / 已登录)且当前不存在第一页;

2. 点击首页按钮。

跳转到主页第一页成功跳转到第一页
MAIN-03点击上一页按钮

1. 进入主页面(未登录 / 已登录)且当前不在第一页;

2. 点击上一页按钮。

跳转到上一页成功跳转到上一页
MAIN-04点击尾页按钮

1. 进入主页面(未登录 / 已登录)且当前不在最后一页;

2. 点击尾页按钮。

跳转到尾页成功跳转到尾页
MAIN-05点击下一页按钮

1. 进入主页面(未登录 / 已登录)且当前不在最后一页;

2. 点击下一页按钮。

跳转到下一页成功跳转到下一页
MAIN-06点击查看全文按钮

1. 进入主页面(未登录 / 已登录);

2. 在主页面点击任意文章的 “查看全文” 按钮。

跳转至博客详情页,显示完整标题、发布时间、内容、阅读量正确显示标题、发布时间、内容、阅读量;

 部分操作截图

主页

MAIN-06: 点击查看全文按钮


4.3 自动化测试

4.3.1. 测试目标

  • 验证博客系统核心功能(注册 / 登录、文章发布 / 编辑 / 删除、页面跳转、)的稳定性与正确性。
  • 覆盖 前端交互逻辑 和 用户体验流程,减少人工回归测试成本,提升迭代效率。
  • 确保新功能开发或代码变更时,不破坏已有功能(冒烟测试、回归测试)。

4.3.2 自动化测试用例

4.3.3 环境准备

因篇幅有限:全部代码链接为:博客自动化测试完整代码

 1. 创建Maven项目并配置依赖

在IDEA中点击 File → New → Project ...→ Maven→next→输入项目名称和地址→Finish


2. 添加Maven依赖(pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>mycnblogTest</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><!-- 测试驱动下载 --><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></dependencies></project>

4.3.4 基础测试类 | Utils

说明:

  • 根据自动化测试用例来编写代码,每一个页面一个测试类,然后在各个测试中进行测试用例的编写。
  • 公共属性需要单独放一个类

------------------------------------------------------------------------------------

  • common
    • Utils.java                ——公共类,创建驱动对象、强制等待、处理弹窗、屏幕截图
  • tests
    • LoginPage.java                ——登录页面所有用例
    • RegistrationPage.java      ——注册页面所有用例
    • MyListPage.java               ——个人列表页面所有用例
    • DetailPage.java                ——详情页面所有用例
    • EditPage.java                   ——编辑页面所有用例
    • HomePage.java               ——主页所有用例
  • iamge  
    • 2025-04-10                      ——存放当天的屏幕截图

基础公共类中存放一些公共属性:loginUrl、driver;公共方法:屏幕截图、弹窗处理

创建驱动

    public Utils(String url){driver = createDriver();wait = new WebDriverWait(driver, Duration.ofSeconds(5));driver.get(url);}/*** 获取驱动对象* @return*/public static WebDriver createDriver(){if(driver == null){// 下载驱动WebDriverManager.chromedriver().setup();ChromeOptions options = new ChromeOptions();// 允许访问所以链接options.addArguments("--remote-allow-origins=*");// options.addArguments("-headless"); // 无头模式设置// 打开浏览器driver = new ChromeDriver(options);//  隐式等待driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));}return driver;}

屏幕截屏

    /*** 屏幕截图* @param funcName* @throws IOException*/public void getScreensShot(String funcName) throws IOException {// ./src/test/java/images/2025-04-05/test01_17553033.pngSimpleDateFormat sim1 = new SimpleDateFormat("yyyy-MM-dd");SimpleDateFormat sim2 = new SimpleDateFormat("HHmmssSS");String dirTime = sim1.format(System.currentTimeMillis());String fileTime = sim2.format(System.currentTimeMillis());String fileName = "./src/test/java/images/" + dirTime +  "/" + funcName + "_" + fileTime + ".png";File imageFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);FileUtils.copyFile(imageFile, new File(fileName));}

处理弹窗

    /*** 处理弹窗 点击确认* @param expectedMessage 期望的弹窗消息*/public static void handleAlertAccept(String expectedMessage) {// 切换到警告弹窗Alert alert = wait.until(ExpectedConditions.alertIsPresent());// 获取实际的弹窗消息String actualMessage = alert.getText();// 关闭弹窗alert.accept();// 断言实际消息与期望消息是否一致assert actualMessage.equals(expectedMessage) : "实际弹窗消息与期望消息不符。实际消息: " + actualMessage + ", 期望消息: " + expectedMessage;}/*** 处理弹窗 点击取消* @param expectedMessage 期望的弹窗消息*/public static void handleAlertDismiss(String expectedMessage) {// 切换到警告弹窗Alert alert = wait.until(ExpectedConditions.alertIsPresent());// 获取实际的弹窗消息String actualMessage = alert.getText();// 关闭弹窗alert.dismiss();// 断言实际消息与期望消息是否一致assert actualMessage.equals(expectedMessage) : "实际弹窗消息与期望消息不符。实际消息: " + actualMessage + ", 期望消息: " + expectedMessage;} 

4.3.4 登录页面测试 | LoginPage

登录页面测试:主要编写登录页面的测试用例、比如页面加载测试、正常登录、异常登录、注册/主页按钮测试

创建驱动访问登录页面

public class LoginPage extends Utils {public static String url = loginUrl;// 使用继承的方法实现访问urlpublic LoginPage(){super(url);}
}

正常登录:

    public void logined(String username, String password){// 清空账号、密码driver.findElement(By.xpath("//*[@id=\"username\"]")).clear();driver.findElement(By.xpath("//*[@id=\"password\"]")).clear();driver.findElement(By.xpath("//*[@id=\"username\"]")).sendKeys(username);driver.findElement(By.xpath("//*[@id=\"password\"]")).sendKeys(password);driver.findElement(By.xpath("//*[@id=\"submit\"]")).click();wait.until(ExpectedConditions.urlToBe(myListUrl));WebElement web = driver.findElement(By.xpath("//*[@id=\"username\"]"));String actualMsg = web.getText();// 断言实际消息与期望消息是否一致assert actualMsg.equals(username) :"实际用户名与期望用户名不符。实际用户名: " + actualMsg + ", 期望用户名: " + username ;}

用户名或密码错误测试

注:文本输入框进行输入内容前先清空;不然上一次用例的内容会影响这次用例的测试;博主这就踩坑了。

    // 用例4 账号错误 | 密码错误public void testWrongUserPwd(){// 清空账号、密码driver.findElement(By.xpath("//*[@id=\"username\"]")).clear();driver.findElement(By.xpath("//*[@id=\"password\"]")).clear();driver.findElement(By.xpath("//*[@id=\"username\"]")).sendKeys("admins");driver.findElement(By.xpath("//*[@id=\"password\"]")).sendKeys("1234567");driver.findElement(By.xpath("//*[@id=\"submit\"]")).click();// 强制等待弹窗出现wait.until(ExpectedConditions.alertIsPresent());// 处理错误的弹窗——警告弹窗String expectMsg = "用户名或密码错误!";handleAlertAccept(expectMsg);}

注册按钮点击测试

注意这种页面跳转测试,这种需要再一开始确保就在要测试的界面,不然会发现元素找不到,这可能是上一个用例跳转到了其他页面。

    // 用例8 点击注册public void loginPageRegClick(){driver.get(url);driver.findElement(By.xpath("/html/body/div[1]/a[3]")).click();// 通过URL检测是否跳转到注册页面verifyUrlRedirection(regUrl);}

4.3.5 注册页面测试:| RegistrationPage

注册页面测试类:进行注册检测(异常,正常情况)、退出注册页面验证等注册页面用例测试

创建驱动访问注册页面

public class RegistrationPage extends Utils {public static String url = regUrl;private LoginPage login = new LoginPage();public RegistrationPage() {super(url);}// 测试用例
}

账号、密码、确认密码为空注册测试

    public void empty(){// 清空操作clear();driver.findElement(By.xpath("//*[@id=\"submit\"]")).click();// 强制等待弹窗出现wait.until(ExpectedConditions.alertIsPresent());// 处理错误的弹窗——警告弹窗handleAlertAccept("请先输入用户名!");}

密码和确认密码为不同注册测试

    public void differentPwds(){// 清空操作clear();driver.findElement(By.xpath("//*[@id=\"username\"]")).sendKeys("admin4");driver.findElement(By.xpath("//*[@id=\"password\"]")).sendKeys("123456");driver.findElement(By.xpath("//*[@id=\"password2\"]")).sendKeys("123453");driver.findElement(By.xpath("//*[@id=\"submit\"]")).click();// 强制等待弹窗出现wait.until(ExpectedConditions.alertIsPresent());// 处理错误的弹窗——警告弹窗String expectMsg = "两次密码不一致,请重新输入!";handleAlertAccept(expectMsg);}

用户名已存在

    // 用例7: 用户名已存在注册测试public void existingUser(){// 清空操作clear();driver.findElement(By.xpath("//*[@id=\"username\"]")).sendKeys("admin");driver.findElement(By.xpath("//*[@id=\"password\"]")).sendKeys("123456");driver.findElement(By.xpath("//*[@id=\"password2\"]")).sendKeys("123456");driver.findElement(By.xpath("//*[@id=\"submit\"]")).click();// 强制等待弹窗出现wait.until(ExpectedConditions.alertIsPresent());// 处理错误的弹窗——警告弹窗String expectMsg = "该用户已存在,请重新输入!";handleAlertAccept(expectMsg);}

 成功注册测试、跳转到登录页面

注意:注册用户名需要不同,不然会下一次运行就出错了,这里可以使用时间戳。

    // 用例9: 成功注册测试、跳转到登录页面public void regSuc2(){driver.get(regUrl);clear();// 设计用户名String timestamp = new SimpleDateFormat("yyyyMMddHHmmssSS").format(System.currentTimeMillis());String userName = "user_" + timestamp;String password = "123.com";driver.findElement(By.xpath("//*[@id=\"username\"]")).sendKeys(userName);driver.findElement(By.xpath("//*[@id=\"password\"]")).sendKeys(password);driver.findElement(By.xpath("//*[@id=\"password2\"]")).sendKeys(password);driver.findElement(By.xpath("//*[@id=\"submit\"]")).click();// 显示等待弹窗出现wait.until(ExpectedConditions.alertIsPresent());// 关闭弹窗,跳转到登录页面handleAlertAccept("恭喜:注册成功!是否要跳转到登陆页面?");Alert alert = driver.switchTo().alert();alert.accept();// 检查当前页面是否还在注册页面verifyUrlRedirection(loginUrl);// 登录login.logined(userName, password);}

4.3.6 博客列表页测试 | MyListPage

博客列表页测试类:主要实现博客列表页的测试,例:博客列表显示、个人信息显示、分页按钮测试、查看文章测试等等;

创建驱动访问博客列表页

public class MyListPage extends Utils {private static final Logger LOGGER = Logger.getLogger(MyListPage.class.getName());public MyListPage() {super(myListUrl);}// 测试用例
}

分页按钮测试-上一页

    public void testPreviousPageButton(){// 获取当前URL中的页码参数int currentPage = getCurrentPage();WebElement prePageBtn = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id=\"artDiv\"]/div[2]/button[2]")));if(currentPage == 1){// 首页prePageBtn.click();// 等待弹窗的出现handleAlertAccept("当前已经在首页了");} else if (currentPage > 1){// 非首页情况prePageBtn.click();// 上一页URL匹配wait.until(ExpectedConditions.urlContains("pindex=" + (currentPage - 1)));int newPage = getCurrentPage();if(newPage != currentPage - 1){LOGGER.log(Level.SEVERE, "上一页跳转失败, 期望页码: " + (currentPage - 1) +", 实际页码: " + newPage);}}}

分页按钮测试-下一页

    // 用例6 分页按钮测试-下一页public void testNextPageButton() {String xpath = "//*[@id=\"artDiv\"]/div[2]/button[4]";int total = getTotalPages(xpath);// System.out.println("一共:" + totalPages + "页");int currentPage = getCurrentPage();WebElement nextPageBtn = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id=\"artDiv\"]/div[2]/button[3]")));if(currentPage == total){// 当前是尾页,点击下一页会有弹窗提醒nextPageBtn.click();handleAlertAccept("当前已经在尾页了");} else {// 非尾页情况nextPageBtn.click();// 跳转到下一页wait.until(ExpectedConditions.urlContains("pindex=" + (currentPage + 1)));int newPage = getCurrentPage();if(newPage != currentPage + 1){LOGGER.log(Level.SEVERE, "下一页跳转失败, 期望页码: " + (currentPage - 1) +", 实际页码: " + newPage);}}}

查看全文按钮测试

    // 用例7 查看全文按钮测试public void testViewFullTextButton(){driver.findElement(By.xpath("//*[@id=\"artList\"]/div[1]/div[4]/a[1]")).click();// 等待页面加载完成wait.until(ExpectedConditions.urlContains("blog_content.html"));// 验证页面是否加载了全文内容WebElement fullTextContent = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id=\"editorDiv\"]")));assert fullTextContent.isDisplayed() : "查看全文按钮测试失败: 全文内容未显示";}

4.3.7 博客主页测试 |  HomePage

HomePage类: 主要编写博客主页的测试用例,例:分页按钮检查、博客显示检查、登录和未登录不同检查。

验证已发布文章标题、发布时间、摘要正常显示

    public void testBlogListDisplay(){// 检查博客标题WebElement titleElement = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id=\"artList\"]/div[1]/div[1]")));assert titleElement.isDisplayed() : "文章标题未正常显示";// 检查博客发布时间WebElement timeElement = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id=\"artList\"]/div[1]/div[2]")));assert timeElement.isDisplayed() : "文章发布时间未正常显示";// 检查博客内容WebElement contentElement = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id=\"artList\"]/div[1]/div[3]")));assert contentElement.isDisplayed() : "文章内容未正常显示";}

登录时显示退出登录,未登录时显示登录按钮

    public void testLoginAndLoginOut(){// 检测登录按钮存在WebElement loginButton = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id=\"login-link\"]")));assert "登录".equals(loginButton.getText()) : "登录按钮显示异常";// 登录操作loginButton.click();wait.until(ExpectedConditions.urlToBe(loginUrl));LoginPage login = new LoginPage();login.loginSuc();wait.until(ExpectedConditions.urlToBe(myListUrl));// 检测退出登录按钮存在driver.get("http://localhost:8085/blog_list.html");wait.until(ExpectedConditions.urlToBe(homePageUrl));WebElement loginOutButton = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id=\"login-link\"]")));assert "退出登录".equals(loginOutButton.getText()) : "退出登录按钮显示异常";loginOutButton.click();handleAlertAccept("确认退出?");wait.until(ExpectedConditions.urlToBe(loginUrl));// 登录,便于后面测试login.loginSuc();}

4.3.8 博客详情页 | DetailPage

DetailPage类:主要编写博客详情页的测试用例, 例:文章展示是否正常、文章阅读量是否正常;

文章阅读量显示测试

    public void testArticleViewCount(){// 获取文章初始阅读量WebElement viewCountElement = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id=\"rcount\"]")));int initialViewCount = Integer.parseInt(viewCountElement.getText());driver.get(url);wait.until(ExpectedConditions.urlToBe(url));// 再次获取文章阅读量viewCountElement = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id=\"rcount\"]")));int currentViewCount = Integer.parseInt(viewCountElement.getText());assert currentViewCount == (initialViewCount + 1) : "文章阅读显示异常";}

4.3.9 博客编辑页 | WriteBlogPage

WriteBlogPage类:主要编写博客编辑页的测试用例,例如:编辑博客页能否正常打开,异常博客编写、正常博客编写并发布;

成功发布文章

注意:Markdown编辑器无法通过clear()来删除内容,可以通过键盘事件来模仿Ctrl+A+Delete;

  public void testArticleSuccessSubmit(){WebElement titleInput = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id=\"title\"]")));WebElement submitButton  = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("/html/body/div[2]/div[1]/button")));WebElement contentEditor = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id=\"editorDiv\"]/div[1]/div[6]/div[1]/div/div/div/div[5]/div/pre/span/span")));String title = "《解锁博客系统新体验:高效创作与个性化展示》";String content = "在当今数字化内容创作时代,博客已成为人们分享观点、交流思想的重要平台。你是否渴望在博客系统中轻松输出优质内容?如今的博客系统已实现 “质” 的飞跃,从编辑创作到展示分享,全方位助力你的内容之旅。\n" +"# 一、智能编辑:Markdown 加持,创作无忧\n" +"智能编辑器支持 Markdown 语法,让排版变得轻松快捷。无需复杂的操作,通过简单的符号和命令,就能快速完成标题、列表、链接、图片等元素的排版。无论是撰写技术文档,还是分享生活感悟,都能高效完成。而且,编辑器还具备自动保存功能,实时保存你的创作内容,告别意外丢失内容的烦恼,让你专注于创作本身。\n" +"# 二、个性模板:一键切换,风格随心\n" +"系统拥有丰富的模板库,无论是极简风、复古范,还是时尚潮流、文艺清新等风格,都能一键切换。你可以根据博客主题和个人喜好,选择最适合的模板,让你的博客独具风格,给读者带来全新的视觉体验。即使没有专业的设计技能,也能轻松打造出高颜值的博客页面。\n" +"# 三、高效管理:标签分类,精准查找\n" +"通过标签和分类管理功能,你可以对博客内容进行有序整理。给每篇文章添加合适的标签和分类,方便后续查找和管理。当积累了大量内容后,无论是自己回顾,还是读者搜索,都能快速定位到感兴趣的文章,大大提高了内容的查找效率。\n" +"# 四、智能推荐:精准推送,拓展阅读\n" +"更惊喜的是,系统还能根据用户浏览数据,运用智能算法精准推送感兴趣的文章。一方面,帮助作者扩大内容传播范围,让优质文章被更多人发现;另一方面,为读者提供个性化的阅读推荐,满足不同的阅读需求,拓展阅读视野,实现作者与读者之间的高效连接。\n" +"快来体验这款功能强大的博客系统,开启你的高效创作与精彩展示之旅,让每一次创作都能绽放光彩!";titleInput.sendKeys(title);Actions action = new Actions(driver);// 模拟全选操作(Ctrl + A) + Deleteaction.keyDown(contentEditor, Keys.CONTROL).sendKeys(contentEditor, "a").keyUp(contentEditor, Keys.CONTROL).sendKeys(contentEditor, Keys.DELETE).perform();action.sendKeys(contentEditor, content).perform();submitButton.click();// 处理|确认提交?|弹窗handleAlertAccept("确认提交?");// 处理 是否继续添加文章弹窗handleAlertDismiss("恭喜: 文章添加成功!是否继续添加文章?");wait.until(ExpectedConditions.urlToBe(myListUrl));// 通过标题验证是否添加成功WebElement currentTitleEle = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id=\"artList\"]/div[1]/div[1]")));String currentTitle = currentTitleEle.getText();assert currentTitle.equals(title) : "文章添加异常,期望标题: " + title + ", 实际标题: " + currentTitle;driver.quit();}

五、测试结论

5.1 测试通过情况总结

        经综合测试,个人博客系统未通过整体测试验收。目前存在多项严重问题:登录模块中,当用户名不存在时,系统无法明确提示用户,可能导致用户反复尝试却无法得知失败原因,影响注册登录流程;文章发布功能存在严重缺陷,成功发布后无法跳转至对应文章详情页,致使功能链路断裂,影响用户体验与使用效率 。

        同时,系统在界面、安全、兼容、易用及性能方面均存在风险:界面布局存在留白过多问题,影响美观与操作便利性;安全性方面存在漏洞,可能引发用户信息泄露或非法访问;兼容性不足,无法在多种浏览器、操作系统及设备上稳定运行;易用性存在缺陷,用户操作不便;性能表现不佳,无法满足高并发或复杂操作场景需求。以上问题将显著降低用户使用意愿,增加系统安全隐患,若投入使用,可能导致用户流失、数据安全事故及口碑受损等严重后果,需立即修复优化。

http://www.xdnf.cn/news/175699.html

相关文章:

  • 0804标星_复制_删除-网络ajax请求2-react-仿低代码平台项目
  • P1168 中位数
  • Node.js 应用部署:镜像体积优化与安全的多阶段构建探索
  • NGINX upstream、stream、四/七层负载均衡以及案例示例
  • C#通过NTP服务器获取NTP时间
  • 【有啥问啥】深入理解 Layer Normalization (LayerNorm):深度学习的稳定基石
  • Rabbit MQ的基础认识
  • Postman接口测试: postman设置接口关联,实现参数化
  • 泰迪杯实战案例超深度解析:基于多源数据的信用风险评估与反欺诈检测
  • 【深度学习】多头注意力机制的实现|pytorch
  • WEB安全--社会工程--SET钓鱼网站
  • maven相关概念深入介绍
  • 如何实现一个可视化的文字编辑器(C语言版)?
  • 【python】lambda用法(结合例子理解)
  • pyspark将hive数据写入Excel文件中
  • 「Mac畅玩AIGC与多模态03」部署篇02 - 在 Mac 上部署 Dify
  • Python中变量标识的本质
  • LVS--总结
  • Maven下载aspose依赖失败的解决方法
  • CSS 内容超出显示省略号
  • Netfilter 与struct nf_hook_ops 相关
  • “赛教融合”模式下的网络安全专业Python实训教学解决方案
  • 8.DJI-PSDK:一站式项目功能开发总结(空中气象站项目/激光甲烷检测项目)
  • [python] 基于WatchDog库实现文件系统监控
  • PySpark中DataFrame应用升阶及UDF使用
  • Cad求多段线中心点(顶点平均值) C#
  • 利用脚本搭建私有云平台,部署云平台,发布云主机并实现互连和远程连接
  • Arduino 入门学习笔记(五):KEY实验
  • 3G大一下安卓考核题解
  • 多节点同步协同电磁频谱监测任务分配方法简要介绍