博客系统全流程测试总结

1.项目概要

本项目针对个人博客系统开展全维度自动化测试,覆盖系统核心模块(登录界面、首页、详情页、编辑页),围绕功能、安全、性能、界面、兼容性、易用性 6 大测试方向设计用例,验证系统在不同场景下的可用性、稳定性与可靠性。

1.1项目测试背景

为满足个人创作者 "低成本搭建专属内容发布平台" 的需求,本博客系统以 "轻量、易用、自主可控" 为核心目标开发:

  • 支持创作者独立完成博客内容的编辑、发布、管理;
  • 提供用户身份验证、内容展示等基础功能,同时预留扩展接口(如评论、分类统计);
  • 适配多终端场景,帮助创作者实现内容的跨设备触达;

1.2测试目的及测试启动背景

为确保系统正式上线后能稳定支撑创作者的日常使用,需通过全维度测试验证:

  • 功能流程的正确性(如博客发布、编辑、删除的无异常执行);
  • 非功能维度的达标性(如登录响应速度、多终端兼容性、数据传输安全性);
  • 用户操作的易用性(如错误提示的清晰性、流程的流畅度);最终保障系统从 "可用" 升级为 "可靠、好用" 的个人内容平台。

1.3测试环境

软件:Google Chrome

测试工具:postman、selenium、JMeter

开发工具:pyCharm Community Edition 2024.2.1

操作系统:Windows 11家庭中文版

浏览器版本:Google Chrome、Microsoft Edge

2.测试用例编写

3.手工测试

3.1登录页面测试

如图所示,登录弹窗布局清晰、无文字错误、图片 / 样式加载正常;用户名 / 密码输入框可正常输入、删除内容。

3.2主页测试

3.3博客编辑页面测试

3.4博客详情页测试

4.博客兼容性测试

4.1不同浏览器

  • Chrome
  • Edge

4.2设备兼容性测试

  • PC端
  • 手机端

5.自动化测试

5.1项目目录

5.2驱动类(Util.py

python 复制代码
import os.path
import sys
from datetime import datetime
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from webdriver_manager.core.driver import Driver
#创键你一个浏览器对象
class Driver: #创建一个driver类,把test中所有可能用到的东西都装进去
    driver = "" #创建一个驱动对象,其中一个成员为空
    def __init__(self):#构造函数
        options=webdriver.ChromeOptions()
        from selenium.webdriver.chrome.service import Service
        self.driver=webdriver.Chrome(service=Service(ChromeDriverManager().install()),options=options)
    #为每个调用Driver类的类对象都对应一个driver成员
    #单例模式,所有的测试问价都用一个driver
    def getScreenShot(self):
        #创建屏幕截图
        #图片文件名称
        dirname = datetime.now().strftime("%Y-%m-%d")#生成的文件夹名称
        #判断dirname文件夹是否已经存在
        if not os.path.exists("../images/"+dirname):
            os.mkdir("../images/"+dirname)
        filename=sys._getframe().f_back.f_code.co_name+"-"+datetime.now().strftime("%Y-%m-%d-%H%M%S")+".png"
        self.driver.save_screenshot("../images/"+dirname+"/"+filename)


BlogDriver = Driver()

5.3登录类 (BlogLoginTest.py)

python 复制代码
import time

from selenium.webdriver.common.by import By

from common.Util 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 LoginSucTest(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(2)
        #能够找到博客首页的昵称,说明登录成功,否则登录失败
        self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > h3")
        #添加屏幕截图
        BlogDriver.getScreenShot()
        time.sleep(5)
        self.driver.back()

    #异常登录的测试用例
    def LoginFailTest(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("zhanger")
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("12344")
        self.driver.find_element(By.CSS_SELECTOR, "#submit").click()

        time.sleep(3)
        #检查登录是否成功
        alert=self.driver.switch_to.alert
        actual=alert.text
        #断言一下是否符合预期
        alert.accept()
        assert actual =="用户不存在"
        BlogDriver.getScreenShot()
        self.driver.back()
        #self.driver.quit()

5.4首页类(BlogListTest.py)

python 复制代码
import time
from selenium.webdriver.common.by import By
from common.Util 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):
        time.sleep(2)
        #测试博客标题是否存在
        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")
        #添加屏幕截图
        BlogDriver.getScreenShot()

5.5详情类

python 复制代码
import time

from selenium.webdriver.common.by import By

from common.Util import BlogDriver


#测试博客详情页
class BlogDetail:
    url=""
    driver=""
    def __init__(self):
        # 刚才的问题就是之前的blogId的博客被清除了,所以报了"操作有误,请联系管理员" 这个错误
        self.url="http://47.108.157.13:8090/blog_detail.html?blogId=33981"
        self.driver= BlogDriver.driver
        self.driver.get(self.url)
        #登录状态下博客详情页的测试
    def DetailTestByLogin(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.XPATH,'//*[@id="detail"]/p')
        #屏幕截图
        BlogDriver.getScreenShot()

        # 未登录状态下的博客详情页面测试
    def DetailTestFileLogin(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")
        #用户名
        self.driver.find_element(By.CSS_SELECTOR, "body > div.container-login > div > div:nth-child(2) > span")
        #密码
        self.driver.find_element(By.CSS_SELECTOR, "body > div.container-login > div > div:nth-child(3) > span")
        #提交
        self.driver.find_element(By.CSS_SELECTOR, "#submit")
        BlogDriver.getScreeShot()

5.6编辑类(BlogEditTest.py

python 复制代码
# 正确的导入方式(放在文件开头)

from selenium.webdriver.support import expected_conditions as EC  # 关键:这里的EC是expected_conditions的别名
import time
from telnetlib import EC

from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait

from common.Util import BlogDriver
#from tests.BlogDetailTest import BlogDetail
#博客编辑页面
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)
    #在登录状态下,正确发布博客
    def EditSucTest(self):
        self.driver.find_element(By.CSS_SELECTOR,"#title").send_keys("自动化测试创建1")
        time.sleep(3)
        #找到编辑区域,输入关键词(发现编辑区域不可操作)
        #菜单栏元素无法定位
        #博客编辑区域默认状态下不为空,暂不处理
        #直接点击发布按钮来发布博客
        self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
        time.sleep(1)
        url = self.driver.current_url
        assert "blog_list.html" in url
        #
        # WebDriverWait(self.driver, 15, 0.5).until(
        #     # 这里替换成你页面中"发布完成"的标识元素(比如成功提示、新页面加载等)
        #     EC.url_contains("blog_list.html")
        # )

        actual=self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div:nth-child(4) > div.title").text
        # 这里最好别用这个进行断言,因为这个博客系统会定期对数据库进去清除,之前发布的博客信息 也会被清除
        # assert actual =="自动化测试创建1"
        #屏幕截图
        BlogDriver.getScreenShot()
        time.sleep(3)

        # 错误发布博客(未登录状态下)
    def EditSucTestbyNoLogin(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")
        # 用户名
        self.driver.find_element(By.CSS_SELECTOR, "body > div.container-login > div > div:nth-child(2) > span")
        # 密码
        self.driver.find_element(By.CSS_SELECTOR, "body > div.container-login > div > div:nth-child(3) > span")
        # 提交
        self.driver.find_element(By.CSS_SELECTOR, "#submit")
        BlogDriver.getScreeShot()

5.7启动类(RunTest.py

python 复制代码
import time
from tests.BlogEditTest import BlogEdit
from tests.BlogDetailTest import BlogDetail
from tests.BlogListTest import BlogList
from tests.BlogLoginTest import BlogLogin
from common.Util import BlogDriver

#表示程序的执行入口
if __name__ == "__main__":
    #创建类对象,调用其方法
    # BlogLogin().LoginFailTest()
    # time.sleep(3)
    BlogLogin().LoginSucTest()
    time.sleep(3)
    #登陆成功之后就可以调用博客首页测试首页的用例(登录状态)
    BlogList().ListTestByLogin()
    #测试登录状态下的登录详情页
    BlogDetail().DetailTestByLogin()
    #博客编辑页面测试
    BlogEdit().EditSucTest()
    #执行浏览器的退出
    BlogDriver.driver.quit()

6.性能测试

6.1目录

6.2登录

6.3列表页

6.4详情页

6.5添加博客

6.6聚合报告

6.7Transaction per Second(吞吐量)

JMeter 中的吞吐量(Throughput) 是指在测试时间段内,系统成功处理的请求数量(或事务数)与时间的比值。

吞吐量是性能测试的核心指标之一(与响应时间、错误率、资源利用率并称四大核心指标),直接反映系统的处理能力和负载容量,吞吐量越高说明系统的处理事务能力越强。

6.8Response Times over Time(响应时间)

响应时间(Response Time),也叫延迟时间,是指从用户(或测试工具)发送一个请求开始,到接收到服务器返回的完整响应为止的总耗时,单位通常为毫秒(ms)。

响应时间是用户体验的直接体现,也是性能测试中最贴近用户感知的核心指标,地位与吞吐量同等重要。

6.9 Active Threads Over Time(随时间变化的活跃线程状态)

6.10性能测试报告

JMeter测试报告是一个全面而详细的文档,它提供了关于测试执行结果的详细信息,帮助用户全面评估系统的性能并进行性能优化。

性能测试报告

7.总结

7.1 响应时间表现:整体趋势 + 各接口详情

1. 整体趋势

测试总时长 1 分钟(12/14/25 5:16-5:17),整体平均响应时间 604.87ms,但存在明显的 "长尾请求":

  • 最大值达到 70751ms(约 70 秒),说明有极少数请求响应极慢;
  • 99% Line(99% 请求的响应时间)为 8769.03ms(约 8.8 秒),远超 "可接受" 阈值(通常 1-3 秒),用户体验会受影响。

7.2吞吐量和数据传输分析

1. 吞吐量
  • 整体吞吐量:23.47 Transactions/s(每秒处理 23.47 个请求);
  • 各接口吞吐量(按请求数占比):列表页(5.94)、添加博客(7.93)、登陆(8.10)、详情页(7.95)------ 接口间吞吐量分布较均衡,但整体吞吐量不算高(1 分钟仅处理 2262 个请求)。
2. 数据传输
  • 整体接收速率:96.71 KB/sec(每秒从服务器接收约 97KB 数据);
  • 各接口传输:列表页接收速率最高(91.49 KB/sec),说明该接口返回的数据量最大(可能是列表数据多),这也是其响应时间长的原因之一;
  • 发送速率整体仅 7.99 KB/sec,说明请求数据量很小,瓶颈不在请求端。

7.3 线程与并发分析

  1. 系统在 50 线程满并发下,处理能力不足:理论上 50 线程应支撑更高吞吐量,但实际仅 23.47,且列表页响应时间暴增,说明系统(尤其是列表页接口)无法承载 50 线程的并发压力。
  2. 线程启动 / 结束策略的合理性:
    • 启动策略(每 3 秒启动 5 个)是 "梯度加压",符合真实场景的流量增长;
    • 结束策略(每 1 秒结束 5 个)是 "快速减压",但测试总时长 60 秒下,结束阶段仅占 10 秒,主要压力集中在满并发的 33 秒,能有效暴露高并发下的瓶颈。
  3. 列表页是并发瓶颈:在 50 线程压力下,列表页的实际处理能力(5.94 Transactions/s)远低于其他接口,是限制整体并发能力的关键。

7.4 核心总结点

优势

  1. 数据发送量小,请求本身无冗余数据。
  2. 详情页、添加博客接口响应快且稳定,99% 请求延迟低于 300ms;
  3. 所有请求错误率为 0,系统稳定性较好,无请求失败;

风险点

  • 列表页是性能短板:平均响应超 2 秒,最大值达 70 秒,99% 请求超 35 秒,严重影响用户体验;
  • 整体存在长尾请求:99% Line(8.8 秒)远超用户可接受阈值,可能是系统资源(CPU / 内存)或依赖服务(数据库)在高并发下出现争抢;
  • 整体吞吐量偏低:1 分钟仅处理 2262 个请求,若业务高峰期并发更高,系统承载能力不足。

8.项目链接

https://gitee.com/xiaoshe-c-language/blog_auto_test.git

相关推荐
可信计算3 小时前
【算法随想】一种基于“视觉表征图”拓扑变化的NLP序列预测新范式
人工智能·笔记·python·算法·自然语言处理
张广涛3 小时前
【无标题】
python
爱笑的眼睛113 小时前
超越剪枝与量化:下一代AI模型压缩工具的技术演进与实践
java·人工智能·python·ai
yaoh.wang3 小时前
力扣(LeetCode) 14: 最长公共前缀 - 解法思路
python·程序人生·算法·leetcode·面试·职场和发展·跳槽
reasonsummer3 小时前
【办公类-18-07】20251215(Python)“口腔检查涂氟信息”批量生成打印(区名、学号、姓名、学校、班级、身份证、户籍、性别、民族)
开发语言·python
Rabbit_QL4 小时前
【PyTorch】detach:从计算图中切断梯度的原理与实践
人工智能·pytorch·python
晨曦5432104 小时前
MySQL与Python数学函数大比拼
python·mysql
一个无名的炼丹师4 小时前
【硬核实战】Python处理多源异构文档:从读取到智能信息提取的统一框架深度剖析
开发语言·python
Mr_Xuhhh4 小时前
JAVA期末重点
java·开发语言·python