目录
[2.1 系统概述](#2.1 系统概述)
[2.2 测试项目范围](#2.2 测试项目范围)
[3.1 测试目标](#3.1 测试目标)
[3.2 测试策略](#3.2 测试策略)
[4.1 测试工具配置](#4.1 测试工具配置)
[4.2 测试环境详情](#4.2 测试环境详情)
[7.1 自动化测试代码结构图](#7.1 自动化测试代码结构图)
[7.2 自动化测试代码脚本](#7.2 自动化测试代码脚本)
[1. common 包](#1. common 包)
[2. tests 包](#2. tests 包)
[8.1 登录测试截图](#8.1 登录测试截图)
[8.2 博客功能测试截图](#8.2 博客功能测试截图)
一、项目背景
随着互联网技术的快速发展,博客系统已成为个人和企业展示知识、分享经验的重要平台。对于我们在博客系统当中我们可以将自己日常学习的知识等编写为博客,这样就可以让我们来更好的复习。为确保博客系统的稳定性、功能完整性和用户体验,本项目对基于Web的博客系统进行了全面的自动化测试。
系统链接: http://47.108.157.13:8090/blog_login.html
二、项目简介
博客系统是一个Web应用程序,主要功能包括:
-
用户登录/注销
-
博客列表浏览
-
博客详情查看
-
博客创建与编辑
-
博客删除操作

2.1 系统概述
该博客系统是一个Web程序,主要功能包括:
1.用户登录/注销
2.博客列表浏览
3.博客详情查看
4.博客创建与编辑
5.博客删除操作
2.2 测试项目范围
本次自动化测试覆盖以下模块:
-
用户认证模块:登录功能的正向和异常场景测试
-
博客列表模块:不同用户状态下的列表展示测试
-
博客详情模块:博客查看、编辑和删除操作测试
-
博客编辑模块:博客创建和编辑功能测试
三、测试计划
3.1 测试目标
|----------|---------------------------------------|-----------------------------------------|
| 测试目标 | 详细描述 | 测试重点 |
| 功能验证 | 确保各功能模块符合需求规格说明,包括用户认证、博客管理、内容展示等核心功能 | • 登录功能的正确性 • 博客增删改查功能完整性 • 界面元素存在性和可操作性 |
| 流程测试 | 验证核心业务流程的完整性和正确性,确保用户从登录到系统使用的全流程畅通 | • 用户登录→博客列表→博客详情→编辑/删除的完整流程 • 异常流程处理机制 |
| 异常测试 | 验证系统在异常情况下的处理能力,包括错误输入和非法操作 | • 边界值测试 • 无效数据输入 • 异常操作场景 |
3.2 测试策略
|----------|---------|----------------|----------------------------------------------------------------------|
| 测试类型 | 测试方法 | 覆盖范围 | 具体实施 |
| 功能测试 | 自动化脚本执行 | 所有核心功能模块 | • 使用Selenium WebDriver编写测试脚本 • 覆盖登录、博客列表、博客详情、博客编辑四个模块 • 设计正向和负向测试用例 |
| 界面测试 | 页面元素验证 | 页面布局、交互元素 | • 验证页面元素存在性(标题、按钮、输入框等) • 验证元素可交互性(点击、输入等) • 截图对比关键页面状态 |
| 流程测试 | 业务流程模拟 | 用户注册到系统使用的完整流程 | • 模拟用户完整操作流程 • 验证流程中页面跳转的正确性 • 测试流程中的异常中断处理 |
| 异常测试 | 异常数据输入 | 边界值、无效数据、异常操作 | • 测试空输入、错误格式输入 • 测试超长字符串输入 • 测试重复操作、非法操作场景 • 验证异常提示信息准确性 |
四、测试工具与环境
4.1 测试工具配置
|--------------------|-------------|-------------|
| 工具/框架 | 版本/配置 | 用途 |
| Python | 3.14 | 测试脚本开发语言 |
| Selenium WebDriver | 4.0.0 | 浏览器自动化框架 |
| ChromeDriver | 与Chrome版本匹配 | Chrome浏览器驱动 |
| webdriver-manager | 4.0.2 | 自动管理浏览器驱动 |
| 操作系统 | Windows 11 | 测试执行环境 |
4.2 测试环境详情
|-------|-------------------------------------------------------------------------------------|
| 环境类型 | 配置详情 |
| 测试服务器 | http://47.108.157.13:8090 |
| 浏览器 | Chrome 100+ |
| 测试数据 | 预定义用户:zhangsan(123456), lisi(123456) |
| 网络环境 | 稳定的互联网连接 |
| 分辨率 | 2800×1800 |
五、性能测试覆盖
注:本次测试主要关注功能测试,性能测试暂未包含在自动化测试范围内。建议后续版本增加以下性能测试:
页面加载时间测试
并发用户登录测试
大数据量博客列表加载测试
API响应时间测试
六、自动化测试用例

七、自动化测试代码结构
7.1 自动化测试代码结构图
python
博客系统自动化测试项目/
├── Common/
│ │
│ └── Utils.py # 驱动管理、截图工具
├── tests/
│ │
│ ├── BlogLogin.py # 登录测试类
│ ├── BlogList.py # 博客列表测试类
│ ├── BlogDetail.py # 博客详情测试类
│ └── BlogEdit.py # 博客编辑测试类
├── images/ # 自动生成的截图目录
│ └── 2025-12-08/ # 按日期分类
│
└── runtest.py # 测试执行入口
7.2 自动化测试代码脚本
1. common 包
Utils.py - 核心工具类
import datetime
import os
import sys
from os.path import dirname
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):
dirname=datetime.datetime.now().strftime("%Y-%m-%d")
if not os.path.exists("../images/"+dirname):
os.mkdir("../images/"+dirname)
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()
2. tests 包
BlogLogin.py - 登录测试类
python
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from Common.Utils import BlogDriver
class BlogLogin:
url=""
driver=""
def __init__(self):
self.url="http://47.108.157.13:8090/blog_login.html"
self.driver=BlogDriver.driver
self.driver.get(self.url)
#登录成功
def LogSucTest(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()
self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > h3")
#self.driver.quit()
# time.sleep(1)
BlogDriver.getScreeShot()
#切换为上一个页面
# self.driver.back()
# time.sleep(2)
#密码错误登录失败
def LoginFailByPassword(self):
wait=WebDriverWait(self.driver,3)
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("1234567")
self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
wait.until(EC.alert_is_present())
#检测是否出现提示弹窗
alert=self.driver.switch_to.alert
assert alert.text=="密码错误"
alert.accept()
BlogDriver.getScreeShot()
#用户名和密码都是错误登录失败
def LoginFail(self):
wait=WebDriverWait(self.driver,3)
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("zhangsanq")
self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("1234567")
self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
wait.until(EC.alert_is_present())
#检测是否出现提示弹窗
alert=self.driver.switch_to.alert
assert alert.text=="用户不存在"
alert.accept()
BlogDriver.getScreeShot()
#用户不存在登录失败
def LoginFailByName(self):
wait=WebDriverWait(self.driver,3)
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("zhangsanq")
self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("123456")
self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
wait.until(EC.alert_is_present())
#检测是否出现提示弹窗
alert=self.driver.switch_to.alert
assert alert.text=="用户不存在"
alert.accept()
BlogDriver.getScreeShot()
#用户名和密码为空登录失败
def LoginFailByEmpty(self):
wait = WebDriverWait(self.driver, 3)
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("")
self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
wait.until(EC.alert_is_present())
# 检测是否出现提示弹窗
alert = self.driver.switch_to.alert
assert alert.text == "账号或密码不能为空"
alert.accept()
BlogDriver.getScreeShot()
BlogList.py - 博客列表测试类
python
from selenium.webdriver.common.by import By
from Common.Utils import BlogDriver
class Bloglist:
url=""
driver=""
def __init__(self):
self.url="http://47.108.157.13:8090/blog_list.html"
self.driver=BlogDriver.driver
self.driver.get(self.url)
#登录状态
def ListTestBylogin(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")
BlogDriver.getScreeShot()
#未登录状态
def ListTestFail(self):
self.driver.find_element(By.CSS_SELECTOR, "body > div.nav > a:nth-child(6)").click()
self.driver.find_element(By.CSS_SELECTOR,"body > div.container-login > div > h3")
BlogDriver.getScreeShot()
BlogDetail.py - 博客详情测试类
python
from selenium.webdriver import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from Common.Utils import BlogDriver
class BlogDetail:
url=""
driver=""
def __init__(self):
self.url="http://47.108.157.13:8090/blog_list.html"
self.driver=BlogDriver.driver
self.driver.get(self.url)
self.wait = WebDriverWait(self.driver, 3)
def DetailTestSuc(self):
#进入到一篇博客的详情页
self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div:nth-child(1) > a").click()
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,"#h2-u5728u8FD9u91CCu5199u4E0Bu4E00u7BC7u535Au5BA2")
botton=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)")
# botton.send_keys(Keys.CONTROL + 'a')
BlogDriver.getScreeShot()
#进入到编辑页面
botton.click()
self.driver.find_element(By.CSS_SELECTOR,"#title").send_keys(Keys.CONTROL + 'a')
self.driver.find_element(By.CSS_SELECTOR,"#title").send_keys(Keys.DELETE)
self.driver.find_element(By.CSS_SELECTOR,"#title").send_keys("自动化测试001")
BlogDriver.getScreeShot()
self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
self.wait.until(EC.element_to_be_clickable(
(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(1) > a")
))
self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(1) > a").click()
#重新进入到博客的详细页同时进行删除操作
self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div > div.operating > button:nth-child(2)").click()
self.wait.until(EC.alert_is_present())
alert = self.driver.switch_to.alert
alert.accept()
BlogDriver.getScreeShot()
BlogEdit.py - 博客编辑测试类
python
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 BlogEdit:
url=""
driver=""
def __init__(self):
self.url="http://47.108.157.13:8090/blog_edit.html"
self.driver=BlogDriver.driver
self.driver.get(self.url)
self.wait = WebDriverWait(self.driver, 3)
def EditTestSuc(self):
#进行博客标题的编写
self.driver.find_element(By.CSS_SELECTOR,"#title").send_keys("自动化构建测试")
self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
#查看是否返回到主页面当中
self.wait.until(EC.element_to_be_clickable(
(By.CSS_SELECTOR,"body > div.container > div.left > div > a")
))
actual=self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > a").text
assert actual=="GitHub 地址"
BlogDriver.getScreeShot()
八、测试执行截图
8.1 登录测试截图
-
正常登录成功

-
异常登录-密码错误

-
异常登录-用户不存在

-
异常登录-空输入

8.2 博客功能测试截图
-
博客列表页(登录状态)

-
博客编辑功能

-
博客详情编辑

九、缺陷报告
|---------|----------------------|------|-----|
| 缺陷ID | 缺陷标题 | 严重程度 | 状态 |
| DEF-001 | 博客创建成功后无成功提示信息 | 中 | 待修复 |
| DEF-002 | 新创建的博客显示在列表末尾不符合用户预期 | 中 | 待修复 |
| DEF-003 | 博客列表一次性加载所有数据,影响页面性能 | 高 | 待修复 |
DEF-001
博客创建成功后无成功提示信息
|----------|--------------------------------------------------------------------------------------------|
| 字段 | 内容 |
| 缺陷ID | DEF-001 |
| 缺陷标题 | 博客创建成功后无成功提示信息 |
| 严重程度 | 中 |
| 优先级 | 中 |
| 缺陷类型 | 功能缺陷 |
| 发现版本 | V1.0 |
| 发现环境 | 测试环境 (http://47.108.157.13:8090) |
| 发现日期 | 2025-12-10 |
缺陷描述
用户在创建或编辑博客后,系统自动跳转到博客列表页面,但未显示任何操作成功的提示信息。这导致用户无法确认操作是否成功执行,降低了用户体验的友好性。
复现步骤
1.登录系统(用户名:zhangsan,密码:123456)
2.点击"写博客"进入博客编辑页面
3.输入博客标题和内容
4.点击"发布"按钮
5.系统跳转到博客列表页面
实际结果:页面无任何成功提示信息
预期结果:应显示"博客发布成功"或类似提示信息
DEF-002
新创建的博客显示在列表末尾不符合用户预期
|----------|--------------------------------------------------------------------------------------------|
| 字段 | 内容 |
| 缺陷ID | DEF-002 |
| 缺陷标题 | 新创建的博客显示在列表末尾不符合用户预期 |
| 严重程度 | 中 |
| 优先级 | 中 |
| 缺陷类型 | 功能缺陷/逻辑缺陷 |
| 发现版本 | V1.0 |
| 发现环境 | 测试环境 (http://47.108.157.13:8090) |
| 测试人员 | 测试工程师 |
| 发现日期 | 2025-12-12 |
缺陷描述
新创建的博客被添加到博客列表的末尾,而不是按照常见的"最新优先"原则显示在列表顶部。这不符合大多数博客系统的用户习惯,也不利于用户查找最新内容。
复现步骤
1.登录系统(用户名:zhangsan,密码:123456)
2.查看当前博客列表,记录第一篇博客标题
3.创建一篇新博客,标题为"测试新博客"
4.发布后返回博客列表页面
实际结果:新创建的博客显示在列表最底部
预期结果:新创建的博客应显示在列表最顶部(按时间倒序排列)
DEF-003
博客列表一次性加载所有数据,影响页面性能
|----------|--------------------------------------------------------------------------------------------|
| 字段 | 内容 |
| 缺陷ID | DEF-003 |
| 缺陷标题 | 博客列表一次性加载所有数据,影响页面性能 |
| 严重程度 | 高 |
| 优先级 | 高 |
| 缺陷类型 | 性能缺陷 |
| 发现版本 | V1.0 |
| 发现环境 | 测试环境 (http://47.108.157.13:8090) |
| 发现日期 | 2025-12-13 |
缺陷描述
博客列表页面一次性加载所有博客数据,当博客数量较多时会导致:页面加载时间显著延长,浏览器内存占用增加,用户体验下降。
复现步骤
1.登录系统
2.创建超过20篇博客(模拟大量数据场景)
3.访问博客列表页面
4.使用浏览器开发者工具监控网络请求和加载时间
实际结果:一次性加载所有博客数据,页面加载缓慢
预期结果:应采用分页或懒加载技术分批加载数据
十、测试结论
本次博客系统自动化测试按照既定的测试计划和策略。测试中针对系统的核心功能模块进行了完整的自动化测试验证,覆盖了用户登录、博客列表展示、博客详情查看、博客创建与编辑等主要功能场景。
测试过程中,我们严格按照测试用例设计原则,采用Selenium WebDriver框架编写了12个自动化测试脚本,执行了正向功能和异常场景测试,确保系统在不同使用场景下的稳定性和可靠性。测试过程中累计生成截图为问题定位和验证提供了有力支持。
通过本次测试,我们验证了系统基础功能的可用性,同时发现了3个影响用户体验和系统性能的缺陷,为系统的质量提升提供了明确方向。
**通过本次自动化测试,博客系统的核心功能基本满足上线要求,但是还是纯在一定的性能缺陷。**建议在下一版本迭代中修复,提高系统执行的效率。