目录
一、引言
在软件测试领域,自动化测试凭借其高效、可重复的优势,成为保障项目质量的重要手段。本文将以博客系统为实际案例,实现自动化测试,从测试用例设计、脚本开发到测试报告补充,完整拆解 C++ 方向 Web 自动化测试的实施流程。
二、项目背景
随着互联网内容生态的蓬勃发展,博客作为知识分享和观点交流的重要平台,凭借其便捷的数字化学习优势,正逐渐优化传统的纸质笔记形式。这种高效的知识载体深受用户喜爱。为确保为用户提供稳定、易用且优质的博客体验,必须对博客系统进行全面测试。通过模拟真实用户操作场景,我们将验证系统功能完整性、检验交互逻辑合理性,及时发现并修复潜在问题,从而确保系统能够高效支持创作者完成内容发布、阅读和修改等操作。
三、项目功能
1)初始登录界面
覆盖多种登录身份验证场景,包括用户登录,验证登录流程、错误提示等功能,保障用户身份校验及系统访问权限控制准确。
2)博客首页
信息展示:呈现个人信息(头像、昵称等 )、博客列表(名称、创建时间、内容等 ),同时展示 多维度实用提示及对应跳转(如跳转博客详情、编辑页等 ),满足用户快速浏览内容需求。
登录状态交互:区分登录与未登录状态下的功能可见性与操作权限,如登录后可进行个性化操作,未登录则引导登录,保障系统交互逻辑合理。
3)博客详情页
基础信息呈现:展示博客作者个人信息、博客信息,验证互动功能流程及数据反馈准确性。
关联功能跳转:可跳转至实用提示对应页面,保障页面间交互流畅,提升用户操作连贯性。
4)博客编辑页
内容编辑交互:支持标题、内容输入,发布 / 保存 / 预览等操作逻辑,确保创作者能高效编辑、发布博客内容,辅助创作者修正内容。
状态联动:与首页、详情页状态关联,发布后同步更新展示,保障系统内数据一致性,让用户操作结果实时反馈。
四、测试工具
1)基础操作系统环境
系统版本:Windows 11(64 位操作系统)
环境优势:具备稳定的图形化界面支持,兼容 Chrome、Edge 等主流浏览器及 PyCharm 开发工具,可流畅运行 Selenium 自动化测试脚本,满足本地测试与调试需求。
2)浏览器环境
Google Chrome 浏览器
作用:作为自动化测试核心执行浏览器,配合 Selenium ChromeDriver 驱动,实现页面元素定位、交互操作(如登录、输入、点击发布等)及截图功能,保障测试流程的稳定性与兼容性。
3)开发与测试工具环境
PyCharm(Python 3.7 解释器)
核心功能:作为 Python 开发 IDE,提供代码编辑、语法校验、断点调试、脚本运行等功能,支持集成 Selenium、unittest 等测试库;
解释器配置:采用 Python 3.7 版本,确保与项目依赖的 Selenium 版本(如 3.x/4.x)、webdriver-manager 等库兼容,避免因版本不匹配导致的脚本执行异常。
Xmind
作用:用于梳理测试需求、设计测试用例,通过思维导图形式拆解博客系统功能模块(如登录、首页、编辑页、详情页)的测试点,清晰呈现测试范围与用例逻辑,便于团队对齐测试目标与执行计划。
4)依赖库环境
除上述工具外,需通过 PyCharm 的pip
工具安装以下核心依赖库,确保自动化脚本正常运行:
Selenium:自动化测试核心库,提供操作浏览器、定位元素、模拟用户交互的 API;
webdriver-manager:自动管理 ChromeDriver、EdgeDriver 版本,避免手动下载驱动及版本不兼容问题;
datetime、os、sys:Python 内置库,分别用于生成截图时间戳、管理截图文件路径、获取调用方法名,支撑测试结果记录与文件管理功能。
五、测试模块
测试覆盖博客系统 4 个核心页面,每个页面区分 “登录” 与 “未登录” 两种状态,确保功能与权限验证全面性:
测试模块 | 核心测试场景 |
---|---|
登录页(blog_login.html) | 1. 正常登录(用户名 lisi / 密码 123456); 2. 异常登录(账号密码均错、账号错、密码错) |
首页(blog_list.html) | 1. 登录状态:验证博客信息(标题、内容、按钮)与个人信息(昵称、头像)加载; 2. 未登录状态:验证跳转登录页逻辑 |
详情页(blog_detail.html) | 1. 登录状态:验证博客标题、时间、内容加载及 “编辑 / 删除” 按钮功能; 2. 未登录状态:验证权限拦截与登录跳转 |
编辑页(blog_edit.html) | 1. 登录状态:正常发布(输入标题 “Jmeter 测试”)、异常发布(无标题); 2. 未登录状态:验证发布拦截与登录跳转 |
六、项目实践
1)设计自动化测试用例
测试用例设计围绕系统功能分层展开,已梳理成思维导图。覆盖登录界面、首页信息展示、详情页交互、编辑页内容发布等核心功能,测试执行将严格对照导图拆解的子场景验证。
2)编写项目测试脚本
根据测试用例,搭建自动化测试框架并编写相应的测试脚本。
1. 测试脚本分布
为了简化测试流程,我们可以将浏览器配置参数提取到配置文件中。通过读取配置文件,测试脚本能够快速获取所需的浏览器对象和URL参数,从而避免重复配置。这种方法不仅提高了测试效率,还使测试代码更加简洁易维护。
关于相册功能的注意事项:
在自动化截图过程中,系统弹窗是由浏览器内核/操作系统直接渲染生成的,不属于页面DOM元素。由于屏幕截图功能仅能捕获页面DOM元素,因此在项目测试时无法截取到这些弹窗内容。在执行测试时,如果必须截图,则需要手动设置程序强制等待截图。
执行入口,按 “登录测试→首页测试→详情页测试→编辑页测试” 顺序执行,确保测试流程连贯,最终关闭浏览器释放资源。
2. 配置文件(pz.py)
import datetime
import os.path
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):
# 图片文件名称2025-08-29-XXXXXX.png
# 图片路径./ceshitupian/2025-08-29/2025-08-29-XXXXXX.png
# 文件夹名称
dirname = datetime.datetime.now().strftime("%Y-%m-%d")
# 判断dirname文件夹是否已经存在
# 不存在则创建文件夹
if not os.path.exists("../ceshitupian/" + dirname):
os.mkdir("../ceshitupian/" + dirname)
# 设置图片文件名称2025-08-29-XXXXXX.png
#sys._getframe().f_back.f_code.co_name 用来获取调用的方法名字
filename = sys._getframe().f_back.f_code.co_name + "-" + datetime.datetime.now().strftime("%Y-%m-%d-%H%M%S") + ".png"
self.driver.save_screenshot("../ceshitupian/" + dirname + "/" + filename)
BlongDriver = Driver()
3. 登录页测试(dl.py)
import time
from selenium.webdriver.common.by import By
from common.pz import BlongDriver
#登录界面
class BlongLogin:
url = ""
driver = ""
def __init__(self):
self.url = "http://8.137.19.140:9090/blog_login.html"
self.driver = BlongDriver.driver
self.driver.get(self.url)
#成功登录
def LoginSucTest(self):
self.driver.find_element(By.CSS_SELECTOR,"#username").send_keys("lisi")
self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("123456")
self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
#添加截图
BlongDriver.getScreeShot()
#登录成功后有个人信息显示
#以昵称为例子检测
#显示昵称则成功登录
#self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > h3")
#通过页面差异检验
ret = self.driver.find_elements(By.CSS_SELECTOR, "body > div.nav > a:nth-child(6)")
# 遍历元素
for i in ret:
print("页面右上角信息显示(有注销则登录成功,无则没有登录):"
"",i.text)
time.sleep(1)
#返回登录页面,测试登录失败情况
#self.driver.back()
#time.sleep(1)
#异常登录
def LoginFailTest(self):
#多次输入send_keys会造成关键词输入的拼接
#所以先clear删除再输入
#都错误的测试
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("lis")
self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("12345")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
time.sleep(2)
alert = self.driver.switch_to.alert
# 验证登录错误原因
print("弹窗内容(账号密码都错误):", alert.text)
alert.accept()
time.sleep(2)
#账号错误测试
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("lis")
self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
time.sleep(2)
alert = self.driver.switch_to.alert
# 验证登录错误原因
print("弹窗内容(账号错误,密码正确):", alert.text)
alert.accept()
time.sleep(2)
#密码错误测试
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("lisi")
self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("12345")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
time.sleep(2)
alert = self.driver.switch_to.alert
time.sleep(2)
# 验证登录错误原因
print("弹窗内容(账号正确,密码错误):", alert.text)
alert.accept()
time.sleep(2)
#self.driver.quit()
#login = BlongLogin()
#login.LoginSucTest()
#login.LoginFailTest()
4. 首页测试(sy.py)
import time
from selenium.webdriver.common.by import By
from common.pz import BlongDriver
#博客首页
class BlongList:
url = ""
driver = ""
def __init__(self):
self.url = "http://8.137.19.140:9090/blog_list.html"
self.driver = BlongDriver.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.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 > img")
#输出信息确认测试完成
#输出博客标题
ret = self.driver.find_elements(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(1) > div.title")
# 遍历元素
for i in ret:
print("首页博客标题:", i.text)
print("首页登录状态测试完成")
#添加屏幕截图
BlongDriver.getScreeShot()
#测试首页(未登录情况下)
def ListTestFail(self):
#先注销在访问
self.driver.find_element(By.CSS_SELECTOR, "body > div.nav > a:nth-child(6)").click()
#再次访问
ret = self.driver.find_elements(By.CSS_SELECTOR, "body > div.nav > a:nth-child(6)")
# 判断逻辑
if ret:
logout_text = ret[0].text.strip()
print(f"页面右上角信息显示:{logout_text} → {'登录成功' if logout_text == '注销' else '登录状态异常'}")
else:
print("页面右上角未找到“注销”元素 → 未登录")
print("首页没有登录状态测试完成")
5. 详情页测试(xq.py)
from selenium.webdriver.common.by import By
from common.pz import BlongDriver
#测试博客详情页
class BlongDeail:
url = ""
driver = ""
def __init__(self):
self.url = "http://8.137.19.140:9090/blog_detail.html?blogId=158477"
self.driver = BlongDriver.driver
self.driver.get(self.url)
#登陆状态下博客详情页
def DetailTestByLogin(self):
#检查标题
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 > p")
# 输出信息确认测试完成
# 输出博客内容
ret = self.driver.find_elements(By.CSS_SELECTOR,"#detail > p")
# 遍历元素
for i in ret:
print("博客详情页内容:", i.text)
print("博客详情页登录状态测试完成")
#屏幕截图
BlongDriver.getScreeShot()
#详情页测试(未登录情况下)
def DetailFail(self):
#先注销在访问
self.driver.find_element(By.CSS_SELECTOR, "body > div.nav > a:nth-child(6)").click()
#再次访问
ret = self.driver.find_elements(By.CSS_SELECTOR, "body > div.nav > a:nth-child(6)")
# 判断逻辑
if ret:
logout_text = ret[0].text.strip()
print(f"页面右上角信息显示:{logout_text} → {'登录成功' if logout_text == '注销' else '登录状态异常'}")
else:
print("页面右上角未找到“注销”元素 → 未登录")
print("博客详情页没有登录状态测试完成,跳转至首页,需要重新登录")
6. 编辑页测试(bj.py)
import time
from selenium.webdriver.common.by import By
from common.pz import BlongDriver
#测试博客编辑页面
class BlongEdit:
url = ""
driver = ""
def __init__(self):
self.url = "hhttp://8.137.19.140:9090/blog_edit.html"
self.driver = BlongDriver.driver
self.driver.get(self.url)
#正确发布博客(登陆状态下)
def EditSucTestByLogin(self):
time.sleep(1)
#点击写博客,开始编辑博客
self.driver.find_element(By.CSS_SELECTOR,"body > div.nav > a:nth-child(5)").click()
time.sleep(2)
self.driver.find_element(By.CSS_SELECTOR,"#title").send_keys("Jmeter测试")
#菜单栏无法元素无法定位
#博客系统编辑区域默认情况下就不为空,可以暂不处理
#菜单栏元素
#self.driver.find_element(By.CSS_SELECTOR,"# editor > div.editormd-toolbar > div > ul > li:nth-child(21)").click()
#直接点击发布按钮来发布博客
self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
#点击完成之后出现页面的跳转,页面跳转需要加载时间
time.sleep(3)
actual=self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div:nth-child(1) > div.title").text
print("编辑博客测试标题:"+actual)
assert actual == "Jmeter测试"
#屏幕截图
BlongDriver.getScreeShot()
print("博客编辑页登录状态,正常发布博客测试完成")
def EditTestNo(self):
time.sleep(1)
#点击写博客,开始编辑博客
self.driver.find_element(By.CSS_SELECTOR,"body > div.nav > a:nth-child(5)").click()
time.sleep(1)
#不编辑,直接点击发布按钮来发布博客
self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
time.sleep(2)
#出现弹窗
alert = self.driver.switch_to.alert
# 退出弹窗
alert.accept()
time.sleep(1)
# 通过页面差异检验
ret = self.driver.find_elements(By.CSS_SELECTOR, "#submit")
# 遍历元素
for i in ret:
print("需要重新输入标题后,再发布文章")
time.sleep(1)
# 屏幕截图
BlongDriver.getScreeShot()
print("博客编辑页登录状态,异常发布博客测试完成")
#博客编辑页测试(未登录情况下)
def EditFail(self):
time.sleep(1)
#先注销在访问
self.driver.find_element(By.CSS_SELECTOR, "body > div.nav > a:nth-child(6)").click()
time.sleep(2)
# 点击写博客,开始编辑博客
self.driver.find_element(By.CSS_SELECTOR, "body > div.nav > a:nth-child(5)").click()
time.sleep(2)
self.driver.find_element(By.CSS_SELECTOR, "#title").send_keys("未登录Jmeter测试")
self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
#再次访问
ret = self.driver.find_elements(By.CSS_SELECTOR, "body > div.nav > a:nth-child(6)")
# 判断逻辑
if ret:
logout_text = ret[0].text.strip()
print(f"页面右上角信息显示:{logout_text} → {'登录成功' if logout_text == '注销' else '登录状态异常'}")
else:
print("页面右上角未找到“注销”元素 → 未登录")
print("编辑博客页没有登录状态测试完成,跳转至首页,需要重新登录")
7. 运行文件(run.py)
from test import dl
from test import sy
from test import xq
from test import bj
from common.pz import BlongDriver
if __name__ == "__main__":
dl.BlongLogin().LoginFailTest()
dl.BlongLogin().LoginSucTest()
# 登陆成功之后就可以调用博客首页测试首页的用例(登陆状态)
sy.BlongList().ListTestByLogin()
# 注销后测试首页(未登录状态)
sy.BlongList().ListTestFail()
# 测试登录状态下的博客详情页
dl.BlongLogin().LoginSucTest()
xq.BlongDeail().DetailTestByLogin()
# 测试没有登录状态下的博客详情页
xq.BlongDeail().DetailFail()
# 测试登录状态下正常发布的博客编辑页面
dl.BlongLogin().LoginSucTest()
bj.BlongEdit().EditSucTestByLogin()
# 测试登录状态下错误发布的博客编辑页面
bj.BlongEdit().EditTestNo()
# 测试没有登录状态下的博客编辑页面
bj.BlongEdit().EditFail()
#指定浏览器的退出
BlongDriver.driver.quit()
3)执行测试
1. 登录测试
测试程序运行结果:
登录成功场景测试结果:
输入正确用户名 "lisi" 和密码 "123456" 后点击登录按钮。
系统跳转至登录后页面,通过定位页面右上角元素“注销”进行验证。
控制台输出该元素文本内容,若显示 "注销" 相关信息,则表明登录成功,输出见运行结果。
通过 back () 方法返回登录页面,准备执行登录失败测试。
登录失败场景测试结果:
在输入错误信息前,都清空输入框内容。
账号密码均错误:输入 "lis" 和 "12345" 点击登录,系统弹出提示弹窗,控制台输出弹窗文本内容,点击 "确定" 关闭弹窗
账号错误、密码正确:输入 "lis" 和 "123456" 点击登录,系统弹出提示弹窗,控制台输出弹窗文本内容,点击 "确定" 关闭弹窗
账号正确、密码错误:输入 "lisi" 和 "12345" 点击登录,系统弹出提示弹窗,控制台输出弹窗文本内容,点击 "确定" 关闭弹窗
以上错误测试中,在关闭弹窗后均返回登录界面,所有场景测试完成后,关闭浏览器驱动。
2. 首页测试
登录状态测试运行结果:
首页信息截屏:
登录状态下,首页博客信息(标题、内容、按钮)与个人信息(昵称、头像)均完整加载,文本输出与截图功能正常。
注销后未登录状态,测试运行结果:
未登录状态下,访问首页时,直接跳转至登录界面。
3. 详情页测试
测试运行结果(登录及未登录):
登录状态下博客详情页信息:
未登录状态下,访问博客详情时,通过“注销按钮”是否存在观测,页面将直接跳转至登录界面。
4. 编辑页测试
测试运行结果:
登录状态下可正常发布博客,标题显示正确。
登录状态下标题为空时系统会拦截发布并提示。
点击后,继续返回编辑页。
未登录状态下无法发布博客,权限控制有效。
点击发布文章后,跳转至登录页:
5. 部分自动化截图展示
七、项目亮点与优化点
1)项目亮点
自动化效率提升:
脚本可重复执行,避免手动测试的重复性操作,单轮测试执行时间缩短至 5 分钟内。
结果可视化:
截图按 “日期 + 方法名” 分类存储,控制台输出详细日志(如弹窗内容、博客标题),问题可追溯。
兼容性保障:
通过 webdriver-manager 自动管理驱动版本,兼容不同 Chrome 版本,降低环境配置成本。
权限控制全面:
覆盖 “登录 / 未登录” 两种状态,确保未授权操作被合理拦截,符合系统安全设计。
2)待优化点
等待机制:
当前使用time.sleep()
固定等待,若页面加载延迟易导致元素定位失败,后续可替换为显式等待(WebDriverWait
),提升脚本稳定性;
异常场景扩展:
未覆盖 “网络中断”“页面超时” 等异常场景,可增加异常处理逻辑,提升测试健壮性。
八、项目结论
本项目通过自动化测试完整验证了博客系统的核心功能,所有测试用例执行通过,系统在 “功能完整性”“权限控制”“交互逻辑” 上均符合预期:
- 登录页能准确校验账号密码,异常提示清晰。
- 首页、详情页在登录状态下加载完整信息,未登录状态跳转登录页,权限控制合理。
- 编辑页支持正常发布与异常拦截,发布后数据同步至首页,数据一致性良好。
- 脚本框架模块化程度高,可复用性强,截图记录便于后续维护与问题排查。