news 2026/9/12 20:36:34

博客系统~~测试报告

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
博客系统~~测试报告

一、项目背景

本简易博客系统为面向个人用户的轻量化内容发布平台,主要支持用户注册登录、个人信息管理、博文编辑、草稿保存、文章发布与浏览、评论互动等核心功能,可满足个人日常博文记录、内容整理与分享的使用需求。为保障系统功能稳定、流程合规、交互正常,我独立负责本次系统全流程测试工作,覆盖功能、兼容性、接口、安全等多项测试维度,全面验证系统各项业务逻辑与使用场景,排查潜在缺陷,确保系统整体运行满足上线使用标准。

二、项目简介

2.1 核心业务模块

  1. 登录模块:账号密码登录;对空输入、错误账号密码、前后空格输入做校验
  2. 博客首页:展示全部已发布博文,展示博文标题、内容摘要
  3. 博文编辑模块:跳转编辑页面,填写博文标题、博文正文内容
  4. 博文发布模块:提交编辑内容完成发布,发布成功后博文同步展示到首页

2.2 测试环境

项目详情
被测系统简易博客 Web 端
浏览器Chrome 128
操作系统Windows11
手工测试工具Chrome 浏览器
自动化技术栈Python + Selenium
Bug 管理禅道(本地文档记录)
测试类型功能测试、UI 自动化测试、回归测试

三、测试计划

模块之间存在数据耦合(登录后才能编辑发布文章,发布的文章数据回显首页),采用整体提测,全部功能开发完成后统一进入测试;Bug 修复完成后执行全量回归测试。

功能模块后端开发前端开发提测日期测试人员测试开始时间测试完成时间测试结果
登录功能开发 A开发 B2026‑09‑12杨容2026‑09‑132026‑09‑13通过
博客首页开发 A开发 B2026‑09‑12杨容2026‑09‑142026‑09‑14通过
博文编辑功能开发 A开发 B2026‑09‑12杨容2026‑09‑152026‑09‑15通过
博文发布功能开发 A开发 B2026‑09‑12杨容2026‑09‑162026‑09‑16通过
全量回归测试开发 A开发 B2026‑09‑12杨容2026‑09‑172026‑09‑17通过

四、测试内容

手动对项目功能进行Web的基本功能测试

1.1 如何设计测试用例

设计设计测试用例一般从6个方面进行设计:

针对这套 Web 端简易博客系统设计测试用例时,我主要从六大测试维度开展设计,分别为功能测试、界面 UI 测试、性能测试、易用性测试、安全性测试以及兼容性测试。由于该项目属于个人 Web 博客站点,测试过程中会重点聚焦业务核心功能开展验证。

1.2设计个人博客系统测试用例思维导图如下:

基于个人博客系统的页面进行功能测试设计:

1.3登录模块

  • 正向:正确账号密码,登录成功跳转博客首页
  • 反向:账号为空;密码为空;账号错误;密码错误;账号密码前后带空格输入

1.4博客首页

  • 登录的博客首页正常展示标题、内容;多条博客正常列表展示

1.5博客编辑模块

执行多组边界输入测试:正常输入标题与正文、标题为空、正文为空、标题超长输入、特殊符号输入,系统各项校验逻辑符合需求,测试成功

1.6博客发布模块

对博客发布功能进行验证:完整填写标题与正文,博客可正常发布;当标题为空、正文为空时,系统触发校验,禁止提交发布;博客发布成功后,首页页面实时刷新,可展示刚新增的博文内容。

1.7博客退出模块

在博客列表页点击”退出“按钮之后,会跳转到博客登录界面,此时界面中的账号和密码输入框中的数据被清空,可以正常登录。

自动化对项目功能进行Web的基本功能测试

1.1配置运行环境

安装两个库(在命令行输入即可)

pip install webdriver-manager

pip install selenium

创建项目

解释器类型选择 Custom environment,单选框切换为 Select existing,可复用已装好的 selenium、webdriver-manager;Create a welcome script可以让项目干净一点

创建好一个新的项目后鼠标点击左上角的File选中里面的Steeings

如果Steeings里面没有两个库就点加号下载

选择下载就行了

添加好后再次查看就行

我们一共要测试五个页面:博客首页、登录页、列表页、详情页、编辑页。如果每个页面的测试脚本都重复写创建驱动、打开网址的代码,会反复创建浏览器驱动,浪费系统资源。 所以做了代码抽离:把驱动创建、页面访问这类通用逻辑放到common公共包;各个页面独立的测试用例代码,统一放在test测试包。

