1. 为什么拿博客系统当测试练习项目
做软件测试这行,最尴尬的事就是简历上“项目经验”一栏空空如也。我见过不少转行或者应届的朋友,测试理论背得滚瓜烂熟,什么等价类、边界值、判定表张口就来,可一到面试官问“你测过什么项目?具体怎么测的?”就卡壳了。为什么?因为大部分人的测试经历要么是网上找个小 Demo 随便点点,要么就是培训机构给你个后台管理系统模板,做完你自己心里都没底。
后来我慢慢意识到一个问题:练手项目的选择太关键了。第一,这个项目要能装起来、能跑起来,不能光看文档;第二,功能要足够多,能覆盖常用的测试场景;第三,最好贴近真实业务,别搞那种纯玩玩的案例。综合下来,博客系统是最合适的选择之一。
博客系统这东西,表面看着简单——不就是发文章、看文章嘛。但仔细拆下来,它的功能密度相当高:注册登录、个人中心、文章发布与编辑、分类与标签、评论回复、搜索分页、权限控制、图片上传,运气好点的还带个后台管理。这些功能几乎把web测试里最常见的题型都串起来了,和电商系统那套“商品—购物车—订单”比起来,业务逻辑不复杂,但覆盖面一点不差。
更重要的一点是,博客系统的技术实现不受限。你有后端基础,可以用 Django 或者 Spring Boot 自己写一个;你只想专注测试,就能直接部署一套开源博客,或者用之前培训班的电商项目改一改。部署完之后,你手里就有一个真实可操作的系统,黑盒测试、接口测试、自动化脚本、性能摸底全都有得玩。“沉淀中”这个状态其实挺好的,项目不是一次性做完就扔,而是每学一个新测试技能,就回来在博客系统上练一遍。
这篇内容我就按我实际做过的路线来讲,从环境搭建、功能用例设计、接口自动化、到最后的简历沉淀,给大家一个能直接照着操作的完整路径。
1.1 博客系统功能地图:先知道要测什么
拿到一个项目别急着点鼠标,先画功能地图。我习惯用一张 Excel 表把模块、子功能、优先级列出来,像这样:
| 模块 | 子功能 | 优先级 | 典型测试重点 |
|---|---|---|---|
| 用户认证 | 注册、登录、退出、找回密码 | 高 | 密码策略、会话管理、验证码 |
| 用户信息 | 个人资料编辑、头像上传 | 中 | 文件类型/大小限制、字段校验 |
| 文章管理 | 发布、编辑、删除、草稿 | 高 | 权限校验、状态流转、数据一致性 |
| 分类标签 | 新增、修改、关联文章 | 中 | 删除约束、引用关系 |
| 评论系统 | 发表评论、回复、删除 | 高 | SQL 注入、敏感词、归属校验 |
| 搜索分页 | 关键词搜索、分页浏览 | 中 | 分页边界、搜索条件组合 |
| 后台管理 | 用户管理、文章审核、数据统计 | 高 | 越权操作、数据展示完整性 |
这套地图做出来,你就知道这个项目要往哪些方向使劲。博客系统不是一个 CRUD 拼凑的玩具,它自带用户体系,意味着“鉴权”是一大测点;它有评论和搜索,意味着“安全测试”也有的放矢;它有草稿和发布状态,意味着“状态流”的测试有深度。
我见过一些人拿博客练手,测来测去就是“发一篇文章试试”“评论一条试试”,这不是测试,是玩耍。功能地图的意义在于让你带着清单去执行,知道这个系统哪些地方容易出问题,哪些地方值得写自动化用例。
1.2 技术栈选型与测试方向的关系
博客系统的主流实现方式有几种:纯前端静态站(如 Hexo、VuePress)、带后端接口的完整 web 应用(Spring Boot + Vue 或 Django + Bootstrap)、以及直接部署开源 CMS 系统。做测试练习,首选是前后端分离的完整应用,因为你能同时练到 UI 测试和接口测试。
选型的时候有个原则:不要追求多高端的框架,而是优先考虑你环境能跑起来、文档多、社区活跃的方案。我自己之前用的是 Spring Boot 搭建的后端 + Vue 管理后台,前端展示站走 nginx 静态资源,数据库用的 MySQL,缓存偶尔用一下 Redis。这套组合的好处是贴近国内大多数公司的实际技术栈,面试聊起来有共同语言。
如果你是纯测试方向、后端功底一般,部署现成博客系统也完全可行。GitHub 上很多开源的博客项目,比如用 Spring Boot 写好的整套部署包,把 MySQL 启动、导入 sql 文件、改几个配置就能跑。关键是你要知道部署过程发生了什么事情,而不是一路下一步下一步。哪怕项目不是你写的,你也要能说清楚哪个是前端、哪个是后端、请求链路是怎么走的。测试人员的价值恰恰在这里——不懂技术细节的测试发现问题只会截图,懂技术细节的测试能手把手把问题复现给开发看。
2. 项目部署与测试环境准备
环境搭建是测试项目的第一道坎,也是很多人最容易放弃的地方。你想想这个场景:博主在教程里写“下载 JDK、配置环境变量、启动 MySQL、倒入数据库脚本”,你以为五步就结束了,实际做起来每个环节都能蹦出两个幺蛾子。环境装不上,后面的测试全白谈。
我把部署博客系统的过程拆成了一份清单,按顺序做完,踩坑概率会低很多。
2.1 环境清单与一步步部署步骤
第一步,准备基础软件:
- JDK 1.8(最低要求 1.8,很多老项目对高版本 JDK 兼容并不好)
- MySQL 5.7 或 8.0(取决于项目说明,5.7 更稳)
- Redis 5.0+(如果项目用到缓存和验证码存储)
- Node.js + npm(前端构建用)
- Nginx(做反向代理和静态资源服务)
这些工具都有 Windows 安装包,对新手友好。装完 JDK 之后命令行输入java -version能出版本号,MySQL 装完记得把服务启动,能通过 Navicat 或者命令行连上库就行。这里我先说一个最常见的坑:MySQL 8.0 的认证插件改了,如果你是 8.0,连接时报 “Public Key Retrieval is not allowed”,记得在连接串里加allowPublicKeyRetrieval=true&useSSL=false。
第二步,拿到项目代码。用 git clone 把项目拉到本地,千万别手动下载 zip 包,因为后续你可能需要切换分支、拉取最新代码,习惯命令行操作更高效。
第三步,初始化数据库。项目仓库里一般有个sql目录,里面放着建表脚本和初始数据。在 Navicat 里新建一个数据库,字符集选 utf8mb4(不然后面存表情符号要出乱子),然后运行 sql 脚本。执行完看看表数量对不对,比如博客系统一般会有 user、article、comment、tag 等十来张表,如果只有零星几张,八成是脚本执行不完整。
第四步,修改后端配置。打开项目里的application.yml或application.properties,把数据库 username/password 改成你自己的,Redis 地址端口确认没问题。有些博客系统还涉及文件存储目录,需要配置一个本地路径来存上传的图片。
第五步,启动前端和服务端。前端一般用npm install装依赖,然后npm run dev或npm run build跑起来;后端用 IDE 启动主类,或者用mvn spring-boot:run。全部启动后浏览器访问首页,注册一个账号试着登录,能跑通就算环境搞定。
注意:环境搭建时尽量保持软件版本的“刚刚好”,JDK 不见得越新越好、MySQL 也不见得要最新。项目 README 里写了什么版本就按什么版本装,这是新手最容易犯的错误——用 JDK17 跑一个 JDK8 的老博客项目,启动直接报 Caused by: java.lang.UnsupportedClassVersionError,你还以为是代码写错了。
2.2 环境搭建中的三个高频坑
第一个坑是端口被占用。后端项目默认跑 8080 端口,你本地如果装过其他服务(比如 Zabbix 或者另一个 Java 进程),启动会报 Address already in use。处理方式很简单,找到被占用的端口进程,或者改项目配置换个端口。在 Windows 上用netstat -ano | findstr 8080查进程 PID,再在任务管理器里结束它。
第二个坑是数据库连接失败。报 Communications link failure 的大多情况是 MySQL 服务没启动,或者是密码不对。还有一种情况是数据库账号没有远程访问权限,本地连没事,换台机器就连不上。博客系统项目其实不需要分布式部署,就本地单机跑,所以权限问题较少出现,但你在简历写到“部署了博客系统”以后,面试官可能问你怎么把系统放到服务器上,这里记得留意。
第三个坑是前端跨域。前后端分离的项目,前端跑 8081,后端跑 8080,前端请求后端接口会被浏览器拦截,报 “Access-Control-Allow-Origin”。大部分项目后台已经配了 CORS 过滤器,如果没配,你需要手动加一下,或者用 Nginx 做一层反向代理把/api转到后端服务上。
环境搭好之后我建议做一个冒烟测试:走一遍“注册—登录—发表一篇文章—发起评论”的完整链路。这个冒烟不是随便点点,而是确认主流程没有基础性不可用的问题,为后面写用例打底。冒烟都过不了的项目,你别急着一头扎进用例设计里,先把环境修好再说。
3. 功能测试用例设计与登录专项实战
功能测试是软件测试的地基,也是博客系统项目里练得最扎实的部分。我在做这个项目的时候,大概手工执行了 200 多条用例,覆盖了核心功能。可能有人觉得,200 条是不是太多了?其实当你按照模块去拆,二百条真的不多。
拿“登录”这一个功能来说,很多人就只能想到“输对的账号密码能进去、输错密码进不去”,但现实业务里的登录远比你想的要复杂:账号存不存在、密码错到什么程度算错、密码输错几次要不要锁定、空值和空格怎么处理、能不能在别处登录同一账号、登录之后回退浏览器后退会不会出现会话不同步……每一个问号都是一个测试点。
3.1 登录功能的用例设计与测试数据
登录是博客系统最常见的入口,也是安全要求最高的模块。我列一下我当时设计的用例维度:
- 正常登录:正确的账号 + 正确的密码,验证能跳转到首页且显示用户名
- 密码错误:正确账号 + 错一次 / 连续错三次,观察提示一致性和是否有锁定机制
- 账号不存在:用未注册的手机号或邮箱登录,提示到底是走“用户不存在”还是“密码错误”
- 输入校验:空用户名、空密码、账户名前后带空格、密码前后带空格、纯空格字符
- 长度边界:账号超过最大长度、密码超过最大长度
- 会话相关:登录成功后刷新页面、回退上一页、多标签页同时登录同一个账号
- 安全角度:SQL 注入尝试、万能密码尝试、错误密码登录频率限制
这里我实际执行时踩过一个值得说的点:很多博客系统的登录接口在用户名不存在和密码错误时返回的信息不一样,一个返回“用户不存在”,一个返回“密码错误”。从产品体验上讲这等于帮黑客指点方向,正确的做法是两个场景统一返回“账号或密码错误”。我当时把这个提成了 bug,开发的回应是“这是老代码设计如此”,这时候就看测试怎么沟通了。我的建议是不要硬杠,先按需求文档来,需求文档没写就按照行业常识提建议级 bug,开发不改你记录在案就行。
边界值的计算也要刻意练。博客系统一般规定用户名最少 3 个字符、密码最少 6 位,在测试数据设计时要有三组:最小值(3 位和 6 位)、小于最小值(2 位和 5 位)、大于最大长度(比如用户名最长 20 位,就往里填 21 位)。实际测试发现很多同学只测了一个错误场景,边界值整组的覆盖率低,这是功能测试里不太应该出现的疏忽。
验证码功能也要测。有些博客登录自带图片验证码,你至少要验证三件事:验证码正确时能通行;验证码错误或过期时被拒绝;刷新页面或者点击验证码图片后旧码立即失效。如果你在测试环境想让验证码功能暂时屏蔽,可以看看配置里有没有开关,或者临时把验证码校验逻辑注释掉,但这种改动只能在自己环境做,不要污染公共测试环境。
3.2 文章管理与评论模块的测试要点
登录测完之后,博客系统的重头戏就是文章管理。文章模块有一个核心概念叫“状态机”:草稿、已发布、已下线。不同状态下的文章,在前台和后台的表现都不同。我设计用例时按照状态流来梳理:
- 新建文章保存为草稿,前台是否不可见
- 草稿补充内容后发布,前台是否实时可见
- 已发布文章编辑并保存,前台内容是否同步更新
- 已发布文章下线,前台是否还能访问,URL 直接访问是否会 404
- 删除文章后,评论是否随之清理
这些用例看起来简单,实际执行时反而容易漏掉一个细节点:下线的文章如果被加入过收藏,或者被搜索引擎收录,直接访问详情页应该返回什么状态码。要么 404 重定向,要么显示“文章不存在”,不能出现 200 状态码带空壳页面,这对 SEO 和用户体验都不友好。
评论模块的测试重点和文章不太一样,它更偏内容安全。我通常从以下角度设计评论用例:
- 正常发表:登录用户在文章下添加评论,前台能显示
- 回复场景:用户 A 评论后,用户 B 回复 A 的评论,楼层关系是否正确
- 未登录评论:前台的输入框是否隐藏,还是点了之后才跳转登录
- 空评论、超长评论:系统是否做了长度限制
- 敏感词过滤:如果系统有敏感词库,测试命中敏感词时是否有提示
- 防重复提交:同一内容快速点击多次提交,会不会出现多条重复评论
- 删除权限:作者能否删除别人在自己文章下的评论,管理员能不能删任何评论
测评论的时候有一个隐藏考点:评论提交后是立即生效,还是要经过后台审核。如果走审核流程,你要把“作者本人看得到自己的评论”和“其他用户看不到未通过审核的评论”分开验证。这块不搞明白,你接口自动化的时候会把自动化的断言都写错。
文章模块还有一块是上传图片和头像。这块用例设计要覆盖文件类型限制(非法后缀、伪装后缀)、大小限制(边界内、超出几个字节)、文件名特殊字符、重复文件名覆盖等。有一次我在做博客项目时就发现,文章封面图上传成功之后文件名被重新生成了,但原图路径带了中文字符,在 IE 浏览器下直接裂图。这个案例我在面试时也提过,面试官普遍觉得这种问题能找到说明测试做得细。
4. 接口测试与自动化脚本
功能测试做熟了以后,一定要往接口测试和自动化方向走。现在的 web 系统前后端分离的趋势很明显,功能层面测出来的 bug 大多要靠接口定位到具体请求参数。而且博客系统的接口设计相对规整,特别适合做接口自动化的入门项目。
接口测试带来的另一个好处是能补足手工测试的盲区。比如我们用 Postman 直接调用接口绕过页面验证码,或者构造一些前端不可能产生的异常数据(数据库字段长度 255,你偏要传一个 300 字符的字符串进去),前端因为有限制碰不到这些场景,后端可能没有校验,这种深层 bug 只能靠接口测出来。
4.1 核心接口清单与关键参数分析
做接口测试之前先把接口清单整出来。博客系统的接口大致有这么几类:
| 接口模块 | 典型接口 | 方法 | 核心参数 |
|---|---|---|---|
| 用户认证 | /api/login | POST | username、password |
| 用户认证 | /api/register | POST | username、password、email |
| 文章操作 | /api/articles | POST/GET | title、content、status |
| 文章详情 | /api/articles/{id} | GET | id 路径参数 |
| 评论操作 | /api/comments | POST | articleId、content |
| 文件上传 | /api/upload | POST | multipart 文件流 |
| 分类管理 | /api/categories | POST/GET | name、description |
接口参数的选取依据是什么?我看两个东西:一看接口文档(或者抓包记录),字段必填性、类型、长度约束;二看业务逻辑,比如发布文章接口必须带 token 表示用户身份,评论接口要带 articleId 确认评论的对象。
参数组合的测试思路和功能测试是相通的。拿 login 接口说,除了校验正确的账号密码,我会专门测缺少某个字段、字段类型传错(username 传数字、password 传对象)、参数值为 null、参数值超长。这些用 Postman 拼一下很轻松,但手工在页面上触发不了,因为它们要绕过前端的输入限制。
接口测试里还有一类必测的是鉴权:未带 token 访问需要登录的接口,应该返回 401 或者 403;带过期 token 访问,应该被拦截;使用普通用户的 token 去调删除接口,应该被拒绝。博客系统的权限漏洞经常出在越权上,你登录用户 A,直接改接口路径去删用户 B 的文章,如果后端不校验资源归属,这就是水平越权漏洞,严重级别是极高的。系统存在这种漏洞,你在简历里写“发现越权类安全缺陷”就有底气了。
4.2 用 Postman 做接口冒烟和一键回归
Postman 是这个环节的主力工具,功能不强求多用,但有几个核心操作一定要熟练:环境变量的使用、断言脚本、集合批量跑。
环境变量解决的是测试环境切换问题。本地测试 base url 是http://localhost:8080,后面部署到服务器变成http://服务器IP:8080,你把请求里所有 URL 的域名部分替换成{{baseUrl}}变量,环境一换,全集合的请求就都跟上走了。
Postman 断言脚本用 JavaScript 写,核心用法也不复杂。拿登录接口举例:
pm.test("状态码为200", function () { pm.response.to.have.status(200); }); pm.test("返回结果包含token", function () { var jsonData = pm.response.json(); pm.expect(jsonData.data.token).to.be.a('string'); });断言有两条:一是状态码,二是业务字段。只看状态码远远不够,状态码 200 只能说明 HTTP 层通了,业务上可能返回了“密码错误”的报文。所以断言一定要落到业务字段上。
Postman 支持把登录返回的 token 自动存到环境变量,后续接口直接用:
var jsonData = pm.response.json(); pm.environment.set("token", jsonData.data.token);这样你把发布文章、评论、删除等接口按顺序放进一个 Collection,先跑登录提取 token,再跑业务接口,就形成了一条完整的接口冒烟链路。每次版本更新之后,一键把集合里的几十个请求跑一遍,两三分钟就能知道核心接口有没有被改坏,这是手工回归做不到的效率。
4.3 用 Python + requests + pytest 做接口自动化
Postman 适合快速验证,但到了自动化阶段还是得落到代码上。我的做法是用 Python 的 requests 库封装接口请求,用 pytest 管理用例,最后让报告输出到一个 html 文件里。这套班子轻、依赖少、容易上手。
代码结构我习惯这么组织:
blog_api_test/ ├── core/ │ ├── base_request.py # 统一请求封装 │ └── config.py # 环境配置、账号密码 ├── testcases/ │ ├── test_login.py # 登录测试用例 │ ├── test_article.py # 文章测试用例 │ └── test_comment.py # 评论测试用例 ├── common/ │ ├── data_utils.py # 测试数据生成 │ └── assert_utils.py # 断言封装 └── reports/ └── report.html # 测试报告base_request 里做几件事:请求超时设置、公共 header(Content-Type、token)、统一打印请求日志。代码大概长这样:
import requests BASE_URL = "http://localhost:8080" class BaseRequest: @staticmethod def post(path, data=None, json=None, headers=None, files=None): url = BASE_URL + path default_headers = {"Content-Type": "application/json"} if headers: default_headers.update(headers) response = requests.post(url, data=data, json=json, headers=default_headers, files=files, timeout=10) return response @staticmethod def get(path, headers=None): url = BASE_URL + path default_headers = {} if headers: default_headers.update(headers) response = requests.get(url, headers=default_headers, timeout=10) return response然后写登录用例,把功能测试时设计的各种场景用代码表达出来:
import pytest from core.base_request import BaseRequest def test_login_success(): resp = BaseRequest.post("/api/login", json={"username": "admin", "password": "123456"}) assert resp.status_code == 200 assert resp.json()["code"] == 200 assert "token" in resp.json()["data"] def test_login_wrong_password(): resp = BaseRequest.post("/api/login", json={"username": "admin", "password": "wrong123"}) assert resp.status_code == 200 assert resp.json()["code"] == 400 def test_login_empty_username(): resp = BaseRequest.post("/api/login", json={"username": "", "password": "123456"}) assert resp.status_code == 200 assert resp.json()["code"] == 400这里要注意一个细节:接口返回错误时状态码可能仍然是 200,业务错误码走的是 body 里的 code 字段。这个和开发约定有关,所以你在写断言之前先抓包看一次实际返回结构,不要自己想当然。测试人员写自动化最容易犯的错就是断言写错地方,最后自动化红了,但开发说“这不是 bug,是你脚本问题”。
pytest 里可以用 fixture 来做“登录一次,多条用例复用 token”的操作:
import pytest from core.base_request import BaseRequest @pytest.fixture(scope="module") def login_token(): resp = BaseRequest.post("/api/login", json={"username": "admin", "password": "123456"}) token = resp.json()["data"]["token"] return token def test_create_article(login_token): headers = {"token": login_token} resp = BaseRequest.post("/api/articles", json={"title": "pytest写入", "content": "内容"}, headers=headers) assert resp.json()["code"] == 200运行就用 pytest 跑一下,报告我用 pytest-html 插件直接生成:
pytest testcases/ --html=reports/report.html --self-contained-html -s接口自动化做完之后,你会慢慢发现一个规律:功能测试里的绝大多数场景,在接口层面都能用一个甚至两个请求表达出来。手工测一遍要五分钟,自动化跑一遍三秒钟,而且每次回归都能跑。测试人员如果只停留在手工点鼠标的阶段,工作效率很难上去,接口自动化是性价比最高的突破方向。
注意:自动化用例不是越多越好。核心接口、高风险场景(登录鉴权、越权操作、关键业务链路)优先写,边缘场景你写了一大堆,维护成本会教你做人。我之前写过一批特别繁琐的用例,最后项目一改版,全部重写,心都在滴血。
5. 测试过程中的缺陷定位与日志排查
很多人觉得测试不就是发现问题、提 bug 吗?但真实工作中,你提交一个“登录失败”的 bug,开发回复“本地复现不了”,局面就僵住了。所以测试人员在博客系统实战中,一定要刻意练习“定位问题的能力”。不是让你替开发改代码,而是你要能从现象出发,通过日志和数据库把人揪出来。
我习惯的定位路径是:界面 —> 网络请求 —> 服务端日志 —> 数据库数据。四个环节逐层下探,大多数问题不超过前三层就能找到根源。
5.1 从页面现象到代码层级的定位路径
先说最快的一步:浏览器开发者工具看网络请求。页面报“系统异常”,你先打开 Network 面板,找到那条标红的接口。看三个东西:请求 URL 是什么、请求参数是什么、响应体返回了什么错误信息。
这一步能过滤掉大量“假 bug”。比如前端传的参数格式不对,接口直接报 400 参数缺失,那这个 bug 应该给前端;比如接口返回 500,服务端报 NullPointerException,那就要去看后端日志了。
后端日志一般在项目的 logs 目录下,Spring Boot 系列的项目启动时也会在控制台直接打日志。看到完整异常堆栈后,先把报错行号记下来。有一次我测评论功能,提交评论后页面一直转圈,日志里出现java.sql.SQLException: Data too long for column 'content',一眼就看出是评论内容的长度超过了数据库字段的最大长度,开发同学给 content 字段设置的是 varchar(255),但前端允许输入 5000 字的评论。这种问题你用功能测试不好直接判断,但配合日志瞬间就能定位到根因。
再看数据库。有些问题表面上是展示问题,实际上是数据没写进去。比如前台文章列表少了一篇文章,后台明明显示它是“已发布”状态。你查一下数据库里这篇文章的status字段到底是 1 还是 2,就能确认是不是状态值映射错了。做软件测试不能只停留在页面上,会查数据库的人,定位效率能翻倍。
5.2 博客系统里我遇到的典型缺陷记录
我把自己做博客系统测试时遇到的几个典型问题整理出来,大家可以直接参考:
第一个是文章分页重复与遗漏并存。首页文章列表每页 10 条,我翻到第二页时发现有两条文章和第一页重合,同时有一篇下午刚发布的文章在第一页消失。排查下来发现排序条件是创建时间,但两条旧数据 create_time 字段为 null,MySQL 默认 null 值排在最前面,加上时间相同的数据每次排序顺序不稳定,导致翻页时重复。这类 bug 不仔细做翻页对比根本发现不了。
第二个是退出登录后仍能通过旧接口操作。最初版本的前端登录后把 token 存到 sessionStorage,退出登录时只是 remove 了 token,没调后端接口失效 token,导致旧 token 只要没过期就能继续调接口。我在 Postman 里拿了登录后的 token,调用退出接口后立刻用原 token 再请求发布文章接口,居然发布成功。这个属于会话管理的安全漏洞,在电商系统里同样常见。
第三个是并发评论导致数据覆盖。用 JMeter 同时发送两条评论请求,结果数据库里只插入了一条,另外一条覆盖了前一条。排查发现代码里用了先查后写的逻辑,没有对文章评论数做原子性更新。这个案例让我意识到:测试不只是验证功能正确,还要关注并发场景下的数据一致性,尤其像博客这种看起来“低并发”的系统,照样藏着一堆并发问题。
日志和定位这一块能力的提升,不是一天两天的事,但拿博客系统反复练绝对是有效的路径。因为系统是自己部署的,想看日志随便看,想查库随便查,权限完全在自己手里,不会被环境限制。相比在大厂里测试环境还要申请权限才能看日志,这种自由度太适合练手了。
6. 项目沉淀:把实战经验写进简历、讲进面试
项目做完整一套,最后的收尾工作就是“沉淀”。这里的“沉淀”不是把你跑的用例、写的脚本往网盘一扔就不管了,而是要把这个项目变成你简历上的亮点、面试中的谈资,让它真正为你找工作服务。博客系统这个项目看似小,但如果深度到位,它绝对够你在面试中撑起一整场技术面。
6.1 简历上的项目描述怎么写
我见过太多人简历上写“参与博客系统测试,负责功能测试和接口测试”,没有任何量化数据,也没有亮点描述。这种写法等于没写。一个不错的项目描述建议包含这几块内容:
- 项目背景:一句话说清楚系统是什么,技术栈有哪些
- 职责范围:功能测试、接口自动化、数据库校验、性能摸底,挑你实际做的
- 量化产出:写了多少条用例、发现了多少个有效缺陷、自动化覆盖了哪些核心接口
- 亮点案例:举一个有代表性的 bug,类型最好是安全漏洞或者逻辑缺陷
举个例子:
项目名称:个人博客系统(前后端分离) 项目描述:基于 Spring Boot + Vue 的博客平台,包含文章管理、评论、分类标签、用户认证等模块。 测试职责:独立负责系统功能测试与接口自动化建设,共设计功能测试用例 200+ 条,发现有效缺陷 35 个,其中 P1 级 6 个;使用 Postman + Python + pytest 搭建接口自动化脚本,覆盖登录、文章、评论等 6 个核心接口模块,回归耗时从手工 1 小时缩短到 5 分钟。 亮点案例:发现退出登录后旧 token 仍可调用接口的水平越权问题,直接推动开发增加服务端 token 失效机制。
这段描述每一句话都有信息量。面试官看到“发现水平越权”“自动化覆盖核心接口”“有效缺陷 35 个”,自然有往下问的欲望。你也不用担心被问倒,因为这些都是你真真实实做过的。
6.2 面试官大概率会问的这些题,怎么答
做了博客系统项目,面试时被问到的高频问题基本集中在下面这些方向,我逐个说一下作答思路。
“介绍一下你的博客系统项目。”这是开场题。别背简历,按项目背景、承担职责、测试内容、亮点发现四段式来讲。控制在三分钟以内,语气要有条理,别流水账。
“登录功能你怎么测试?”这是必考题,也是送分题。把功能测试那节讲的维度讲出来:正常路径、异常输入、边界值、安全性、会话管理。重点说安全测试的角度,会显得你有深度。最后可以补一句:“我还做过登录接口自动化和并发登录测试,发现系统在连续五次错误密码后没有限制,存在暴力破解风险。”这一句话就能把普通测试和靠谱测试分开。
“接口测试和功能测试有什么区别?”别答“接口测试测接口,功能测试测功能”这种废话。从两个角度答:一个是测试层面不同,功能测试关注用户视角的业务结果,接口测试关注前后端协议交互的逻辑;另一个是发现问题的阶段不同,接口问题在集成阶段就应该被发现,越早修复成本越低。再举个例子说明:一个前端限制最多输入 100 字,但后端没有做任何长度校验,功能测试怎么都测不出来,接口测试一抓一个准。
“自动化脚本是怎么维护的?”这个题考察你是不是真的写过自动化,而不是网上抄了个模板。你如实说:项目第一版用例主要写在 Postman 集合里,后期用 Python 重构;接口请求有改动时先改 base 层,再跑一次全量回归;用例失败时先去区分是环境问题还是代码问题,环境问题要写跳过逻辑,代码问题才提 bug。说清楚这些细节,面试官能感受到你是真实操过的人。
“你在测试过程中遇到过印象最深的 bug 是什么?”这时候就把你在博客系统里发现的越权漏洞、超长评论数据截断、并发评论覆盖拿出来讲。讲 bug 有公式:复现步骤、实际结果、预期结果、定位过程和最后怎么解决。特别是定位过程,要讲出你如何通过抓包看接口、查日志找堆栈、再查数据库确认数据状态。一个完整的定位故事,比十条理论回答都管用。
“如果这个项目交给你重新测一遍,你会怎么优化?”这种开放题,考察的是你对测试流程的复盘能力。你可以从一个角度切入:我会把自动化用例优先级重新梳理,把高频核心接口全部纳入持续集成,每次代码提交自动触发回归;另外在安全测试方面加强,不仅测水平越权,还要用工具扫一下依赖库的高危漏洞。回答的核心是“改进”,说明你对自己原来的做法有反思,不是做完就拉倒。
博客系统这个项目做到这一步,已经不仅仅是一个练手项目了。它能给你带来的,不只是几条自动化脚本和一张测试报告,而是一套完成度极高的测试思维训练:从环境部署到功能拆解,从接口验证到缺陷定位,最后到面试表达。这套东西走一遍,比你刷五十道面试题都管用。
我自己带过一些新人,发现大家最容易犯的毛病不是不会测,而是“知道的很多,做的不够”。理论课听了百八十遍,一上手就发懵。拿博客系统这种难度适中的项目,把完整流程走通、走出深度,你的测试功底和面试底气都会上一个台阶。项目仍在“沉淀中”,那正好,每学一个新技能就回来扩展一套用例和脚本,等你在简历上写下这个项目时,它会替你说话。