炸薯条!头像
关注

博客系统 Web自动化测试项目报告

博客系统 Web 自动化测试项目报告

一、项目概述

1.1 项目名称

博客系统 Web 自动化测试项目

1.2 项目类型

Web UI 自动化测试项目

1.3 项目背景

本项目针对一个基于浏览器访问的博客管理系统进行自动化测试,主要验证用户登录、博客列表查看、博客详情查看以及博客发布等核心业务功能。

项目使用 Python 编写测试脚本,基于 Selenium WebDriver 驱动 Chrome 浏览器,模拟真实用户在网页中的操作流程,并通过元素定位、页面跳转、文本断言、弹窗处理等方式验证系统功能是否符合预期。

该项目主要用于熟悉以下测试开发工作:

  • Web 页面元素定位;
  • 浏览器自动化操作;
  • 用户登录流程测试;
  • 正向和反向测试用例设计;
  • 页面跳转验证;
  • 博客发布流程验证;
  • JavaScript 编辑器交互处理;
  • 浏览器弹窗处理;
  • 测试截图保存;
  • 测试结果分析和缺陷定位。

1.4 项目目标

本项目的主要目标如下:

  1. 验证博客系统的核心功能是否能够正常使用;
  2. 验证错误账号或错误密码时系统是否给出正确提示;
  3. 验证登录成功后页面是否正确跳转;
  4. 验证博客列表页面是否能够正常加载;
  5. 验证博客详情内容是否正确展示;
  6. 验证用户是否可以成功发布博客;
  7. 验证博客发布后的成功提示和页面跳转;
  8. 提高回归测试效率,减少人工重复操作;
  9. 积累 Selenium Web 自动化测试实践经验。

二、项目环境

2.1 测试环境

项目内容
操作系统Windows
开发工具PyCharm
编程语言Python
自动化框架Selenium WebDriver
浏览器Google Chrome
浏览器驱动ChromeDriver
Python 环境Python 3.11
测试对象博客系统 Web 页面
页面协议HTTP
测试地址http://47.108.157.13:8090
项目目录pythonProject2
测试目录tests

2.2 主要依赖

项目主要使用以下技术和库:

selenium

核心 Selenium 模块包括:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

各模块作用如下:

模块作用
webdriver启动和控制 Chrome 浏览器
By提供元素定位方式
WebDriverWait实现显式等待
expected_conditions判断页面元素、弹窗和页面状态是否满足条件
time在特殊场景下进行短暂等待
execute_script通过 JavaScript 操作复杂页面元素

三、被测系统功能分析

博客系统主要包含以下功能模块:

3.1 登录功能

用户通过登录页面输入用户名和密码,点击登录按钮进入博客系统。

测试内容包括:

  • 正确用户名和正确密码登录;
  • 错误密码登录;
  • 登录成功后的页面跳转;
  • 登录失败时的错误提示;
  • 登录状态下的页面访问权限。

3.2 博客列表功能

登录成功后,系统跳转到博客列表页面。

测试内容包括:

  • 博客列表页面能否正常访问;
  • 博客标题是否正常显示;
  • 博客列表页面的基本布局是否正常;
  • 博客数据是否能够加载;
  • 页面跳转地址是否正确。

3.3 博客详情功能

用户从博客列表进入某篇博客详情页,查看博客完整内容。

测试内容包括:

  • 详情页是否能够正常打开;
  • 博客标题是否正确;
  • 博客正文是否正确;
  • 列表页和详情页之间的跳转是否正常。

3.4 博客发布功能

登录用户进入博客编辑页面,填写博客标题和正文,点击“发布文章”按钮完成博客发布。

测试内容包括:

  • 博客标题输入;
  • 博客正文输入;
  • Markdown 编辑器交互;
  • 发布按钮点击;
  • 发布成功弹窗;
  • 发布后页面跳转;
  • 新博客是否出现在博客列表中;
  • 发布博客标题是否正确。

3.5 注销功能

系统页面提供注销入口,用于退出当前登录状态。

测试内容包括:

  • 点击注销按钮;
  • 页面是否返回登录页;
  • 登录状态是否被清除;
  • 注销后是否还能直接访问需要登录的页面。

四、自动化测试框架设计