1.2创建驱动对象

commonUtils.py 文件中封装了Driver 工具类,该类中包含两个核心方法:

  1. 浏览器驱动初始化方法,用于创建 Chrome 浏览器驱动对象、设置隐式等待,统一完成浏览器启动配置;
  2. 自动截图方法,可自动创建日期命名的截图文件夹、根据测试方法名和系统时间生成截图文件,实现测试场景自动截图功能。
#创建一个浏览器对象 import os import datetime import sys from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager class Driver: driver="" def init(self): options = webdriver.ChromeOptions() self.driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()),options=options) self.driver.implicitly_wait(2) # 创建截图函数 def getScreeShot(self): # 首先在上一级路径创建一个文件夹,命名为:mage+当天的年月 # 创建之前判断文件夹是否存在 dirname = datetime.datetime.now().strftime("%Y-%m-%d") # 首先要判断dirname是否存在 if not os.path.exists("../mage/" + dirname): #os.mkdir("../mage/" + dirname) os.makedirs("../mage/" + dirname, exist_ok=True) # sys._getframe().f_back.f_code.co_name 获取调用函数的方法名字 # 图片名字Logintest-2025-3-23-123409 filename = sys._getframe().f_back.f_code.co_name + "-" + datetime.datetime.now().strftime( "%Y-%m-%d-%H-%M-%S") + ".png" # 利用驱动对象调用截图函数 self.driver.save_screenshot("../mage/" + dirname + "/" + filename) BlogDriver = Driver()

1.3博客登录自动化测试

BlogLogin测试文件

from selenium.webdriver.common.by import By import time from common.Utils import BlogDriver #测试登录页面 class BlogLogin: # url = "" # driver = "" def __init__(self): self.driver = BlogDriver.driver self.url = "http://47.108.157.13:9090/blog_login.html" self.driver.get(self.url) #成功登录的测试函数 def LoginSuess(self): #找到账号框并输入 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) #登录后截图 BlogDriver.getScreeShot() #登录后要核对用户基本信息看是否相同 #用户基本信息的昵称 name = self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > h3").text # 用户基本信息的文章 textq = self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)").text # 用户基本信息的分类 artilce = self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > div:nth-child(4) > span:nth-child(2)").text time.sleep(3) assert name == "zhangsan" assert artilce == "分类" assert textq =="文章" #登录完了回退登录页面 #self.driver.back() # 登录完了回退登录页面 self.driver.back() #登录失败函数 def LoginFail(self): # 输入框可能有账号密码,清空输入框 self.driver.find_element(By.CSS_SELECTOR, "#username").clear() self.driver.find_element(By.CSS_SELECTOR, "#password").clear() time.sleep(1) # 输入错误账号密码 self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("zhangsan1") self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("1234561") self.driver.find_element(By.CSS_SELECTOR, "#submit").click() time.sleep(2) # =========检验登录失败弹窗核心代码========= alert = self.driver.switch_to.alert # 切换到弹窗 print("弹窗提示文本:", alert.text) # 拿到弹窗文字,打印出来 # 断言:判断弹窗文字是不是预期的“用户不存在” assert alert.text == "用户不存在" alert.accept() # 点击弹窗的【确定】,关闭弹窗,才能继续后续操作 # 登录失败后截图 BlogDriver.getScreeShot() time.sleep(3) if __name__ == '__main__': BlogDriver.init() login = BlogLogin() login.LoginSuess() login.LoginFail()

Runtest文件

from common.Utils import BlogDriver from test import BlogLogin if __name__ == "__main__": BlogDriver.init() #先启动浏览器 login=BlogLogin.BlogLogin() login.LoginSuess()#登录成功 login.LoginFail()#登录失败

运行顺序是:

  1. BlogDriver.init()→ 启动 Chrome 浏览器,给BlogDriver.driver赋值成浏览器对象
  2. login=BlogLogin.BlogLogin()→ 进入 BlogLogin 构造方法,拿到已经启动好的 driver
  3. 执行 LoginSuess 登录成功用例
  4. 执行 LoginFail 登录失败用例

可以图片文件夹有图片

1.4博客页表自动化测试

Bloglist测试文件

import time from selenium.webdriver.common.by import By from common.Utils import BlogDriver class BlogList: def __init__(self): self.driver = BlogDriver.driver self.url = "http://47.108.157.13:9090/blog_list.html" self.driver.get(self.url) #登录状态博客列表页用例 def BlogLoginList(self): # 检查第一篇博客标题 self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(1) > 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.right > div:nth-child(1) > a") # 用户昵称 self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > h3") # 用户文章数量 self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)") # 用户分类数量 self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > div:nth-child(4) > span:nth-child(2)") # 截图 BlogDriver.getScreeShot() # 未登录状态访问列表页 def NotBlogLoginListTest(self): # 直接访问博客列表地址(此时浏览器没有登录cookie) self.driver.get("http://47.108.157.13:9090/blog_list.html") time.sleep(2) BlogDriver.getScreeShot() # 核心断言,验证跳转登录页面 assert "blog_login.html" in self.driver.current_url # 登录状态,测试注销退出功能 def QuitBlogLoginList(self): # 点击注销按钮 self.driver.find_element(By.CSS_SELECTOR, "body > div.nav > a:nth-child(6)").click() BlogDriver.getScreeShot() # 获取页面标题、url Quittitle = self.driver.title QuitUrl = self.driver.current_url print("页面标题:",Quittitle) print("页面地址:",QuitUrl) # 断言跳转登录页 assert Quittitle == "博客登陆页" assert QuitUrl == "http://47.108.157.13:9090/blog_login.html" # input输入框取值!!重点:要用get_attribute("value") Quitusername = self.driver.find_element(By.CSS_SELECTOR, "#username").get_attribute("value") Quitpassword = self.driver.find_element(By.CSS_SELECTOR, "#password").get_attribute("value") print("账号框内容:" + Quitusername) print("密码框内容:" + Quitpassword) assert Quitusername == "" assert Quitpassword == "" def QuitBlog(self): # 注销退出登录 # 假设页面上退出按钮id或者css选择器,你换成你页面真实的 time.sleep(1) self.driver.find_element(By.CSS_SELECTOR, "body > div.nav > a:nth-child(6)").click() time.sleep(1) # 断言:退出成功,跳转到登录页面 print("当前页面地址:", self.driver.current_url) assert "blog_login.html" in self.driver.current_url BlogDriver.getScreeShot() # 截图 time.sleep(2)

Runtest文件

from common.Utils import BlogDriver from test import BlogLogin from test import BlogList if __name__ == "__main__": BlogDriver.init() #先启动浏览器 login=BlogLogin.BlogLogin() login.LoginSuess()#登录成功 # login.LoginFail()#登录失败 # 2.登录成功后,校验博客列表页面元素 bloglist = BlogList.BlogList() bloglist.BlogLoginList() # 3.测试注销退出 bloglist.QuitBlogLoginList() # 4.注销之后,现在浏览器处于【未登录状态】,执行权限测试 bloglist.NotBlogLoginListTest()
  • BlogLoginList:登录成功后,查看列表页面元素展示是否正常
  • NotBlogLoginListTest未登录直接访问列表页面,测试权限拦截
  • QuitBlogLoginList登录后执行退出,校验注销功能
函数前置状态测试目的
BlogLoginList✅已登录,停留在博客列表页校验博客列表页面 UI 元素正常渲染:博客标题、发布时间、博文简介、查看全文按钮、用户昵称、文章 / 分类数量正常展示
NotBlogLoginListTest❌无登录态,直接访问列表 URL权限控制测试:测试未登录的用户直接输入博客列表地址,校验系统能不能拦截,自动跳到登录页面。
QuitBlogLoginList✅已登录,停留在博客列表页注销功能测试:点击注销按钮,验证登录态清除、页面成功跳转登录页,登录表单输入框清空

1.4博客详情页面自动化测试

Blogdtail

import time from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from common.Utils import BlogDriver class BlogDetail: # driver = "" # url = "" def __init__(self): self.driver = BlogDriver.driver # 一篇博客的url self.url = "http://47.108.157.13:9090/blog_detail.html?blogId=127" self.driver.get(self.url) def BlogLoginDetailTest(self): time.sleep(2) # 检查一下博客的标题是否存在 self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div > div.title") # 检查一下发布博客的时间是否存在 self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div > div.date") # 检查一下博客的内容是否存在 self.driver.find_element(By.CSS_SELECTOR, "#detail") # 检查一下用户基本信息的昵称是否存在 self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > h3") # 检查一下用户基本信息的文章是否存在 self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)") # 检查一下用户基本信息的分类是否存在 self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > div:nth-child(4) > span:nth-child(2)") # 检查一下编辑按钮是否存在 self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div > div.operating > button:nth-child(1)") # 检查一下删除按钮是否存在 self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div > div.operating > button:nth-child(2)") # 添加屏幕截图 BlogDriver.getScreeShot() time.sleep(2)

Runtest文件

from common.Utils import BlogDriver from test import BlogLogin from test import BlogDtail #from test.BlogDtail import BlogDtail if __name__ == "__main__": BlogDriver.init() #先启动浏览器 login=BlogLogin.BlogLogin() login.LoginSuess()#登录成功 # login.LoginFail()#登录失败 blogdtail=BlogDtail.BlogDetail() blogdtail.BlogLoginDetailTest()

BlogLoginDetailTest已登录,在博客列表页面点击博文进入详情页,校验博客标题、发布时间、正文、编辑、删除按钮正常展示

1.6博客编辑自动化

Blogedit

import time from selenium.webdriver.common.by import By from common.Utils import BlogDriver class BlogEdit: driver = "" url = "" def __init__(self): self.driver = BlogDriver.driver # 博客编辑/新增博文页面 self.url = "http://47.108.157.13:9090/blog_edit.html" self.driver.get(self.url) def BlogLoginEditTest(self): # 登录状态:新增一篇博客,填写标题 self.driver.find_element(By.CSS_SELECTOR, "#title").send_keys("自动化测试") # 富文本编辑器菜单栏为第三方组件,暂时不做元素校验 time.sleep(1) BlogDriver.getScreeShot() # 点击发布文章按钮 self.driver.find_element(By.CSS_SELECTOR, "#submit").click() # 等待页面跳转完成,防止代码执行快于页面加载导致元素定位失败 time.sleep(1) # 获取跳转后的页面地址,校验是否成功跳转到博客列表页 jumpurl = self.driver.current_url print(jumpurl) assert jumpurl == "http://47.108.157.13:9090/blog_list.html" # 获取列表第一条博文标题,校验刚刚发布的文章成功展示 articl = self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(1) > div.title").text print(articl) assert articl == "自动化测试" def NotBlogLoginEditTest(self): #清空cookie,模拟全新未登录用户 self.driver.delete_all_cookies() print("访问编辑页后实际url:", self.driver.current_url) # 权限控制测试:未登录用户直接访问博客编辑页面URL self.driver.get("http://47.108.157.13:9090/blog_edit.html") time.sleep(1) BlogDriver.getScreeShot() # 断言:未登录访问编辑页,系统拦截并自动跳转登录页面 assert "blog_login.html" in self.driver.current_url # 判断当前浏览器地址里面, ** 是否包含blog_login.html **。 # 如果包含 → 断言通过(符合预期,权限拦截生效) # 如果不包含 → 断言报错(BUG!没拦住,未登录直接进到编辑页面了)

Runtest

from common.Utils import BlogDriver from test import BlogLogin from test import Blogedit #from test.BlogDtail import BlogDtail if __name__ == "__main__": BlogDriver.init() #先启动浏览器 login=BlogLogin.BlogLogin() login.LoginSuess()#登录成功 # login.LoginFail()#登录失败 # 新增:博客编辑发布 blogedit = Blogedit.BlogEdit() blogedit.BlogLoginEditTest()
函数前置状态测试目的
BlogLoginEditTest✅已登录,进入博文编辑页新增博客文章,填写标题并发布;校验发布成功后跳转列表页,列表展示新发布文章
NotBlogLoginEditTest❌无登录态,直接访问编辑页 URL验证未登录用户访问博文编辑页面时,系统是否强制拦截,并自动跳转至登录页面

1.7全量回归测试

from common.Utils import BlogDriver from test import BlogLogin from test import BlogList from test import BlogDtail from test import Blogedit if __name__ == "__main__": # 初始化浏览器 BlogDriver.init() print("=====开始执行全量回归测试=====") #1.登录模块 login=BlogLogin.BlogLogin() login.LoginSuess() #2.博客列表模块 bloglist = BlogList.BlogList() bloglist.BlogLoginList() #3.博客详情模块 blogdetail = BlogDtail.BlogDetail() blogdetail.BlogLoginDetailTest() #4.博文编辑发布模块 blogedit = Blogedit.BlogEdit() blogedit.BlogLoginEditTest() #5.注销退出 bloglist.QuitBlog() #6.权限控制测试(2个页面未登录拦截) bloglist.NotBlogLoginListTest() blogedit.NotBlogLoginEditTest() print("=====全量回归测试执行完毕,全部用例通过=====") BlogDriver.driver.quit()
登录 → 列表 → 详情 → 发布文章 → 注销(页面跳登录页) →【执行权限用例前,delete_all_cookies 清空cookie】 → 未登录访问列表页 →【delete_all_cookies 清空cookie】 → 未登录访问编辑页

