ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

博客系统测试实战:从用例设计到接口自动化与性能验证

博客系统测试实战:从用例设计到接口自动化与性能验证 博客系统大概是软件测试新人能接触到的最理想的项目载体——功能边界清晰、业务不算复杂、前后端分离带来的问题足够典型而且每个人或多或少都用过博客理解成本极低。这个项目我在几个阶段反复打磨过从最初手写几十条测试用例到后来接入接口自动化、再扩展到性能与安全方面的验证沉淀下来不少可复用的经验。这篇文章就把这套实战过程完整记录下来包含测试范围怎么划、用例怎么设计、自动化脚本怎么写、面试时项目经验怎么讲适合正在找测试工作或者想提升测试实战能力的人参考。文章延续“沉淀中”的定位后续我还会持续补充新的测试模块和踩坑记录你可以把它当成一份随时更新的实战笔记来看。1. 项目背景与测试策略的定位1.1 为什么选择博客系统作为测试项目早几年带新人做测试项目时我见过很多人一上来就选“电商系统”或者“后台管理系统”结果需求文档看了好几天业务流程还没理清楚用例一张都写不出来。博客系统的好处在于它的业务逻辑足够直观注册、登录、写文章、改文章、删文章、评论、个人中心这些功能每个测试人员都作为用户用过不需要额外补业务背景可以把精力全部放在“怎么测”而非“业务是什么”上。从技术角度看现在主流的博客系统基本都采用前后端分离架构前端用 Vue 或 React后端用 Spring Boot、Django 这类框架接口走 RESTful API。这种技术栈正好贴合当前互联网公司的主流研发模式测试过程中涉及的接口联调、Token 鉴权、跨域问题、异步数据加载都是日常工作中高频出现的真实场景。用一个贴近生产环境结构的项目来练手远比用一个玩具项目更有价值。我选择的是一个开源的前后端分离博客系统技术栈大概是后端 Python Django MySQL前端 Vue Element UI接口采用 JWT 登录鉴权。部署在本地环境测试数据自己造环境完全可控。对测试来说可控环境意味着可以反复破坏、反复恢复这是很关键的条件。1.2 测试范围的划定与整体思路接到一个项目第一件事绝对不是打开页面乱点而是先划定测试范围。我把整个项目拆成四个维度来管理功能测试、接口测试、自动化回归、性能与安全验证。功能测试覆盖用户注册与登录、文章管理、评论系统、个人中心四个核心模块接口测试覆盖所有对外暴露的 RESTful API重点验证参数校验、状态码和业务逻辑自动化回归聚焦主流程包括“注册-登录-发布文章-添加评论”这条链路性能和安全验证则包括并发登录、接口响应时间、SQL 注入和 XSS 注入的基本检查。这个策略遵循了测试金字塔的思路越底层、越频繁执行的内容投入越高越上层、越偏体验的内容投入相对少。博客系统这类中小型项目没必要一上来就搭建大规模压测平台用小而实的方案把核心链路覆盖住比追求工具多而全更有效。2. 博客系统功能测试核心实操2.1 登录功能测试用例设计实战登录功能是整个项目的门面也是测试人员面试时最高频被问到的模块。无论项目怎么换登录的测试思路是通用的这里我以博客系统登录为例把用例拆给你看。我先梳理了一下登录接口的参数用户名、密码、验证码后端返回一个 Token前端把 Token 存在本地后续所有请求都带上它。设计用例的时候我从正常流程、异常流程、安全角度三个维度去铺用例编号测试步骤预期结果优先级LOGIN-001输入正确用户名和密码点击登录登录成功跳转首页并返回TokenP0LOGIN-002输入正确的用户名、错误密码登录失败提示“用户名或密码错误”P0LOGIN-003输入不存在的用户名登录失败提示同样文案不暴露用户是否存在P1LOGIN-004用户名为空密码正确登录按钮置灰或提示“请输入用户名”P1LOGIN-005用户名正确密码为空提示“请输入密码”P1LOGIN-006用户名和密码均包含特殊字符如 OR 11登录失败不返回任何数据验证 SQL 注入防护P1LOGIN-007连续输入错误密码5次账号锁定或强制输入验证码30分钟内不可登录P1LOGIN-008登录后等待超过Token过期时间再操作跳转登录页提示“登录已过期”P1LOGIN-009输入正确账号密码勾选“记住我”后登录关闭浏览器重开仍保持登录状态P2LOGIN-010两个浏览器同时用同一账号登录后登录一方成功前一方Token失效被踢下线P2这里有几个细节需要特别注意。第一是“用户名不存在”和“密码错误”必须返回一样的提示这是防止用户枚举的标准做法我在测试时发现很多项目会在这一块留漏洞。第二是 Token 过期机制JWT 本身无状态过期时间在服务端配置前端要能识别 401 状态并跳转登录页这是联调阶段经常出的问题。第三是“记住我”功能不少系统只是把过期时间拉长并没有真正落地刷新机制需要实测分辨。我把这组用例按照 P0 必须全部通过、P1 尽量修复、P2 可延后修复的优先级标准来管理实际执行过程中P0 用例必须全绿否则项目不允许进入下一阶段。2.2 文章管理模块的测试要点博客系统的核心是文章这个模块虽然界面简单但涉及的逻辑状态比较多。我梳理出文章发布、编辑、删除、列表加载四条业务链路每条链路都有几个容易踩坑的点。先看文章发布。页面上的字段包括标题、正文、分类、标签、封面图、是否公开、是否置顶。这里最容易被忽视的是“草稿箱”和“发布”两个状态之间的切换。我设计的用例中有一条是“保存草稿后重新编辑并直接发布确认文章状态和链接是否正确生成”实际执行时发现草稿文章在数据库里没有独立的发布时间字段直接发布后首页显示的时间是更新的时间而非创建时间这是一个典型的低级数据缺陷。标题和正文的边界值也值得单独列一组。标题最短几个字符、最长多少字符、是否允许空标题、正文是否允许为空这些都必须参照接口文档拉出边界值来测。我实测发现标题长度为 1 个字符时可以发布但列表页渲染时因为样式问题直接崩了这就是前后端数据校验不一致导致的线上事故测试时最容易漏。文章编辑权限也是重点。非文章作者访问编辑页时页面虽然不显示编辑按钮但直接通过 URL 拼接/articles/3/edit是否能打开很多前端只是把按钮隐藏了后端却没有做权限校验这是典型的越权漏洞。测试时一定要绕过 UI 层面直接构造请求去验证后端逻辑。列表加载方面需要注意分页参数。首页每页显示 10 篇文章那第 11 篇是不是出现在第二页把页码参数改成 -1 或者 9999 会发生什么我在这个项目里发现页码传 9999 时返回了空数组但状态码是 200而传 -1 时直接抛了 500属于后端参数校验缺失。2.3 评论与个人中心的边界场景评论模块看起来简单但边界场景特别多。未登录用户能不能评论登录用户能不能给自己文章评论评论内容超长怎么处理评论里包含 HTML 标签会不会被转义这些问题每条都可以展开成一组用例。我最看重的是评论内容的 XSS 防护测试。在评论里输入一段scriptalert(xss)/script提交如果前端直接渲染了这段脚本说明存在存储型 XSS 漏洞。这个测试在真实项目中会直接判定为 P0 缺陷因为它会影响所有访问该页面的用户。我在博客系统里实测富文本编辑器和普通评论框的处理方式不一样普通评论框做了转义但富文本编辑器的内容未经彻底过滤XSS 可以绕过后来反馈给开发在服务端加了白名单标签校验才修复。个人中心的资料修改测试重点放在头像上传和后端字段联动上。头像上传要关注文件类型、文件大小、文件命名方式实测发现用 PNG 格式但把后缀改成 JPG 也能上传说明后端只校验了文件扩展名而没有校验真实文件头这样会带来安全风险。地址、昵称等字段修改后文章列表页作者显示是否同步更新也是一个经常被忽略的场景。个人中心这类模块最值得投入的是“多模块联动”的用例设计。单独测某个页面的功能没有任何问题一旦触发跨模块交互就暴露问题这是测试思维要从“单页面视角”升级到“全链路视角”的关键一步。3. 接口测试与自动化脚本落地3.1 API 接口测试方案设计博客系统的接口测试我建议遵循“先手工、后自动、再接入持续回归”的节奏。第一步先用 Postman 把每个接口的手工调用跑通第二步再写 Python 脚本做自动化。为什么推荐 Postman 而不是直接上代码因为接口测试的第一步是了解接口语义包括请求方法、请求头、参数体、返回结构。Postman 能直观展示请求和响应还能把接口按模块建 Collections 分组适合建立接口全景图。我一般会把下面这张表作为接口测试的基准画出来模块接口路径方法鉴权核心验证点登录/api/loginPOST无返回Token、登录失败错误码注册/api/registerPOST无用户名唯一性、密码强度校验文章列表/api/articlesGET无分页参数、分类过滤、标签过滤文章详情/api/articles/{id}GET可选文章状态、浏览量累加发布文章/api/articlesPOST需Token字段必填、权限校验编辑文章/api/articles/{id}PUT需Token非作者编辑返回403删除文章/api/articles/{id}DELETE需Token非作者删除返回403添加评论/api/articles/{id}/commentsPOST需Token评论内容校验评论列表/api/articles/{id}/commentsGET无分页与排序规则接口测试关注的核心点可以总结成七个状态码、返回数据格式、错误信息提示、参数校验、业务逻辑、权限控制、性能基线。每个接口至少覆盖正常返回 200、参数错误返回 400、未授权返回 401、无权限返回 403、资源不存在返回 404 这五类典型情况。3.2 Python 自动化测试脚本实现自动化框架我选的是 pytest requests 这个组合原因很直接pytest 的参数化和 fixture 机制非常成熟requests 简单易用两者组合维护成本低几乎成了 Python 接口自动化的事实标准。项目结构我按照模块和功能分开组织方便后续扩展blog_test/ ├── conftest.py ├── config.py ├── apis/ │ ├── login_api.py │ ├── article_api.py │ └── comment_api.py ├── tests/ │ ├── test_login.py │ ├── test_articles.py │ └── test_comments.py └── reports/conftest.py 里最关键的是登录 Token 的 fixture。我在后面跑用例时发现如果每个测试文件都单独写登录逻辑代码冗余严重且维护困难所以直接抽了一个 session fixture 出来import pytest import requests from config import BASE_URL, USERNAME, PASSWORD pytest.fixture(scopesession) def token(): 登录获取Token整个会话只执行一次 url f{BASE_URL}/api/login payload {username: USERNAME, password: PASSWORD} resp requests.post(url, jsonpayload) assert resp.status_code 200 return resp.json()[data][token] pytest.fixture() def auth_headers(token): 构造带鉴权的请求头 return {Authorization: fBearer {token}}登录接口的用例参数化用 pytest 的 parametrize 标记。这里有一个很实用的技巧异常用例组的数据不只写一组要把空值、超长值、特殊字符都塞进去参数化以后代码量不增加覆盖维度却能拉满import pytest import requests from config import BASE_URL class TestLogin: pytest.mark.parametrize(payload, expected_code, expected_msg, [ ({username: admin, password: 123456}, 200, 登录成功), ({username: admin, password: wrong}, 400, 用户名或密码错误), ({username: no_such_user, password: 123456}, 400, 用户名或密码错误), ({username: , password: 123456}, 400, 请输入用户名), ({username: admin, password: }, 400, 请输入密码), ({username: admin, password: OR 11}, 400, 用户名或密码错误), ]) def test_login(self, payload, expected_code, expected_msg): url f{BASE_URL}/api/login resp requests.post(url, jsonpayload) data resp.json() assert resp.status_code expected_code assert data[message] expected_msg这里要提醒一下参数化用例的预期结果必须来自接口文档或者开发确认不能自己拍脑袋。我在早期犯过一个错误想当然认为参数缺失应该返回 400实际系统返回的是 500跟进开发后发现那是他们的已知缺陷而不是预期行为。测试用例必须记录真实结果不能为了与设计契合而篡改预期。文章接口的自动化要重点覆盖权限校验。发布、编辑、删除都属于需要鉴权的高危操作我没有 Token 去调接口时预期返回 401有 Token 但操作别人的文章时预期返回 403。这套用例的断言逻辑非常固定跑一遍能快速验证权限体系是否完整。测试报告我用 pytest-html 生成执行命令加一行参数就行pytest tests/ -v --htmlreports/report.html --self-contained-html跑完打开 HTML 报告用例通过率、失败堆栈、执行时间一目了然。自动化不是跑完就完关键是定时回归——我搭了一个简单的定时任务每天晚上把主流程用例跑一遍第二天早上看报告这样能第一时间发现开发的改动是否破坏了原有功能。3.3 UI 自动化与回归策略的取舍接口自动化能覆盖大部分逻辑校验但页面交互层面的回归还得靠 UI 自动化。博客系统的 UI 自动化我选的是 Selenium配合 ChromeDriver原因是资料多、社区成熟、遇到问题容易搜到解决方案。我梳理出三条最核心的 UI 用例用户登录后成功跳转首页、登录后创建文章并立即出现在列表页、在文章详情页添加评论并显示成功。实现上主要依赖元素定位与显式等待比如登录按钮用 ID 定位文章列表用 XPath 定位。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 def test_create_article(): driver webdriver.Chrome() driver.get(http://localhost:8080/login) driver.find_element(By.NAME, username).send_keys(admin) driver.find_element(By.NAME, password).send_keys(123456) driver.find_element(By.ID, loginBtn).click() # 等待跳转完成 WebDriverWait(driver, 10).until(EC.url_contains(/home)) # 进入发布文章页 driver.find_element(By.LINK_TEXT, 写文章).click() WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, articleTitle))) driver.find_element(By.ID, articleTitle).send_keys(自动化测试文章标题) driver.find_element(By.CLASS_NAME, ql-editor).send_keys(这是自动化测试写的正文内容) driver.find_element(By.ID, submitBtn).click() # 发布成功跳转到文章详情页断言标题出现 WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, article-title))) assert driver.find_element(By.CLASS_NAME, article-title).text 自动化测试文章标题 driver.quit()UI 自动化最大的痛点是稳定性元素加载慢一点、网络波动一下用例就挂了。我的做法是凡是能通过接口验证的逻辑一律不过度依赖 UI而 UI 用例只保留对业务主流程的冒烟回归数量控制在十条以内。这样既控制了维护成本又保证了核心链路不被漏测。4. 性能测试与环境搭建避坑指南4.1 测试环境搭建与数据准备性能测试和功能测试有一个很大的区别功能测试造几条数据就能跑性能测试必须有一个数据量像样的环境否则测出来的数字完全不可信。博客系统至少要有 5000 个用户、10000 篇文章、50000 条评论才能暴露出真实问题。我用一个 Python 脚本批量插入测试数据。需要注意直接调接口造数太慢几千条可能要好几分钟我选择直接操作 MySQL 写入基础数据然后防止意外改动了生产环境特意在测试库上执行。import pymysql import random conn pymysql.connect(hostlocalhost, usertest, password123456, databaseblog_test) cursor conn.cursor() for i in range(1, 5001): username fuser_{i} cursor.execute( INSERT INTO users (username, password, email) VALUES (%s, %s, %s), (username, e10adc3949ba59abbe56e057f20f883e, f{username}test.com) ) conn.commit() cursor.close() conn.close()还要强调一下性能测试之前必须做一件事把功能测试遗留的脏数据清理干净把所有日志和缓存清空。我第一次压测时忘了清理日志表结果压测结果里混进了大量磁盘 IO 干扰同样的并发量前后两次结果差了近一倍排查了半天才发现是日志涨太快拖慢了整个数据库。4.2 性能测试场景设计与瓶颈定位博客系统性能测试的重点场景有两个一个是登录接口的并发压测一个是文章列表页的并发读取压测。原因很明确登录是高频写操作、涉及密码校验和 Token 生成逻辑容易成为性能瓶颈文章列表是高频读操作、涉及多表查询和分页排序索引没建好就很容易拖垮接口。我用 JMeter 搭了一个最简单的线程组把登录接口配成 200 个线程并发持续运行 5 分钟。压测过程中不要只看平均响应时间这个指标很容易被极少数慢请求带偏。我同时关注三个核心指标P95 响应时间、错误率、TPS。实测下来第一次压测的结果就不太理想。P95 响应时间接近 4 秒错误率 2.3%TPS 只有 45。通过查看后端日志和慢 SQL 日志定位到两个问题一是用户表没有对 username 字段建立唯一索引登录时每次都要全表扫描二是数据库连接池配置太小高并发下线程都在排队租连接。开发加上索引、调大连接池后再次压测P95 降到 800 毫秒错误率归零TPS 涨到了接近 300。瓶颈定位的基本思路我归纳下来就是“从外到内、逐层排查”先看网络层有没有丢包再看 Web 服务器的连接数有没有打满然后看数据库慢 SQL、最后看应用本身的代码逻辑和缓存命中率。80% 的性能问题最终都指向数据库这是压测时优先关注数据库日志的原因。5. 项目经验的面试转化与简历提炼5.1 简历上的项目描述怎么写博客系统项目在简历上能不能成为加分项完全取决于你怎么描述。很多人写“负责博客系统测试写了测试用例发现了几个 bug”这种描述约等于没写。我看到比较有效的写法的公式是项目背景 我的职责 我做的具体工作 可量化的结果。我自己的简历这一段大概是这样的项目名称基于 Django Vue 的前后端分离博客系统测试 项目职责独立负责全流程测试包括需求分析、测试计划、用例设计、接口自动化与性能验证。 核心工作设计并执行测试用例 126 条覆盖登录、文章、评论、个人中心四个核心模块累计提交 Bug 43 个其中 P0/P1 缺陷 17 个搭建基于 pytest requests 的接口自动化框架实现登录、文章增删改查、评论共 38 条自动化用例回归时间从 2 小时缩短至 15 分钟使用 JMeter 完成登录接口并发压测定位并推动修复数据库索引缺失导致的 P95 响应时间超过 4 秒的性能问题。注意几个要点每个数字都必须真实假的经不起面试官追问“定位并推动修复”体现的是你的分析能力和沟通协调能力这是测试岗位很看重的一点核心名词要具体写清楚工具和工程量避免空泛。5.2 面试高频问题与应答思路面试官看到你简历上有测试项目基本会围绕几个角度去问我提前把自己的思路整理了一遍。“你怎么测登录功能”——这个问题我在前面已经拆过用例应答时要从功能用例设计、安全用例设计、接口自动化三个层面展开。先讲正常和异常场景再补充 SQL 注入、暴力破解、Token 过期这些安全点最后提一句接口自动化是怎样覆盖这些场景的。层层递进的方式面试官会觉得你的思路是完整的。“接口测试和功能测试有什么区别”——重点落在测试对象和关注维度不同上。功能测试关注用户视角的交互体验接口测试关注数据维度的正确性、状态码、响应时间、鉴权逻辑。接口测试能提前暴露问题、节省测试成本但功能测试能保证最终用户体验两者互补。“发现一个 bug 怎么定位是前端还是后端”——这是我面试时被问得最多的问题。我的通用做法是打开浏览器开发者工具切到 Network 面板看请求和响应。如果请求没发出或者参数格式不对大概率是前端问题如果请求正常但返回数据错误或状态码异常则要往后端排查。如果是页面渲染问题就要看前端控制台有没有报错。“测试用例设计有没有什么方法论”——可以从等价类划分、边界值分析、场景法、正交试验这几个术语入手配合博客系统的具体例子来说明。比如密码长度的边界值、登录场景的正常流和异常流方法论本身不难难的是能不能自如地把方法和项目案例结合起来讲。6. 常见问题与实测排查记录6.1 环境搭建与联调问题速查整个实战过程中我在环境层面踩过不少坑挑几个有代表性的列出来遇到相同问题可以直接对照处理。问题现象根本原因解决方式npm install 频繁报错或下载极慢默认源访问国外仓库不稳定切换为国内镜像源命令npm config set registry https://registry.npmmirror.com前端页面能打开但登录后拿不到用户信息跨域请求未正确配置检查后端是否开启 CORS 并允许携带 Authorization 请求头数据库中文乱码建库时字符集不是 utf8mb4重建数据库建表语句明确指定 CHARACTER SET utf8mb4接口返回 401 但请求头明明带上了 TokenToken 有效期内但格式错误确认是否缺少 Bearer 前缀或 Token 中间有空格被截断前端调接口报错“Failed to fetch”后端服务未启动或端口不一致检查后端监听端口用 curl 直接验证接口连通性这类环境问题在测试初期会耗掉大量时间我现在的习惯是部署完环境后先写一个一键自检脚本把服务状态、数据库连接、关键接口连通性统一验一遍报错信息提早暴露后面就能专心做测试设计而不是折腾环境。6.2 真实缺陷复盘与 Bug 单编写最后分享几个我在这个项目中印象比较深的缺陷案例。这些案例的价值不在于缺陷本身而在于它们揭示了测试设计时容易被忽略的维度。第一个是越权编辑缺陷。我在文章编辑页点击 F12手动修改请求里的文章 ID 为别人文章的数据后重新发送接口竟然返回成功。这个问题的根源是后端没有校验当前登录用户是否为文章作者属于典型的水平越权漏洞。测试过程中必须主动绕过 UI 层去验证后端接口的鉴权逻辑。第二个是存储型 XSS。在我往评论框提交img srcx onerroralert(1)内容后其他用户打开文章详情页时弹窗触发。问题出在后端只做了换行过滤而没有对 HTML 标签做严格白名单校验评论内容在渲染时被浏览器执行了。这个缺陷直接标为 P0 并推动开发转义和过滤之后又做了第二轮回归确认修复生效。第三个是分页参数异常。文章列表接口传入page-1per_page0时直接返回了 500而且后端日志里显示 SQL 报错“limit -1”。这类参数边界问题只在外部输入不可信时才会暴露测试人员应该在所有涉及数值型参数的接口上都补一组负数、零、超大的用例。发现缺陷后Bug 单的编写质量也很重要。一份合格的 Bug 单必须包含标题简洁描述现象、前置条件、复现步骤、预期结果、实际结果、环境信息、严重程度和优先级、附带截图或日志。我见过大量因为 Bug 单写不清楚导致开发无法复现而被退回的案例信息越完整沟通成本越低测试人员的专业性也就体现得越明显。这一轮博客系统测试项目从环境部署到用例设计、从接口自动化到性能排查、再到面试经验沉淀我把能落地的细节都整理在这里了。项目还在持续迭代我也会继续补充新的测试模块和踩坑记录。“沉淀中”这三个字不只是标题后缀更是我实际操作中一直遵循的工作节奏——每个阶段把经验留下来、把问题复盘透、把方案固化下来下一次遇到类似项目时就能少走很多弯路。
返回列表