基于SSM(Spring + Spring MVC + MyBatis)框架构建的个人博客系统,通过分层架构实现高效协作:Spring负责依赖注入与事务管理,Spring MVC处理HTTP请求分发,MyBatis完成数据持久化操作。系统包含以下核心功能模块:
1、系统核心页面与功能
-
用户登录页
- 支持账号密码认证,通过拦截器限制未登录用户访问其他页面。
- 集成Shiro框架实现密码加密(如MD5)与安全控制。
-
博客发表页
- 提供富文本编辑器(如百度UEditor)支持标题、内容编辑,需登录后操作。
- 发布时自动记录发布日期、时间、发布者信息。
-
博客编辑页
- 支持已发布博客的标题与内容修改,更新后保留原始发布时间。
- 前端验证必填字段,避免标题或内容为空提交。
-
博客列表页
- 分页展示所有用户发布的博客,按发布时间倒序排列(最新置顶)。
- 显示每篇博客的标题、发布日期、发布者及点击量统计。
-
博客详情页
- 展示博客完整内容,支持登录用户进行评论或删除操作。
- 提供“查看全文”入口,点击后跳转至详情页。
2、自动化测试核心内容(基于Selenium)
通过Selenium定位Web元素并模拟用户行为,覆盖以下测试场景:
-
用户登录验证
- 测试成功登录后跳转至列表页,以及异常登录(错误密码/空输入)的提示处理。
- 验证登录状态下的权限控制(如未登录禁止访问编辑页)。
-
博客内容操作
- 发布流程:模拟标题/内容输入、提交,验证发布后列表页实时更新。
- 编辑与删除:修改后检查更新时间不变性;删除后验证数据不可访问性。
- 详情页校验:对比列表页与详情页的标题、内容、发布者信息一致性。
-
系统功能完整性
- 统计用户信息展示准确性(如昵称、头像)。
- 验证博客数量同步更新,删除后列表项减少。
- 退出账号后重定向至登录页,会话终止。
关键技术与设计约束
- 数据库设计:采用MySQL,表结构包含用户表、博客表、评论表,遵循职责分离原则。
- 响应式前端:使用Bootstrap/Layui实现多设备适配。
- 测试缺陷:已知问题包括删除后URL残留访问风险、更新时间未刷新等,需进一步修复。
注:系统测试需结合隐式等待、页面截图(便于问题追踪)及参数化测试用例(提高覆盖率)。完整源码与环境配置(Idea/MySQL 5.7+/Tomcat)详见文献。
3、 测试内容
3.1 编写测试用例
设计测试用例一般从一下六个方面展开:功能测试,易用性测试,界面测试,性能测试,安全性测试以及兼容性测试。在博客系统中主要围绕功能性测试展开
3.2 执行测试用例
1、用户登陆界面
2、输入正确的账号密码
例如(账号:zhangsan 密码:123456)
预期结果成功登陆进入到主页面
3,输入错误的账号密码
2、博客主页
从图中我们可以看到用户的头像,文章数量,用户名,GitHub地址
3、 博客编辑/发布/删除
博客编辑
1,首先打开查看全文
进入到编辑的主界面
然后我们对标题和内容进行修改,然后点击更新文章
运行结果:
博客发布
博客删除
4、用户退出
3.3 自动化测试
3.3.1 WebDriverManager与Selenium类库安装说明
WebDriverManager 是一款自动化管理浏览器驱动的工具,专为简化Selenium测试框架的配置流程而设计。其核心价值在于通过自动处理浏览器驱动的下载、版本匹配及环境配置,显著提升自动化测试的效率和可靠性。
1、核心功能与优势
-
自动化驱动管理
- 版本兼容性:自动检测本地安装的浏览器版本(如Chrome/Firefox/Edge等),下载并配置对应的驱动程序(如chromedriver/geckodriver/msedgedriver)。
- 环境配置:自动设置系统环境变量(如
webdriver.chrome.driver
),无需手动指定驱动路径。 - 缓存机制:默认将驱动缓存于
~/.cache/selenium
,有效期内避免重复下载。
-
跨浏览器支持
兼容主流浏览器驱动管理:WebDriverManager.chromedriver().setup(); // Chrome WebDriverManager.firefoxdriver().setup(); // Firefox WebDriverManager.edgedriver().setup(); // Edge
2、安装方法(Python)
“Python项目”
通过pip
安装:
bash pip install selenium webdriver-manager
代码初始化示例:
from selenium import webdriverfrom webdriver_manager.chrome import ChromeDriverManagerfrom selenium.webdriver.chrome.service import Servicedriver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
3、技术价值
- 效率提升:消除手动下载驱动、匹配版本、配置路径的冗余操作。
- 版本同步:实时适配浏览器更新,避免因驱动版本过旧导致的兼容性问题。
- 跨平台支持:兼容Windows/macOS/Linux系统,适配CI/CD流水线环境。
注:对于企业级测试框架,建议结合
WebDriverManager
的高级配置项(如自定义缓存周期、私有镜像源)优化持续集成流程。
3.3.2 编写自动化测试脚本
3.3.2.1 Utils
import os
import datetime
import sysfrom selenium import webdriver
from selenium.webdriver.edge.service import Service
from webdriver_manager.microsoft import EdgeChromiumDriverManager#创建一个浏览器对象
class Driver:driver = ""def __init__(self):options = webdriver.EdgeOptions()self.driver = webdriver.Edge(service=Service(EdgeChromiumDriverManager().install()),options=options)self.driver.implicitly_wait(5)def getScreenShot(self):#创建屏幕截图#图片文件名称 2025-06-11-145333.png#图片路径: ../images/2025-06-11/2025-06-11-145333.pngdirname = datetime.datetime.now().strftime("%Y-%m-%d")if not os.path.exists("../images/" + dirname):os.makedirs("../images/" + dirname)#图片名称:2025-06-11-145333.png# filename = datetime.datetime.now().strftime("%Y-%m-%d-%H%M%S") + ".png"# 获取调用的方法名filename = sys._getframe().f_back.f_code.co_name + "-" + datetime.datetime.now().strftime("%Y-%m-%d-%H%M%S") + ".png"self.driver.save_screenshot("../images/" + dirname +"/" + filename)BlogDriver = Driver()
3.3.2.2 BlogLogin
import time
from selenium.webdriver.common.by import By
from common.Utils import BlogDriver#测试博客登陆页面
class BlogLogin:url = ""driver = ""def __init__(self):self.url="http://8.137.19.140:9090/blog_login.html"self.driver = BlogDriver.driverself.driver.get(self.url)#成功登录的测试用例def loginsuc(self):self.driver.find_element(By.CSS_SELECTOR, "#username").clear()self.driver.find_element(By.CSS_SELECTOR, "#password").clear()self.driver.find_element(By.CSS_SELECTOR,"#username").send_keys("zhangsan")self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("123456")self.driver.find_element(By.CSS_SELECTOR,"#submit").click()#通过对比成功登录后首页的名称来进行判断是否登陆成功# time.sleep(3)# self.driver.find_element(By.CSS_SELECTOR,"h3")# BlogDriver.getScreenShot()# self.driver.quit()# self.driver.back()#登陆失败的测试用例def loginfail(self):# 清空输入框self.driver.find_element(By.CSS_SELECTOR, "#username").clear()self.driver.find_element(By.CSS_SELECTOR, "#password").clear()# 输入正确账号+错误密码self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("zhangsan")self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("12345") # 错误密码# 点击登录 → 等待弹窗出现 → 关闭弹窗self.driver.find_element(By.CSS_SELECTOR, "#submit").click()time.sleep(3) # 等待3秒alert = self.driver.switch_to.alert # 获取弹窗alert.accept() # 点击弹窗的"确定"# 截图保存证据BlogDriver.getScreenShot()time.sleep(3)# login = BlogLogin()
# login.loginsuc()
# login.loginfail()
3.3.2.3 BlogDetail
from selenium.webdriver.common.by import Byfrom common.Utils import BlogDriver
import time#测试博客主页
class BlogDetail:url = ""driver = ""def __init__(self):self.url="http://8.137.19.140:9090/blog_list.html"self.driver = BlogDriver.driverself.driver.get(self.url)
#登陆状态下博客详情页测试def BlogDetailtest(self):#检查标题time.sleep(3)self.driver.find_element(By.CSS_SELECTOR, "div.title")#检查时间self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(1) > div.date")#检查内容self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div:nth-child(1) > div.desc")#检查用户名称self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > h3")#屏幕截图BlogDriver.getScreenShot()
3.3.2.4 BlogEdit
import timefrom selenium.webdriver.common.by import Byfrom common.Utils import BlogDriver
#测试博客编辑页面
class BlogEdit:url = ""driver = ""def __init__(self):self.url = "http://8.137.19.140:9090/blog_edit.html"self.driver = BlogDriver.driverself.driver.get(self.url)#正确发布博客(登陆状态下)def EditSucTestByLogin(self):self.driver.find_element(By.CSS_SELECTOR,"#title").send_keys("自动化测试创建")time.sleep(3)#找到编辑区域,输入关键词(编辑区域不可操作)#菜单栏无法元素无法定位#博客系统编辑区域默认情况下就不为空,可以暂不处理#直接点击发布按钮来发布博客self.driver.find_element(By.CSS_SELECTOR,"#submit").click()time.sleep(3)#点击完成之后出现页面的跳转,页面跳转需要加载时间,可能会出现代码执行的速度比页面渲染的速度要快,导致元素查找不到,因此可以添加等待#添加隐式等待和显示等待都可以,任选择一个#隐式等待:创建浏览器对象之后就可以加上,因为隐式等待的作用域在driver整个生命周期#显示等待:可以作用在当前代码中actual=self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div:nth-child(1) > div.title").text#assert actual == "自动化测试创建"#屏幕截图BlogDriver.getScreenShot()
3.3.2.5 testRun
from Tests import BlogDetail
from Tests import BlogLogin
from Tests import BlogEdit
import timefrom common.Utils import BlogDriver
if __name__ == '__main__':BlogLogin.BlogLogin().loginsuc()BlogLogin.BlogLogin().loginfail()BlogLogin.BlogLogin().loginsuc()BlogDetail.BlogDetail().BlogDetailtest()time.sleep(3)BlogLogin.BlogLogin().loginsuc()time.sleep(3)BlogEdit.BlogEdit().EditSucTestByLogin()BlogDriver.driver.quit()
工作目录: