软件测试从 0 到 1:用一个真实可跑的小实验,走完测试全过程

一个页面能打开,按钮能点击,提交后有提示——这样就算测试通过了吗?

先看一个很小的问题:需求写着“年龄在 18 至 60 岁之间,包含两端”,输入 30 一切正常,输入 18 却被拒绝。页面没有崩溃,程序也没有报错,但它做错了事。

软件测试的入门,可以就从这里开始:拿着明确的依据,设计有目的的检查,再用证据说明实际结果。

本文带你走完一次小型实践:读需求 → 设计用例 → 执行测试 → 记录缺陷 → 自动化复测 → 汇报结果。

软件测试入门实验的真实浏览器截图:修正版接受 18 岁输入

本站原创练习页面的真实截图,不是 AI 生图或界面概念图。本文四张图片均来自实际浏览器或实际生成的 Playwright 报告。

核对与实验日期:2026 年 9 月 22 日。基础概念参考 ISTQB CTFL v4.0.1,工具用法参考 Playwright 官方文档。案例、规则和教学缺陷由本站专门设计,并非发现了某个真实业务系统的漏洞。源码和实验结果在文末公开。

1. 先理解:测试不是随便点点,也不只发生在上线前

阅读需求时发现“是否包含 18 岁”没写清,和运行页面时发现“18 岁被误拒绝”,都是有价值的质量检查。前者可以在代码还没写完时进行,后者需要观察程序行为。

ISTQB 大纲强调:测试能够发现缺陷,但不能证明缺陷完全不存在;通常也不可能穷尽所有输入和条件。因此,测试需要做选择,而不是把“暂时没发现问题”说成“绝对没有问题”。CTFL v4.0.1,第 1.3 节

对新手来说,先记住三个问题就够了:

  • 依据是什么? 是明确需求、验收条件,还是我自己的猜测?
  • 怎样检查? 用什么数据、做什么操作、观察哪里?
  • 证据在哪里? 能否让别人照着步骤复现?

“测试”和“修复”也要区分。测试发现实际行为与预期不一致;定位原因并修改代码,是后续修复工作。小项目中可以由同一个人完成,但记录时不要混为一谈。

2. 第一步:把需求改写成能判断对错的规则

本次练习只检查一个年龄输入框,不涉及账号、付款或真实报名。

约定如下:

  1. 输入去掉首尾空白后,必须由十进制数字 0–9 组成,允许前导零。
  2. 年龄数值必须满足 18 ≤ age ≤ 60。
  3. 范围内显示“校验通过:符合年龄要求”。
  4. 整数超出范围显示“年龄必须在 18 至 60 岁之间”。
  5. 空值、小数、字母等格式不符合要求时,显示“请输入整数年龄”。

这些是本练习自定的业务规则,不是通用年龄限制。真实项目如果要求按出生日期计算周岁,就还需要确认生日、时区等条件,不能直接套用这个输入框。

先试着自己操作:打开教学缺陷版,输入 30,再输入 18。

不用填写真实个人信息,页面仅在浏览器内计算,不上传或保存输入。

3. 第二步:有方法地选数据,而不是想到什么测什么

先分组,再关注分界处

对于符合格式的整数,可以按规则分为三组:低于 18、18 至 60、高于 60。再另外检查空值、小数和字母等格式问题。

这种先按预期行为分组的思路,对应等价类划分;围绕分界点选值,对应边界值分析。ISTQB 将它们列为黑盒测试技术,也就是依据外部规则设计检查,而不必先看内部代码。CTFL v4.0.1,第 4.2.1、4.2.2 节

我们先选 10 个用例。表格中的结果必须在执行之前写好,不能看到程序返回什么,就把什么当成正确答案。

编号 输入 预期 为什么选它
T01 17 范围提示 最小允许值的前一个整数
T02 18 通过 最小允许值本身
T03 19 通过 最小允许值的后一个整数
T04 30 通过 合法区间的普通值
T05 59 通过 最大允许值的前一个整数
T06 60 通过 最大允许值本身
T07 61 范围提示 最大允许值的后一个整数
T08 空值 格式提示 没有填写
T09 18.5 格式提示 小数不符合本练习规则
T10 abc 格式提示 非数字输入

这是一组入门用例,不是完整覆盖证明。例如首尾空格、前导零、超长输入、重复点击和键盘操作,还可以继续设计检查。我们没有把所有可能性都自动测完。

一条用例至少写清四件事

以 T02 为例:打开指定版本的页面,输入 18,点击“检查资格”,确认状态区域显示通过提示。

如果只写“测试年龄是否正常”,执行者不知道输入什么,复测的人也不知道之前到底检查了哪里。用例不是越长越专业,而是越能重复执行越有用。

4. 第三步:发现问题后,写一份别人能复现的缺陷报告

教学缺陷版的真实截图:输入 18,实际却出现范围错误提示

真实执行结果:界面左侧约定包含 18 岁,右侧却拒绝了输入。该边界错误为教学目的主动设置。

下面是一份针对本案例的缺陷记录:

1
2
3
4
5
6
7
8
9
10
11
12
编号:AGE-001
标题:输入最小合法年龄 18 时,被错误拒绝
对象:年龄校验实验室 / 教学缺陷版
环境:Windows,Chrome 153.0.8010.48
前提:打开带有 ?version=buggy 的练习页面
步骤:
1. 在“年龄”输入框填入 18。
2. 点击“检查资格”。
预期:显示“校验通过:符合年龄要求”。
实际:显示“年龄必须在 18 至 60 岁之间”。
影响:符合下限规则的输入无法通过。
证据:页面截图、对应自动化测试失败记录。

不要只写“不能用”“有 bug”“快修一下”。也不要在没有分析业务影响时,随手把所有问题都标成最高级别。

一份好的记录应让接手的人少猜几次。若是偶发问题,还应记录出现条件与已观察到的次数;无法稳定复现时就如实说明。

5. 第四步:把重复检查交给自动化

手工先理解规则,自动化再重复检查。反过来,如果预期本身写错,脚本只会更快、更稳定地重复那个错误。

这里使用 Playwright Test。它提供浏览器操作、断言和测试报告;本文用本机 Google Chrome 执行,只验证这一种浏览器配置,没有将结果扩展成“所有浏览器都通过”。Playwright 官方入门

准备与运行

准备 Node.js 24、npm 和 Google Chrome,然后获取配套源码:

1
2
3
4
5
git clone https://github.com/shuangluo760-lang/shuangluo760-lang.github.io.git
cd shuangluo760-lang.github.io/examples/software-testing
npm ci
npm test
npx playwright show-report

已有仓库的读者,更新后直接进入 examples/software-testing 即可。npm ci 使用示例目录自己的锁定依赖,不需要安装整个博客的依赖。

测试配置会自动启动本地页面服务,执行完再关闭;请保持 4178 端口空闲,不必另开一个服务窗口。这种方式使用 Playwright 的 webServer 配置。官方配置说明

想看“发现问题”的过程,另行执行:

1
npm run test:buggy

这条命令应该出现一个失败并返回非零退出码,因为它检查的是教学缺陷版。不是让你忽略任意失败,而是让你对照报告识别我们设置的那个边界错误。

看懂最核心的一条测试

下面是从配套测试中简化出的单用例写法,使用相同配置即可运行:

1
2
3
4
5
6
7
8
9
const { test, expect } = require('@playwright/test');

test('18 岁应通过年龄校验', async ({ page }) => {
await page.goto('/');
await page.getByLabel('年龄', { exact: true }).fill('18');
await page.getByRole('button', { name: '检查资格' }).click();
await expect(page.getByRole('status'))
.toHaveText('校验通过:符合年龄要求');
});

前几行负责操作,最后一行负责判断。没有断言的“打开页面再点按钮”,通常只能说明操作执行过,不能说明结果符合需求。

这里的 toHaveText 会在超时前重试检查目标文本,不需要为了等待页面更新而随意固定暂停几秒。但它不会把错误结果变成正确结果,超过等待时间仍不符合预期就会失败。Playwright 断言文档

Playwright 真实 HTML 报告:教学缺陷版 10 个测试中 9 个通过、1 个失败

首次运行的真实报告。失败项为“年龄 18”;报告标题里的箭头后内容是测试预期,不是失败页面实际显示的内容。查看失败详情才能比较 Expected 与 Received。

6. 第五步:验证修复,并检查有没有影响其他情况

教学缺陷的核心差异只有一个比较符:

1
2
3
4
5
// 缺陷版:错误排除了 18。
const eligible = age > 18 && age <= 60;

// 修正版:与需求一致,包含 18。
const eligible = age >= 18 && age <= 60;

示例页面同时保留了两个版本,方便复现;默认打开修正版,参数 ?version=buggy 则选择教学缺陷版。输入格式校验在范围判断之前完成。

确认原来的 18 岁问题不再出现,是确认测试;再检查 17、19、60、61 等情况有没有受到影响,是回归检查。它们目的不同,不应把“原来的失败项变绿”当成全部工作已经结束。CTFL v4.0.1,第 2.2.3 节

本次对两个版本执行了同一组 10 个用例,预期结果保持不变:缺陷版 9 通过、1 失败;修正版 10 通过。

Playwright 真实 HTML 报告:修正版同一组 10 个测试全部通过

修正版实际运行报告,无跳过或重试后通过的用例。报告由 Playwright HTML reporter 生成,再由浏览器截图,未手工绘制绿色通过状态。报告工具说明

实验环境为 Windows、Node.js 24.21.0、Playwright 1.63.0、Google Chrome 153.0.8010.48。两次运行的时间、版本和逐项结果均保存在源码中的 evidence 目录。单次耗时受断言超时和环境影响,不能拿来宣称修正版性能提升。

7. 最后一步:写结论时,同时交代范围和未测项

对于这个实验,可以这样汇报:

本次针对年龄校验前端,在 Windows + Chrome 环境执行 10 个 UI 用例。教学缺陷版发现 1 个下限判断问题;修正版原失败项通过,其余 9 项也通过。该结果仅说明所列用例在本次环境下符合预期。服务端、性能、安全、跨浏览器及完整可访问性未验证,部分输入规范化场景也未自动化覆盖。

这比“测试通过,可以上线”更有信息量。

本案例没有服务端,所以不能拿它当成完整的报名系统。真实应用不能只靠浏览器输入校验:客户端约束容易绕过,服务端也需要验证收到的数据。这一点在 MDN 的表单校验文档中有明确提醒。MDN:客户端表单校验

上线决策还应结合业务风险、未解决问题和责任人的判断。测试报告提供证据,不替团队做没有依据的保证。

从这个小实验,继续走向真实项目

不必一开始就同时学习十种工具。建议按下面的顺序练习,每一步都留下能展示的成果:

  1. 先练需求与用例。 给这个输入框补上空格、前导零等检查,写明预期及理由。
  2. 再练观察与记录。 不改预期,尝试不同数据,整理一份可复现的问题报告。
  3. 再练自动化。 把已经理解的用例加入脚本,确认失败信息能看懂。
  4. 最后扩展范围。 为自己有权限的练习项目增加接口测试、其他浏览器与非功能检查,分别记录结果;不要对未经许可的真实网站做压测或安全扫描。

软件测试从 0 到 1 的关键,不是装好一个工具,而是能说明:为什么这样测、实际看到了什么、这些证据支持什么结论,以及它们还不能证明什么。

配套实验与参考资料

本文说明文字、练习页面和用例为原创;截图为该练习及工具实际输出。文中实验结果只对应所公开的环境与范围,不是生产系统质量认证。


软件测试从 0 到 1:用一个真实可跑的小实验,走完测试全过程
https://luoshuang.org/software-testing-zero-to-one/
作者
LuoShuang
发布于
2026年9月22日
许可协议