软件测试岗位的招聘流程里简历通过只是第一步真正决定结果的是面试官对项目经历的追问。准备入行或刚转岗的测试同学最容易出现的情况是接口自动化、pytest、JMeter、Selenium 这些名词都学过但简历里没有一套完整项目能说明它们怎么被使用。本文围绕软件测试从入门到进阶的学习路线整理一套 16 个软件测试实战练手项目。项目选择覆盖手工用例设计、接口测试、UI 自动化、性能测试、测试框架建设和持续集成全部基于开源系统或公开接口即可完成。每个项目会说明训练目标、常用技术栈、可交付成果和简历写法。这套清单用于提供学习路径和项目设计思路具体版本和被测系统需要结合本地环境确认。1. 练手项目到底在练什么软件测试学习路线先对齐1.1 练手项目解决的不是“会工具”而是“能讲清楚项目结果”很多学习资料教的是工具语法比如启动 Selenium 打开浏览器、用断言判断接口返回。但面试时面试官不会问“你用不用过 Selenium”而是问你这个测试项目被测系统是什么核心流程是什么。用例是怎么设计的覆盖了哪些边界条件。接口自动化脚本数据存在哪里环境切换怎么做。自动化用例跑挂了怎么定位是接口问题还是 UI 问题。压测结果为什么可信瓶颈在哪个环节。这些问题只有通过完整练手项目才能回答。练手项目的作用是把散装知识点串成一条任务链从测试计划、用例设计到执行、缺陷管理、自动化脚本、持续集成每一步都有产出物。面试时能拿出用例文档、代码仓库、测试报告和问题记录比单纯背面试题更有说服力。1.2 从入门到进阶的四层能力地图软件测试的进阶不是把工具学完而是把一类问题解决到能交付结果的程度。常见路线如下阶段核心能力典型工具/框架可用交付物入门需求分析、用例设计、缺陷管理、手工执行思维导图、Excel、禅道/Jira测试计划、用例文档、Bug 清单接口测试请求分析、参数关联、断言、数据驱动、环境切换Postman、Newman、Python requests、pytest、Allure接口测试用例、自动化脚本、测试报告UI 自动化元素定位、PO 模式、等待策略、稳定性分析、移动端冒烟Selenium、Playwright、Appium、PytestUI 自动化框架、用例执行日志、失败截图性能测试脚本编写、场景设计、指标分析、瓶颈识别JMeter、Locust压测脚本、性能指标表、性能测试报告综合与工程化Mock 服务、数据构造、CICD、日志监控Jenkins、GitHub Actions、Docker流水线配置、自动化执行记录、维护方案前两阶段保证能做测试后三阶段决定能否从“执行者”变成“方案提供者”。练手项目也应该按照这个层次递进不要一上来就追求复杂框架。1.3 被测系统怎么选不要从零写一个商城再开始测练手项目最大的误区是花大量时间开发被测系统。建议直接选择开源系统作为被测对象。常见选择包括开源后台管理系统如若依RuoYi、renren-fast前端 Vue 后端 Spring Boot功能稳定适合接口测试和 UI 自动化。开源电商或内容系统如 mall、litemall 等业务链路较长适合设计核心下单流程用例。公开练习接口部分开放平台提供测试接口使用时注意阅读平台规则和合规要求适合接口测试入门。选择时注意不要只选“能跑起来”的系统最好包含登录、列表、表单、权限、状态流转等功能这样用例设计和自动化场景才完整。学习环境下本地跑被测系统即可。生产环境则有更严格要求需要额外考虑环境隔离、测试数据清理、权限管控、日志监控和回滚方案。练手项目阶段把本地环境跑通不必模拟生产环境的所有约束。注意判断一个练手项目是否合格不是看代码量而是看是否能回答“被测系统是什么、你测了什么、发现了什么问题、如何保障结果可信”。2. 16 个软件测试练手项目按四个阶段递进设计这 16 个项目按“入门、接口测试、UI 自动化、性能与工程化”四个阶段设计。每个项目都是一个可独立提交简历的片段也可以组合成一条完整项目经历。2.1 入门阶段用例设计、评审和缺陷管理项目 1-4项目 1基于开源商城系统的手工测试与用例设计训练目标是对商城系统的登录、商品搜索、商品详情、购物车、下单、订单查询等核心模块编写测试用例。重点掌握等价类划分、边界值分析法、场景法和错误推测法。常见做法在本地部署一个开源商城准备测试账号造好商品、库存、优惠券等数据。用思维导图拆分登录模块的功能点和异常分支。用 Excel 或禅道编写用例字段包含用例编号、模块、用例名称、前置条件、测试步骤、测试数据、预期结果、优先级、用例类型。登录模块用例片段用例编号前置条件测试步骤测试数据预期结果优先级TC-LOGIN-001系统已部署用户已注册打开登录页输入正确用户名和密码用户名test001密码Test123登录成功进入首页高TC-LOGIN-002同上输入正确用户名错误密码密码wrong123提示“用户名或密码错误”不跳转高TC-LOGIN-003同上密码为空点击登录无提示“请输入密码”登录按钮不可提交中不要只追求用例数量要能讲清楚“为什么这样设计用例”。面试官几乎必问边界值比如密码长度为 6 到 20 位时5 位和 21 位都属于边界场景。项目 2测试计划与用例评审模拟训练目标是练习写测试范围、测试策略、资源安排、风险评估和进度计划。把项目 1 的用例组织成一份完整测试计划并模拟一次用例评审。可以从被测模块、环境、进度、缺陷规则几个维度写不必模仿固定模板。评审时重点记录三类问题需求不明确、用例缺少异常场景、预期结果不具体。交付成果是测试计划文档、评审会议记录、用例评审问题清单。项目 3缺陷全生命周期管理与缺陷分析训练目标是学会提交有效 Bug跟踪从“待处理-处理中-已修复-待回归-关闭”的流转过程。缺陷记录至少包含标题、环境、版本、优先级、严重程度、复现步骤、实际结果、预期结果、截图或日志。可以额外练习一个模块的 Bug 分布统计区分功能性 Bug 和数据问题、环境问题。每周输出一个 Bug 分析表按模块、原因、严重级别统计并给出测试结论。这类数据在简历里比“写了多少用例”更有说服力。项目 4浏览器 DevTools 与接口请求分析训练目标是学会使用浏览器开发者工具观察页面请求理解 HTTP 方法、状态码、请求头、响应体、Cookie 和 Token 的传递。这是从手工测试过渡到接口测试的桥梁。具体操作打开商城登录页面登录成功后观察登录请求的 URL、请求方式和参数。对比登录失败请求的状态码和响应信息。在浏览器控制台使用fetch直接调用一个 GET 接口观察跨域和鉴权现象。输出成果是几张典型请求分析表说明每个接口的入参、出参、鉴权方式和异常响应。2.2 接口测试阶段数据、关联和框架项目 5-8项目 5Postman 接口测试脚本项目训练目标把商城登录、商品列表、加入购物车、下单等核心接口做成 Postman 集合。学会环境变量、全局变量、前置脚本和测试脚本。Postman Tests 中断言示例pm.test(登录成功返回 token, function () { var jsonData pm.response.json(); pm.expect(jsonData.code).to.eql(200); pm.expect(jsonData.data.token).to.not.be.empty; });关键点先用 Postman 完成单接口调试再通过newman命令批量执行集合为后续持续集成做准备。Newman 是 Postman 集合的命令行运行器适合放入 CI 流程。项目 6Python requests 接口测试脚本训练目标用 Python 写一段可复用的接口请求脚本封装 GET/POST统一处理鉴权打印响应信息。import requests BASE_URL http://localhost:8080 session requests.Session() def login(username, password): url f{BASE_URL}/api/auth/login payload {username: username, password: password} resp session.post(url, jsonpayload) data resp.json() token data.get(data, {}).get(token) if token: session.headers.update({Authorization: fBearer {token}}) return token if __name__ __main__: print(login(test001, Test123))这里的地址是本地示例实际项目要把BASE_URL替换成部署的被测系统地址。封装请求后所有测试用例可以复用同一个 session避免每个用例重复处理登录态。项目 7pytest 数据驱动接口自动化框架训练目标把项目 6 的脚本升级成 pytest 用例。用pytest.mark.parametrize或 YAML/Excel 数据驱动避免测试数据和代码混在一起。import pytest pytest.mark.parametrize( username,password,expected_code, [ (test001, Test123, 200), (test001, wrong123, 400), (, Test123, 400), ], ) def test_login(username, password, expected_code): resp login_request(username, password) assert resp.status_code expected_code真实接口不一定返回 400应根据被测系统实际业务结果调整。这个项目的价值在于理解数据驱动把测试数据从代码中拆出去新增用例时只需要改数据不用改代码。项目 8接口依赖、登录态和参数关联训练目标处理下单接口必须依赖登录 Token、商品 ID、优惠券 ID 等问题。学会从登录响应提取 Token从商品列表提取商品 ID再传给下单请求最后用订单号查询订单。输出成果一个能跑通“登录-加购-下单-查询订单”全链路的接口自动化脚本。这个项目是接口自动化面试的高频考点面试官通常追问“下单接口依赖的商品 ID 是从哪里来的”。2.3 UI 自动化测试阶段选择能稳定的技术组合项目 9-12项目 9Selenium WebUI 自动化购物流程训练目标用 Selenium 自动打开登录页、输入账号密码、搜索商品、加入购物车、提交订单并断言关键页面元素。需要注意不要只用id写死选择器。元素定位优先使用id、>from selenium import webdriver from selenium.webdriver.common.by import By driver webdriver.Chrome() driver.get(http://localhost:8080/login) driver.find_element(By.ID, username).send_keys(test001) driver.find_element(By.ID, password).send_keys(Test123) driver.find_element(By.ID, loginButton).click() assert 首页 in driver.page_source driver.quit()这个项目的难点不是打开浏览器而是选择器稳定性和执行速度。建议完成主流程后再加入一条异常用例比如输入错误密码后断言错误提示。项目 10Pytest PO 模式 UI 自动化框架训练目标把页面元素和业务操作从测试脚本中拆分采用 Page Object 模式。基类封装等待、点击、输入、截图页面类封装各自元素测试类只写业务场景。框架能输出 HTML 报告和失败截图。常见目录结构test_ui/ ├── pages/ │ ├── base_page.py │ ├── login_page.py │ └── cart_page.py ├── tests/ │ ├── conftest.py │ └── test_buy_flow.py ├── reports/ └── pytest.iniPO 模式的核心价值是复用和维护。当登录页的输入框id改变时只需要修改login_page.py所有使用登录页的测试都自动修复。项目 11Appium 移动端 App 冒烟测试训练目标对 Android 端 App 执行冒烟用例启动、登录、首页浏览、退出。掌握 Appium 的 capabilities 配置、定位方式、元素等待和日志收集。Appium 环境相对复杂需要 JDK、Android SDK、模拟器或真机。如果本地没有 Android 环境可以先使用模拟器或聚焦于 Web 端自动化和接口自动化Appium 作为进阶了解。这个项目放在简历上时要能说清楚 capabilities 里每个参数的作用。项目 12Playwright 跨浏览器自动化测试训练目标使用 Playwright 编写一个跨 Chromium/Firefox/WebKit 的自动化用例体验自动等待和截图能力。Playwright 对现代 Web 页面兼容性较好适合作为 Selenium 之外的第二套 UI 技术栈。from playwright.sync_api import sync_playwright with sync_playwright() as p: browser p.chromium.launch() page browser.new_page() page.goto(http://localhost:8080/login) page.fill(#username, test001) page.fill(#password, Test123) page.click(#loginButton) page.wait_for_selector(text首页) page.screenshot(pathlogin_success.png) browser.close()Playwright 的自动等待机制能减少很多不稳定的sleep代码。建议先在 Chromium 上跑通再扩展到 Firefox 和 WebKit。2.4 性能测试阶段设计场景和读结果项目 13-14项目 13JMeter 登录/下单接口压测训练目标用 JMeter 创建线程组、HTTP 请求、CSV 参数化、断言和聚合报告。设计一个包含可变用户数、思考时间的场景采集响应时间、吞吐量、错误率并分析结果。不要只压一个接口就结束。可以先设置 20、50、100 个并发线程观察错误率和响应时间变化。本地压测结果只用于学习性能测试流程不能当作生产环境的性能结论。jmeter -n -t test_plan.jmx -l result.jtl -e -o report_html这条命令用非 GUI 模式执行测试计划输出.jtl日志和 HTML 报告。性能测试的关键不是跑出一个数字而是能解释数字背后的含义平均响应时间、P95、吞吐量和错误率分别说明什么问题。项目 14Locust 编写可编程压测脚本训练目标用 Python 定义用户行为。相对 JMeterLocust 脚本更接近代码适合团队中已有 Python 基础的情况。from locust import HttpUser, task, between class ShopUser(HttpUser): wait_time between(1, 3) def on_start(self): self.client.post(/login, json{username: test001, password: Test123}) task def browse_goods(self): self.client.get(/goods?page1)Locust 的on_start会在每个用户模拟开始时登录一次wait_time模拟用户思考时间。这个项目可以和项目 13 对比说明不同压测工具适合的不同场景。2.5 综合进阶阶段Mock 服务与持续集成项目 15-16项目 15测试数据构造与 Mock 服务训练目标解决下单流程对第三方支付、短信、库存服务依赖的问题。常见方案是使用mock-server或 Python Flask 写一个最小 Mock 服务按请求路径和参数返回预设响应。输出成果一份 Mock 服务脚本、一份测试数据准备文档说明如何快速构造登录用户、商品、优惠券和订单数据。这个项目能体现测试架构设计能力因为实际工程中经常要模拟不稳定或未就绪的外部依赖。项目 16自动化用例接入持续集成流水线训练目标把项目 7、项目 10 的 pytest 用例接入 Jenkins 或 GitHub Actions在代码提交后自动执行。产物包括测试报告、失败截图和日志。name: api-test on: push: branches: [ main ] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Set up Python uses: actions/setup-pythonv5 with: python-version: 3.10 - run: pip install -r requirements.txt - run: pytest -m api --htmlreport.html持续集成的价值不是“能跑”而是“提交后自动跑、失败后能通知、结果能归档”。这个项目可以作为整个学习过程的收尾把所有自动化用例串起来。2.6 16 个练手项目速查表序号项目阶段核心能力主要工具1手工测试与用例设计入门用例设计方法思维导图、Excel、禅道2测试计划与用例评审入门计划与评审文档、会议记录3Bug 管理与缺陷分析入门缺陷生命周期禅道/Jira4DevTools 请求分析入门HTTP 请求理解浏览器 DevTools5Postman 接口测试接口接口调试与断言Postman、Newman6requests 接口脚本接口请求封装Python、requests7pytest 数据驱动框架接口自动化框架设计pytest、Allure8接口依赖与鉴权接口参数关联与数据传递requests、pytest9Selenium 购物流程UI 自动化UI 自动化基础Selenium10PO 模式 UI 框架UI 自动化PageObject、失败处理pytest、Selenium11Appium 移动冒烟UI 自动化移动端测试Appium12Playwright 跨浏览器UI 自动化跨端自动化Playwright13JMeter 压测性能性能场景、报告JMeter14Locust 压测编程性能HttpUser 脚本Locust15Mock 与测试数据综合依赖解耦Flask、Mock Server16CICD 接入综合自动触发、结果归档Jenkins/GitHub Actions3. 把练手项目写成简历项目公式、示例与反面写法3.1 简历项目描述公式面试官看简历项目时关注三件事项目背景、你的具体动作、可量化的结果。建议用下面公式组织“为了业务目标我负责项目范围采用技术方案完成了关键动作最终实现可量化的结果。”避免干巴巴写“负责测试”。可以写“设计登录模块测试用例覆盖等价类、边界值和场景法提交有效 Bug 12 个其中严重级 3 个编写 pytest 接口自动化用例 40 条接入 GitHub Actions 后回归时间由人工 1 小时降到脚本执行约 8 分钟。”“可量化结果”必须是练习过程中真实产生的数据不要编造。比如“80 条用例”“覆盖率 85%”这类数字面试官追问就会发现是假的。3.2 简历项目示例示例 1接口自动化方向某开源商城系统接口自动化测试个人练手项目 - 基于 Python requests pytest 搭建接口自动化测试框架使用 YAML 管理测试数据Allure 生成测试报告。 - 封装登录、商品查询、购物车、下单、订单查询等核心业务接口实现登录 Token 在接口间的自动传递。 - 共编写接口用例 60 条数据覆盖正常流程、异常参数、未登录和越权访问场景。 - 通过 GitHub Actions 在代码提交后自动执行失败用例输出响应日志和断言截图。示例 2UI 自动化方向基于 Selenium Pytest 的 Web 端回归自动化个人练手项目 - 使用 Page Object 模式组织页面元素和操作抽取 BasePage 处理等待、点击、截图。 - 覆盖登录、搜索商品、加入购物车、提交订单主流程支持多浏览器运行。 - 执行失败时自动截图并生成 HTML 测试报告解决无头执行时无法定位问题的问题。这两个示例都强调被测系统是什么、用了什么方案、有哪些真实产出。3.3 简历中最常见的负面写法问题表现调整方向堆名词没有场景“熟悉 Selenium、Postman、JMeter、pytest”每个工具对应一个能说清的项目只有工具没有被测系统“写了一个自动化脚本”写明被测系统、流程、数据、报告没有结果“负责接口测试”补充用例数量、发现的问题、执行时长照搬练习源码简历描述和网课案例几乎一样换被测系统重新设计用例和数据数字失真编造“发现 500 个 Bug”只用真实记录少而可信4. 不同阶段最典型的坑和定位方法4.1 用例设计项目的坑最常见的三个问题用例没有前置条件、步骤中缺少具体数据、预期结果不具体。比如“输入正确账号和密码点击登录验证登录成功”这条用例别人没法直接执行。应该写成“输入用户名 test001、密码 Test123点击登录按钮断言跳转到首页且右上角显示用户昵称”。定位方法把一条用例交给另一个不看需求的同学让他直接执行。如果他能不看需求文档就完成验证说明这条用例合格。4.2 接口自动化项目的坑测试数据写死在代码里、环境地址硬编码、登录态没有复用、断言只判断 HTTP 200。其中“断言只判断 200”是最隐蔽的问题。接口返回 200 但业务码可能是失败比如登录接口返回{code: 500, message: password error}。排查路径先看请求是否发出、URL 是否正确。再看请求头是否带上了 Token 或 Cookie。再看响应结构是否符合预期。最后看断言的是状态码还是业务码。推荐做法用全局配置管理环境用 pytest fixture 做登录态用数据文件驱动用例。4.3 UI 自动化项目的坑固定time.sleep、选择器不稳定、用例互相依赖、失败没有截图。固定等待会让脚本变慢而且本地能跑、CI 上跑不稳定。定位方法移除sleep改用显式等待。记录失败时的页面源码和截图。用例尽量独立不要依赖上一条用例执行完后的页面状态。Selenium 中的显式等待示例from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC WebDriverWait(driver, 10).until( EC.visibility_of_element_located((By.ID, loginButton)) )4.4 性能测试项目的坑本地压测结果直接当成性能结论、线程数无限放大导致客户端瓶颈、没有思考时间、只看平均响应时间不看 P95/P99。其中“把本地结果当生产结论”最危险。本地网络、数据库数据量、服务器配置和生产环境差异很大。排查路径先小并发验证脚本正确性。再逐步加压观察客户端、网络、服务端资源。最终结论给出环境说明、配置和局限。4.5 一个通用排查清单问题现象检查内容解决方向用例失败找不到原因请求日志、断言、实际响应加日志输出对比实际结果和预期脚本本地能跑 CI 失败CI 中数据库、服务和依赖是否启动在流水线中增加服务启动和等待步骤元素找不到是否 iframe、新窗口、动态加载检查 iframe、等待策略、选择器稳定性并发压测出错参数冲突、Token 失效、连接池不足参数化用户数据检查鉴权和资源限制报告没有生成路径权限、pytest 插件未安装检查报告目录重新安装插件5. 最小可运行示例用 pytest 自建一个接口自动化练手项目为了让文章不只是清单这里给出一个最小但完整的接口自动化项目。读者可以在本地被测系统上替换地址和数据后直接使用。5.1 目录结构api_test/ ├── config/ │ └── settings.py ├── common/ │ └── client.py ├── testcases/ │ └── test_login.py ├── requirements.txt └── pytest.ini这个目录结构对应常见测试框架分层配置单独放请求封装单独放测试用例单独放。5.2 配置文件config/settings.pyBASE_URL http://localhost:8080 TIMEOUT 10配置集中管理后切换测试环境时只需要改这一个文件。5.3 请求封装common/client.pyimport requests from config.settings import BASE_URL, TIMEOUT class ApiClient: def __init__(self): self.session requests.Session() self.base_url BASE_URL def post(self, path, **kwargs): url f{self.base_url}{path} kwargs.setdefault(timeout, TIMEOUT) return self.session.post(url, **kwargs)封装的意义统一处理基础 URL、超时和会话管理后续增加请求打印日志时只需要改这里。5.4 测试用例testcases/test_login.pyimport pytest from common.client import ApiClient pytest.mark.parametrize( data, expected, [ ({username: test001, password: Test123}, 200), ({username: test001, password: wrong123}, 400), ], ) def test_login(data, expected): client ApiClient() resp client.post(/api/auth/login, jsondata) assert resp.status_code expected这里假设登录失败返回 400实际项目以被测系统为准。parametrize把两条用例合并成一个测试入口表格化展示正常和异常场景。5.5 依赖文件与运行requirements.txtrequests pytest pytest-html PyYAML这里没有锁版本实际项目建议锁定版本保证环境可复现。运行命令cd api_test pip install -r requirements.txt pytest -v --htmlreport.html预期输出collected 2 items testcases/test_login.py::test_login[data0-200] PASSED testcases/test_login.py::test_login[data1-400] PASSED注意不要只验证程序能启动还要验证输入、输出、异常分支和日志是否符合预期。接口自动化项目真正有价值的部分是异常场景和定位能力。5.6 学习环境和生产环境的差别学习环境本地启动被测系统测试数据可以随意修改用例失败可以反复执行不需要考虑权限和监控。生产环境不能直接跑自动化脚本必须使用独立测试环境。需要走配置管理、数据准备、权限审批、监控告警、结果归档和回滚流程。练手项目阶段至少要养成配置外置、日志完整、失败可重现的习惯。6. 练手项目推进不下去时按这条清单自查6.1 常见卡点与处理卡点建议没有被测系统选开源系统部署不了就用公开 API接口文档缺失用 DevTools 观察页面请求和响应不知道用例写到什么程度先覆盖正常流程和高优异常分支不追求全模块自动化用例跑不过先用 Postman 或浏览器手调通再写脚本环境依赖难用 Docker 启动被测系统或使用远程公共接口时间不够不要全部 16 个都做优先完成接口自动化和一个 UI 自动化项目6.2 建议推进节奏周次重点项目交付物第 1 周项目 1-4用例文档、Bug 清单、请求分析表第 2 周项目 5-8Postman 集合、pytest 接口用例第 3 周项目 9-10有余力再做项目 12UI 自动化框架、失败截图第 4 周项目 13-16压测报告、CICD 流水线、简历版本这只是一个参考节奏具体根据基础和时间调整。核心是每周都有物化成果不要停留在“看视频、跟敲代码”。6.3 面试准备建议准备两个项目一个接口自动化、一个 UI 自动化或性能测试能讲 20 分钟细节。简历写出来之后先自己追问一轮被测系统怎么来的测试数据怎么准备用例跑挂了日志在哪看如果接口字段变了脚本要改哪里压测结果为什么可信如果答不出回到对应项目里补。面试官愿意听到“这个问题我项目里遇到过原因是……”而不是“这个我没遇到过”。6.4 生产环境意识即使做练手项目也要养成生产环境意识日志、配置外置、环境隔离、失败重试、数据清理、报告归档。这些习惯比某个具体工具更值钱。一个能展示出“测试执行完怎么清理脏数据”“跑挂了怎么定位”“报告怎么归档”的候选人通常比只能写出“会用 pytest”的候选人更有竞争力。把这些项目逐步做完再回到简历上重新组织一遍项目经历面试时的表达会比再刷一百道面试题更扎实。软件测试的成长曲线并不陡峭关键是把每个项目都“跑完整”有输入、有执行、有产出、有复盘。从项目 1 开始选一个开源系统拆需求、写用例、做接口测试、补自动化、压一次性能最后把它们写成一条能经得起追问的项目经历。