4.1 项目目录结构

项目目录可以整理为以下形式:

pythonProject2
│
├─ tests
│  ├─ BlogDriver.py
│  ├─ BlogLogin.py
│  ├─ BlogList.py
│  ├─ BlogDetail.py
│  ├─ BlogEdit.py
│  └─ RunTest.py
│
├─ screenshots
│  └─ ...
│
└─ .venv

各文件职责如下:

文件职责
RunTest.py测试执行入口,统一调用各个测试方法
BlogDriver.py浏览器驱动初始化、浏览器关闭、截图等公共操作
BlogLogin.py登录相关测试
BlogList.py博客列表页面测试
BlogDetail.py博客详情页面测试
BlogEdit.py博客发布页面测试
screenshots保存测试过程截图

4.2 测试执行流程

整体测试流程如下:

启动浏览器
    ↓
进入博客系统
    ↓
执行错误密码登录测试
    ↓
验证登录失败提示
    ↓
执行正确账号登录
    ↓
验证跳转到博客列表页
    ↓
执行博客列表测试
    ↓
执行博客详情测试
    ↓
进入博客编辑页
    ↓
填写博客标题和正文
    ↓
点击发布按钮
    ↓
处理“博客发表成功”弹窗
    ↓
验证跳转到博客列表页
    ↓
验证新博客标题
    ↓
保存截图
    ↓
结束测试

五、测试用例设计

5.1 登录模块测试用例

用例编号测试功能测试步骤预期结果
LOGIN-001正确账号登录输入正确用户名和密码,点击登录登录成功并跳转到博客列表页
LOGIN-002错误密码登录输入正确用户名和错误密码,点击登录页面提示“密码不正确”
LOGIN-003错误用户名登录输入不存在的用户名和密码页面提示登录失败
LOGIN-004用户名为空不输入用户名,点击登录页面提示用户名不能为空或阻止提交
LOGIN-005密码为空输入用户名,不输入密码页面提示密码不能为空或阻止提交
LOGIN-006登录成功页面验证登录成功后获取当前 URLURL 应包含 blog_list.html
LOGIN-007登录失败页面验证使用错误密码登录页面不应进入博客列表页

5.1.1 错误密码测试

错误密码场景属于反向测试,主要验证系统是否能够正确识别非法登录信息。

示例断言:

actual = self.driver.find_element(
    By.CSS_SELECTOR,
    "body"
).text

assert "密码不正确" in actual

该测试可以防止以下问题:

  • 错误密码也能登录;
  • 错误提示不显示;
  • 错误提示内容错误;
  • 页面跳转到错误页面;
  • 前端校验失效。

5.2 博客列表模块测试用例

用例编号测试功能测试步骤预期结果
LIST-001打开博客列表登录成功后进入列表页页面正常加载
LIST-002页面地址验证获取当前页面 URLURL 包含 blog_list.html
LIST-003博客标题验证获取第一篇博客标题标题正常显示
LIST-004博客列表内容验证检查列表区域文本页面存在博客内容
LIST-005博客跳转详情点击博客标题成功进入博客详情页
LIST-006页面基本元素验证查找导航、列表和博客标题页面核心元素存在

示例页面地址断言:

print("当前页面地址:", self.driver.current_url)

assert "blog_list.html" in self.driver.current_url

5.3 博客详情模块测试用例

用例编号测试功能测试步骤预期结果
DETAIL-001打开博客详情在列表页点击博客详情页正常打开
DETAIL-002详情标题验证获取详情页标题标题与列表页一致
DETAIL-003正文内容验证获取博客正文正文正常显示
DETAIL-004页面地址验证获取当前 URLURL 包含详情页地址
DETAIL-005返回列表页点击返回或主页返回博客列表页

详情页测试重点在于验证页面之间的数据一致性。博客列表页展示的标题,应该与详情页展示的标题一致。


5.4 博客发布模块测试用例

用例编号测试功能测试步骤预期结果
EDIT-001打开编辑页面点击“写博客”成功进入博客编辑页
EDIT-002输入博客标题在标题框输入内容标题输入成功
EDIT-003输入博客正文在编辑器中输入正文正文输入成功
EDIT-004发布空博客不填写内容直接发布系统阻止发布并提示错误
EDIT-005发布博客填写标题和正文后点击发布页面提示“博客发表成功”
EDIT-006发布弹窗处理获取浏览器 Alert 文本Alert 内容为“博客发表成功”
EDIT-007发布后页面跳转关闭成功弹窗跳转到博客列表页
EDIT-008新博客标题验证查找刚发布的博客标题标题与输入内容一致
EDIT-009新博客正文验证进入详情页检查正文正文与输入内容一致

六、关键自动化实现

6.1 显式等待

项目中使用 Selenium 的显式等待来提高脚本稳定性。

示例:

wait = WebDriverWait(self.driver, 10)

title = wait.until(
    EC.visibility_of_element_located(
        (By.CSS_SELECTOR, "#title")
    )
)

显式等待的优点:

  • 等待元素真正出现;
  • 避免页面加载较慢导致测试失败;
  • 比固定 sleep 更稳定;
  • 可以明确等待条件;
  • 减少不必要的等待时间。

常用等待条件包括:

EC.presence_of_element_located()
EC.visibility_of_element_located()
EC.element_to_be_clickable()
EC.alert_is_present()

6.2 博客正文编辑器处理

博客编辑页面使用了 Markdown 编辑器,页面中存在隐藏的 textarea。虽然 Selenium 可以找到该元素,但它可能处于不可交互状态,直接执行:

content.send_keys("博客正文")

可能出现:

ElementNotInteractableException

项目中使用 JavaScript 对编辑器进行处理:

content_text = "这是自动化测试发布的博客正文内容"

self.driver.execute_script("""
    const content = arguments[0];

    const editor =
        document.querySelector(".vditor-sv__editor textarea") ||
        document.querySelector(".vditor-ir__editor") ||
        document.querySelector("[contenteditable='true']") ||
        document.querySelector("textarea");

    if (!editor) {
        throw new Error("没有找到博客正文编辑器");
    }

    editor.focus();

    if (editor.tagName.toLowerCase() === "textarea") {
        const setter = Object.getOwnPropertyDescriptor(
            HTMLTextAreaElement.prototype,
            "value"
        ).set;

        setter.call(editor, content);
    } else {
        editor.innerText = content;
    }

    editor.dispatchEvent(new Event("input", {
        bubbles: true
    }));

    editor.dispatchEvent(new Event("change", {
        bubbles: true
    }));
""", content_text)

该处理方式解决了以下问题:

  • Selenium 无法直接操作隐藏文本框;
  • 页面实际可编辑区域与 DOM 中的 textarea 不一致;
  • 通过 JavaScript 修改编辑器内容;
  • 触发 input 和 change 事件,使前端应用能够感知内容变化。

这部分内容可以作为项目中的一个技术难点进行重点介绍。


6.3 浏览器 Alert 弹窗处理

点击发布后,页面会弹出:

博客发表成功

如果不处理弹窗,继续执行:

self.driver.current_url

会产生:

UnexpectedAlertPresentException

正确处理方式如下:

submit.click()

alert = WebDriverWait(
    self.driver,
    10
).until(
    EC.alert_is_present()
)

alert_text = alert.text
print("发布提示:", alert_text)

assert alert_text == "博客发表成功"

alert.accept()

wait.until(
    lambda driver: "blog_list.html" in driver.current_url
)

print("发布后当前页面地址:", self.driver.current_url)

这里包含了三个验证点:

  1. 等待弹窗出现;
  2. 验证弹窗内容;
  3. 点击确定关闭弹窗。

这种方式比单纯使用 time.sleep() 更可靠。


七、测试结果

7.1 当前测试结果

根据项目运行过程,目前已验证的场景包括:

模块测试结果说明
错误密码登录通过页面能够显示“密码不正确”
正确账号登录通过成功进入博客列表页
博客列表页面通过页面地址和内容验证通过
博客详情页面通过详情页面能够正常打开
博客发布功能功能成功页面显示“博客发表成功”
发布成功弹窗处理已定位问题需要在读取 URL 前关闭 Alert
发布后标题验证待最终确认需要处理弹窗后继续执行断言

7.2 测试执行中的问题

问题一:正文编辑器无法直接输入

错误信息:

ElementNotInteractableException

原因:

页面中的 textarea 元素虽然存在,但处于隐藏或不可交互状态。真正的编辑区域由 Markdown 编辑器动态生成。

解决方案:

  • 使用 JavaScript 获取可编辑区域;
  • 修改编辑器内容;
  • 手动触发 input 和 change 事件;
  • 在测试代码中兼容 textarea 和 contenteditable 元素。

问题二:发布成功后读取 URL 报错

错误信息:

UnexpectedAlertPresentException

原因:

点击发布按钮后,网页弹出浏览器原生 Alert:

博客发表成功

此时 Selenium 不能继续操作当前页面,必须先处理弹窗。

解决方案:

alert = WebDriverWait(
    self.driver,
    10
).until(
    EC.alert_is_present()
)

assert alert.text == "博客发表成功"
alert.accept()

处理完成后,再获取页面地址并执行后续断言。

问题三:固定等待可能导致测试不稳定

早期代码中使用:

time.sleep(2)

这种方式虽然简单,但存在以下问题:

  • 网络较慢时等待时间不足;
  • 页面加载较快时浪费时间;
  • 测试结果受机器性能影响;
  • 无法准确判断页面是否真正加载完成。

改进方式:

wait.until(
    EC.element_to_be_clickable(
        (By.CSS_SELECTOR, "#submit")
    )
)

或:

wait.until(
    lambda driver: "blog_list.html" in driver.current_url
)

八、测试数据设计

8.1 登录测试数据

数据类型用户名密码预期结果
正确数据合法账号正确密码登录成功
错误密码合法账号错误密码提示密码不正确
错误用户名不存在账号任意密码登录失败
空用户名空正确密码提示用户名不能为空
空密码合法账号空提示密码不能为空

8.2 博客发布测试数据

字段测试值
博客标题自动化测试创建
博客正文这是自动化测试发布的博客正文内容
发布方式点击发布按钮
预期提示博客发表成功
预期跳转blog_list.html
预期结果列表中出现新博客

九、项目中的测试方法

9.1 黑盒测试

从用户角度验证博客系统功能,不关注内部实现细节。

主要验证:

  • 输入和输出是否符合预期;
  • 页面是否正确跳转;
  • 提示信息是否正确;
  • 博客数据是否正确展示。

9.2 功能测试

针对博客系统核心功能编写测试用例,包括:

  • 登录;
  • 注销;
  • 博客列表;
  • 博客详情;
  • 博客发布。

9.3 正向测试

使用正常数据验证系统功能是否能够正常完成。

例如:

  • 正确账号登录;
  • 正确填写标题和正文;
  • 正常发布博客;
  • 正常查看博客详情。

9.4 反向测试

使用异常数据验证系统的容错能力。

例如:

  • 输入错误密码;
  • 输入空用户名;
  • 输入空密码;
  • 发布空博客;
  • 不处理弹窗时继续访问页面。

9.5 回归测试

每次修改测试脚本或页面后,重新执行已有测试用例,确认原有功能没有受到影响。


十、项目难点和解决方案

10.1 难点一:页面元素定位

页面中有多个结构相似的元素,部分元素没有明显的唯一 ID。

解决方案:

  • 优先使用唯一 ID;
  • 其次使用稳定的 CSS Selector;
  • 避免过度依赖绝对 XPath;
  • 对关键元素增加显式等待;
  • 对页面结构进行分析后再确定定位表达式。

例如:

(By.CSS_SELECTOR, "#title")

比复杂的层级定位更加稳定。

10.2 难点二:动态页面加载

页面内容不是打开页面后立即出现,直接查找元素可能出现:

NoSuchElementException

解决方案:

wait.until(
    EC.visibility_of_element_located(
        (By.CSS_SELECTOR, "#title")
    )
)

10.3 难点三:富文本或 Markdown 编辑器

编辑器表面上是一个可输入区域,但实际 DOM 结构可能包含:

  • 隐藏的 textarea;
  • 可编辑的 div;
  • 预览区域;
  • 动态生成的内部节点。

解决方案:

  • 通过浏览器开发者工具分析 DOM;
  • 查找 contenteditable 属性;
  • 使用 JavaScript 处理隐藏控件;
  • 触发前端需要的事件。

