测思:测试与伪测试

7 阅读9分钟

1. 科学与伪科学

科学的核心从不是“绝对正确”,而是:

  • 可证伪:理论存在被推翻的可能,而非无法反驳
  • 可验证:能通过客观实验、观察得出明确结论
  • 可重复:实验结果能被他人在相同条件下复现

科学以客观事实为根基,通过严谨观察、实验和推理形成理论,且愿意接受新证据修正,具备自我纠错的生命力。

2. 伪在哪

任意一项不满足“三可”,即便用科学外衣包装,本质也是伪科学。 基于此我们聊聊软件开发行业中的:测试与伪测试

3. 测试与伪测试

3.1. 关于“可证伪性”:你是真的在考试,还是在对口型?

核心大白话: 一个好的测试,必须得有“让你挂科”的能力。如果你怎么改代码,测试都能过,那这测试就是写着玩的。

  • 伪测试(对口型):
    你写了一个计算“加班费”的功能。为了省事,你的测试逻辑是:先让代码算一遍结果,然后把这个结果传给测试。
    • 例子: 代码算出加班费是 500 块,测试脚本就跟着说:“刚才算出来的是 500 块吗?是啊,那通过了。”
    • 为什么伪: 这就像是你考试时,老师问你“1+1等于几?”,你说“等于我写在纸上的那个数”。无论你纸上写的是 2 还是 3,你永远都是对的。这种测试无法证明你错了,它只是代码逻辑的“跟屁虫”。
  • 真测试(动真格):
    不管代码怎么写,测试心里有一本“明白账”。
    • 例子: 无论代码怎么算,测试就认准一条死理:时薪 100,加班 2 小时,结果必须是 200。如果代码算出来是 201,测试立马跳出来指着鼻子骂:“你算错了!”
    • 为什么真: 它有明确的反驳标准。它不关心你是怎么算的,它只关心结果对不对。这种“不给面子”的测试,才叫可证伪。

3.2. 关于“可验证性”:你是看“手术成功”,还是看“病人醒了”?

核心大白话: 别光听程序“叫唤”,要看实实在在的“证据”。

  • 伪测试(看个响儿):
    你做了一个“用户注销账号”的功能。
    • 做法: 脚本点了一下“注销”按钮,看到页面弹出一个“注销成功”的提示框,就认为测试通过了。
    • 为什么伪: 页面弹出“成功”可能只是前端的一行欺骗性代码。实际上,后台数据库里的用户信息可能根本没删,用户的隐私还在裸奔。这种验证是表象的、模糊的,就像医生说“手术很成功”,结果病人没下手术台。
  • 真测试(拿证据):
    不仅要看页面提示,还要去后台“抄家”。
    • 做法:
      • 点完注销,直接去查数据库:那个用户的手机号、密码还在不在?(应该不在了)
      • 试着用旧密码登录一下,能不能登进去?(应该登不进去了)
    • 为什么真: 这叫有明确、客观的结论。不看广告看疗效,每一个证据都是实打实的,这就叫可验证。

3.3. 关于“可重复性”:你是“目击证人”,还是“实验室记录员”?

核心大白话: 如果一个测试(不管是人测的还是机器测的)只有在“特定运气、特定心情、特定模棱两可的操作”下才能成功或失败,那它就不是科学,而是“玄学”。

  • 伪测试(“目击证人”式的模糊描述):
    • 场景: 测试人员提交了一个 Bug 或者写了一个测试步骤。
    • 描述: “打开搜索页面,随便搜几个词,多点几次翻页,有时候页面就卡死了。”
    • 为什么伪:
      • 不可重复: 开发者按照这个描述去操作,可能点了一百次也没卡死。
      • 变量未控制: “随便搜”、“多点几次”、“有时候”——这些词在科学里是禁忌。由于操作步骤具有巨大的随机性,这个测试得出的结论(“搜索功能有问题”)是不可复现的。
      • 结果: 这种测试无法形成有效的闭环,最后往往以“在我机器上是好的”或者“无法复现”而不了了之。这就像是说“我昨天在大街上看见外星人了”,但这事儿谁也复刻不了,它就不是科学。
  • 真测试(“实验室记录员”式的精确实验):
    • 场景: 同样的 Bug 发现过程。
    • 描述:
      • 使用账号 A(普通用户权限)登录。
      • 在搜索框输入关键词“华为”(确定的输入)。
      • 快速点击第 3 页,在页面加载完成前,立即点击“价格排序”按钮(确定的时机和动作)。
    • 为什么真:
      • 完全可重复: 无论谁拿到这份步骤,只要按照 1、2、3 去做,都能 100% 看到那个卡死的现象。
      • 排除干扰: 它明确了账号权限、搜索词、操作顺序。它把一个“偶然的灵异事件”变成了一个“必然的实验结果”。
      • 结果: 只有当测试步骤达到这种“物理级的确定性”时,它才具备了科学的公信力。开发者修完 Bug 后,再次按照这三个步骤跑一遍,发现不卡了,这才叫“验证通过”。

4. 为什么会存在伪测试

这是一个极其深刻的追问。伪测试的普遍存在,确实不仅仅是技术水平的问题,更多的是心理学、组织行为学与人性共同演化的结果。

如果说真测试是在搞“科学”,那么伪测试往往是在搞“仪式”。为什么聪明的人类会热衷于这种徒劳的仪式?

4.1. 证实偏差(Confirmation Bias):人类本能地拒绝“被打脸”

这是伪测试存在的逻辑底层。

  • 心理机制: 人类的大脑天生倾向于寻找能够支撑自己已有观点的证据,而不是反驳自己的证据。
  • 在开发中: 当开发者写完一段代码,潜意识里是“爱”它的,认为它是完美的。写测试时,大脑会下意识地引导你去测试那些你知道“肯定能跑通”的路径。
  • 结果: 开发者写出的测试往往是**“验证性测试” (证明我对了)而不是“批判性测试”**(证明我错了)。这种心理防线让我们很难写出真正具备“证伪性”的用例。

4.2. 焦虑缓解与“安全感错觉”(Psychological Safety Blanket)

这就是你提到的“心理按摩”。

  • 心理机制: 软件开发充满了不确定性,而人类厌恶这种不确定性带来的焦虑感。
  • 在开发中: “绿色的对勾”有一种神奇的镇静作用。即便测试写得很烂,即便断言(Assertion)是空的,只要看到一排绿色的 Passed,团队从开发者到经理都会产生一种虚假的安全感:“看,我们有测试,我们是受保护的。”
  • 结果: 测试在这里不再是质量工具,而成了“护身符” 。人们通过完成“写测试”这个动作来消解对线上事故的恐惧,而不关心这个动作是否真的有效。这是一种“防御性行为”。

4.3. 古德哈特定律(Goodhart's Law):当指标变成目标

“当一个指标变成目标时,它就不再是一个好指标了。”

  • 心理机制: 人类是奖惩驱动的。一旦外部施加了压力,人的动机就会从“做正确的事”转向“完成指标”。
  • 在开发中: 公司规定“单测覆盖率必须达到 80%”。这时,工程师的心理目标变了:我不是为了抓 Bug,我是为了填满那个百分比。
  • 结果: 于是产生了大量“为了覆盖而覆盖”的伪测试。比如测一下简单的 Getter/Setter,或者用一段毫无意义的代码跑一遍所有逻辑但不做实质校验。这就是**“科学表演”**(Scientific Theatre),穿上科学的外衣来迎合管理层的考核指标。

4.4. 认知失调(Cognitive Dissonance):掩盖失败带来的痛苦

  • 心理机制: 当一个专家(开发者)发现自己犯了低级错误时,会产生强烈的心理不适。
  • 在开发中: 如果真测试测出了一个巨大的架构缺陷,意味着开发者需要推翻重来,甚至承认自己的设计很愚蠢。为了避免这种痛苦,大脑可能会诱导我们写出一些“浅尝辄止”的测试,绕开那些核心痛点。
  • 结果: 伪测试成了掩盖“认知失调”的工具,它让人们可以心安理得地推迟面对那些真正困难、真正糟糕的代码问题。

4.5. 社会利他主义的缺失与冲突回避

  • 心理机制: 寻找错误本质上是一种“冲突性”行为。
  • 在开发中: 在某些团队文化中,测试人员如果找出了开发人员太多的 Bug,可能会被视为“找茬”或“不合群”。为了维持团队表面的和谐(和谐偏差),测试往往会变得温和、敷衍。
  • 结果: “你好我好大家好” 的温床催生了伪测试。大家达成了一种默契:我假装认真测,你假装代码没问题,我们按时上线,把矛盾留给未来的自己或用户。

4.6. 总结

伪测试之所以生命力顽强,是因为它顺应了人性

  • 它满足了人类的虚荣心(证明我是对的)。
  • 它缓解了人类的焦虑感(看,全绿了)。
  • 它完成了组织的KPI(指标达标了)。
  • 它维护了团队的和气(没出大问题)。

真测试则是理性的:

  • 它要求你自我否定(证明我是错的)。
  • 它要求你面对痛苦(揭露深层缺陷)。
  • 它要求你极度严谨(不留任何玄学空间)。

5. 结语

科学不是一种结果,而是一种不断与错误作斗争的过程

在软件开发行业中,

  • 伪测试 是一种仪式,它是为了掩盖不确定性而进行的心理按摩;
  • 真测试,是理性的契约。它不依赖于偶然的运气,也不寄托于主观的信心,而是以可证伪为骨架,以可验证的事实为砖瓦。

科学的核心从不是“绝对正确”。在软件开发中,我们也永远无法证明一个程序是绝对完美的,但我们可以通过可证伪、可验证、可重复的手段,把已知的黑暗区域一点点照亮。