1. 项目背景与测试目标
这个个人博客系统是我利用业余时间开发的一个全栈项目,主要面向技术爱好者分享学习笔记和开发经验。系统采用前后端分离架构,前端基于Vue.js+ElementUI,后端使用Spring Boot框架,数据库选用MySQL 8.0。在完成核心功能开发后,我意识到一个完整的项目必须包含严谨的测试环节,于是设计了这套测试方案。
测试的主要目标有三个:验证基础功能是否完整可用(如文章发布、分类管理、评论互动);评估系统在压力下的稳定性(特别是文章列表页的高并发访问);检查常见Web安全漏洞(XSS、CSRF等)。这些测试不仅能发现潜在问题,也为后续迭代提供了优化方向。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 测试环境搭建
2.1 硬件配置
- 开发机:MacBook Pro M1/16GB(本地测试用)
- 服务器:阿里云ECS/2核4G/5M带宽(压力测试用)
- 数据库:阿里云RDS MySQL 8.0/1核2G
2.2 软件环境
bash复制# 前端环境
Node.js v16.14.0
npm 8.3.1
vue-cli 4.5.15
# 后端环境
JDK 11.0.12
Spring Boot 2.6.3
MyBatis-Plus 3.5.1
2.3 测试工具选型
- 功能测试:Postman + Swagger UI
- 压力测试:JMeter 5.4.1
- 安全测试:OWASP ZAP 2.11.1
- 前端测试:Jest + Vue Test Utils
提示:环境配置时最容易忽略的是各组件版本兼容性。比如Spring Boot 2.6.x与MyBatis-Plus 3.5.x存在事务注解的兼容问题,需要额外配置。
3. 功能测试实施
3.1 核心功能测试用例
| 模块 | 测试场景 | 预期结果 | 实际结果 |
|---|---|---|---|
| 用户认证 | 错误密码登录 | 返回401错误 | 符合预期 |
| 文章管理 | 发布含Markdown的文章 | 正确渲染格式 | 表格转义失败 |
| 评论系统 | 回复嵌套评论 | 形成对话树 | 层级显示错位 |
| 搜索功能 | 中英文混合搜索 | 返回相关结果 | 中文分词不准 |
3.2 典型问题排查案例
在测试文章发布功能时,发现包含表格的Markdown内容渲染异常。通过Chrome开发者工具检查发现:
- 前端收到的JSON数据中表格符号
|被转义为\u007c - 排查后端接口,发现Spring Boot默认的Jackson配置开启了字符转义
- 解决方案:在
application.yml中添加配置:
yaml复制spring:
jackson:
generator:
escape-non-ascii: false
4. 性能压力测试
4.1 JMeter测试方案设计
-
线程组:500并发用户,持续10分钟
-
测试接口:
- GET /articles (文章列表)
- GET /articles/{id} (详情页)
- POST /comments (提交评论)
-
监听器配置:
- 聚合报告
- 响应时间图
- 每秒事务数
4.2 关键测试数据
| 指标 | 文章列表页 | 文章详情页 | 评论提交 |
|---|---|---|---|
| 平均响应时间 | 328ms | 215ms | 892ms |
| 错误率 | 0.2% | 0% | 1.8% |
| 吞吐量 | 1423/sec | 1856/sec | 621/sec |
4.3 性能优化实践
发现评论接口在高并发下出现超时,通过Arthas工具诊断发现:
- 评论入库前有敏感词过滤的正则匹配
- 敏感词库采用500+条正则表达式逐条匹配
- 优化方案:
- 改用Trie树数据结构存储敏感词
- 引入本地缓存(Caffeine)
- 异步处理审核逻辑
优化后评论接口吞吐量提升至2100/sec,错误率降为0.3%。
5. 安全测试与防护
5.1 OWASP ZAP扫描结果
扫描发现三个中危漏洞:
-
XSS漏洞:评论内容未过滤
<script>标签- 修复方案:前端使用DOMPurify,后端补充HtmlUtils.htmlEscape
-
CSRF风险:关键操作未校验Token
- 修复方案:启用Spring Security的CSRF防护
-
敏感信息泄露:Swagger接口文档暴露内网IP
- 修复方案:添加
@Profile("dev")限制
- 修复方案:添加
5.2 手动渗透测试案例
尝试通过Burp Suite修改文章ID参数进行越权访问:
- 普通用户A的文章ID为100
- 修改请求参数为ID=101(属于用户B)
- 系统返回403 Forbidden(已修复)
关键实现代码:
java复制@PreAuthorize("#article.userId == authentication.principal.id")
public Article getArticle(Long id) {
return articleMapper.selectById(id);
}
6. 前端专项测试
6.1 组件单元测试
使用Jest测试Markdown渲染组件:
javascript复制test('should render table correctly', () => {
const wrapper = mount(MarkdownViewer, {
props: { content: '|Header|\n|------|\n|Cell|' }
})
expect(wrapper.find('table').exists()).toBe(true)
})
6.2 浏览器兼容性问题
- Edge浏览器:CSS变量在旧版本不支持
- 解决方案:添加PostCSS的autoprefixer
- Safari:ES2020语法报错
- 解决方案:调整Babel配置
7. 测试报告生成与解析
7.1 自动化报告生成
整合Allure报告框架,在Jenkins流水线中配置:
xml复制<plugin>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-maven</artifactId>
<version>2.10.0</version>
</plugin>
生成报告包含:
- 用例执行趋势图
- 失败用例的请求/响应详情
- 系统环境信息
7.2 关键指标可视化
使用Grafana搭建监控看板,主要监控:
- API成功率(99.95% SLA)
- 平均响应时间(<500ms)
- 数据库连接池使用率
8. 经验总结与后续计划
在实际测试过程中,有几个容易被忽视但至关重要的点:
-
测试数据准备:不要只用"完美数据",要构造各种边界情况:
- 超长文章标题(测试前端截断)
- 特殊字符评论(测试XSS防护)
- 重复提交订单(测试幂等性)
-
日志记录:关键测试步骤要留下可追溯的日志:
java复制@Test
void testArticlePublish() {
log.info("开始测试文章发布流程...");
// 测试逻辑
}
- 环境隔离:压力测试一定要在独立环境进行,避免影响开发数据库。
后续计划引入Selenium做端到端测试,并搭建K6性能测试平台实现持续监控。对于个人项目而言,建立完整的测试体系不仅能提升代码质量,更是对工程化能力的很好锻炼。