10.4 难点四:原生浏览器弹窗

发布成功后浏览器弹出 Alert,导致 Selenium 暂停页面操作。

解决方案:

alert = wait.until(EC.alert_is_present())
assert alert.text == "博客发表成功"
alert.accept()

10.5 难点五:测试流程之间存在依赖

博客列表测试、详情测试和发布测试需要先完成登录。

解决方案:

  • 统一在测试入口中控制执行顺序;
  • 将登录流程封装为公共方法;
  • 在每个测试开始前确认当前页面状态;
  • 后续可以改造成独立测试,避免用例之间相互依赖。

十一、项目质量改进方向

11.1 引入 Pytest

目前项目采用普通 Python 方法执行测试,可以进一步迁移到 Pytest。

例如:

import pytest

class TestBlog:

    def test_login_success(self):
        pass

    def test_blog_list(self):
        pass

    def test_blog_publish(self):
        pass

使用 Pytest 后可以获得:

  • 自动发现测试用例;
  • 更清晰的测试报告;
  • Fixture 管理浏览器;
  • 参数化测试;
  • 失败重试;
  • 标记测试用例;
  • 与 CI 工具集成。

11.2 使用 Fixture 管理浏览器生命周期

示例:

import pytest
from selenium import webdriver

@pytest.fixture
def driver():
    driver = webdriver.Chrome()
    driver.maximize_window()
    yield driver
    driver.quit()

这样可以统一管理:

  • 浏览器启动;
  • 浏览器关闭;
  • 测试前置条件;
  • 测试后清理工作。

11.3 引入 Page Object Model

可以将页面操作和测试断言分离。

示例目录:

pages
├─ login_page.py
├─ blog_list_page.py
├─ blog_detail_page.py
└─ blog_edit_page.py

tests
├─ test_login.py
├─ test_blog_list.py
├─ test_blog_detail.py
└─ test_blog_edit.py

页面对象示例:

class BlogEditPage:

    def __init__(self, driver):
        self.driver = driver

    def input_title(self, title):
        self.driver.find_element(
            By.CSS_SELECTOR,
            "#title"
        ).send_keys(title)

    def click_submit(self):
        self.driver.find_element(
            By.CSS_SELECTOR,
            "#submit"
        ).click()

这样可以降低页面结构变化对测试代码的影响。

11.4 增加日志记录

可以使用 Python 的 logging 模块:

import logging

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s"
)

logging.info("开始执行博客发布测试")
logging.info("博客标题输入完成")
logging.info("发布成功提示已确认")

日志可以帮助定位:

  • 测试执行到哪个步骤;
  • 哪一步出现异常;
  • 当前页面地址;
  • 当前使用的测试数据;
  • 页面跳转是否成功。

11.5 自动生成测试报告

可以使用:

pytest --html=report.html

或者使用 Allure:

pytest --alluredir=allure-results
allure serve allure-results

测试报告中可以包含:

  • 用例名称;
  • 执行结果;
  • 错误信息;
  • 截图;
  • 执行时间;
  • 测试步骤;
  • 环境信息。

11.6 接入持续集成

后续可以将项目接入 Jenkins 或 GitHub Actions,实现:

提交代码
    ↓
自动安装依赖
    ↓
启动测试环境
    ↓
执行自动化测试
    ↓
生成测试报告
    ↓
发送测试结果

十二、项目成果

通过本项目,完成了博客系统核心功能的自动化验证,主要成果如下:

  1. 实现了基于 Selenium 的浏览器自动化测试;
  2. 完成登录模块正向和反向测试;
  3. 完成博客列表页面测试;
  4. 完成博客详情页面测试;
  5. 完成博客发布流程测试;
  6. 实现页面元素定位和文本断言;
  7. 实现页面跳转地址验证;
  8. 实现浏览器 Alert 弹窗处理;
  9. 解决 Markdown 编辑器无法直接输入的问题;
  10. 使用显式等待提高测试稳定性;
  11. 实现测试截图保存;
  12. 根据测试异常定位页面交互和脚本问题;
  13. 对自动化测试过程中的异常进行了分析和修复;
  14. 具备从测试执行、问题定位到脚本改进的完整实践经验。

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/2401_82842337/article/details/166845274

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--