全量回归测试将博客系统所有核心业务流程串联,覆盖正向业务场景与权限逆向场景,一次性执行整套自动化用例。

执行顺序:登录系统 → 进入博客列表 → 查看博文详情 → 编辑发布新博客→ 执行账号注销,页面跳转至登录页面。

关键要点:仅页面跳转登录无法清除浏览器会话 Cookie,会导致权限用例误判。因此执行逆向权限用例前,调用delete_all_cookies()清空 Cookie,模拟完全未登录的访客环境。 接着执行两条权限校验用例:

  1. 无登录态直接访问博客列表页,验证系统强制拦截,自动跳转登录页面
  2. 无登录态直接访问博文编辑页,验证系统强制拦截,自动跳转登录页面

所有用例执行完毕,关闭浏览器,自动化全量回归结束

五、BUG 统计简述

Bug 标题Bug 等级报告人是否修复
文章标题输入超长字符无校验提示,可直接提交P2(一般)测试人员已修复
登录账号密码首尾空格未做过滤,带空格可以登录成功P2(一般)测试人员已修复

Bug 级别统计:

  • P0(崩溃阻断):0
  • P1(严重):0
  • P2(一般):2 个

本次测试总共发现 2 个一般级别 bug,无阻断上线 bug;开发全部修复完成,手工 + 自动化回归验证 bug 修复有效。

六、遗留问题

本次迭代版本无遗留问题; 后续优化方向:后续版本迭代可以扩展自动化脚本,增加更多异常场景自动化用例。

七、测试结论

  1. 简易博客系统完成手工功能测试 + UI 自动化测试 + 全量回归测试
  2. 手工测试执行 32 条功能用例;自动化脚本实现 5 条核心业务用例,覆盖登录、编辑、发布博文完整链路;
  3. 发现 bug 共 2 个,P2 级别,全部修复完成并回归验证;不存在 P0、P1 阻断类缺陷;
  4. 系统登录、浏览博文、编辑发布博文核心业务满足需求,测试通过,可以上线
  5. 自动化脚本可用于后续版本快速回归,提升测试效率。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 20:35:54

CookLikeHOC 蒸菜实战:凤爪蒸豆米的标准化复刻配方与蒸制工艺拆解

CookLikeHOC 蒸菜实战:凤爪蒸豆米的标准化复刻配方与蒸制工艺拆解 【免费下载链接】CookLikeHOC 🥢像老乡鸡🐔那样做饭。已添加2026年发布的《老乡鸡菜品溯源报告 2.0中新出现的菜品。主要部分于2024年完工,非老乡鸡官方仓库。文字…

作者头像 李华
网站建设 2026/9/12 20:34:18

分页组件 + el-config-provider 中文国际化 + 靠右布局

完整讲解:分页组件 el-config-provider 中文国际化 靠右布局需求回顾 封装公共分页组件 CommonPagination.vue分页文字中文(共 xx 条、每页、前往)分页整体靠右展示Vue3 Element Plus Vite 按需引入,JS 版本和我们之前 useTab…

作者头像 李华
网站建设 2026/9/12 20:33:23

海洋主题酒馆设计:空间叙事与光影技术解析

1. 项目背景与概念解析"5章鱼酒馆 - 海上明月"这个充满诗意的标题背后,隐藏着一个将海洋元素与餐饮空间完美融合的设计理念。作为一名有十年空间设计经验的设计师,我理解这类项目需要兼顾主题性、功能性和艺术表现力。章鱼作为海洋智慧生物的代…

作者头像 李华
网站建设 2026/9/12 20:32:17

给 kkFileView 接上人大金仓:备份链路一次跑通

给 kkFileView 接上人大金仓:备份链路一次跑通 【免费下载链接】kkFileView Universal File Online Preview Project based on Spring-Boot 项目地址: https://gitcode.com/GitHub_Trending/kk/kkFileView kkFileView 是 Spring Boot 做的在线预览服务&#…

作者头像 李华
网站建设 2026/9/12 20:29:21

从机房到云端,打通 SAP HANA 本地数据库与 SAP HANA Cloud 自助迁移通道

真正开始把一套 SAP HANA Platform 本地数据库迁往 SAP HANA Cloud 时,很多团队最早遇到的障碍往往不是数据量,也不是表结构兼容性,而是一件看起来很基础的事情,SAP 云端的迁移服务究竟怎样安全地访问企业内网里的那套 HANA 数据库。 这件事情如果只看表面,很容易被理解成…

作者头像 李华