输入划分与边界值:有限用例怎样区分相似的错误规则

发布时间:2026/10/30 17:12:21
输入划分与边界值:有限用例怎样区分相似的错误规则

同一项优惠计算,测试 50 元和 150 元都正确,用户买到恰好 100 元时却没有得到优惠。问题不在金额样本太少,而在所选样本没有区分两种写法:“至少 100 元”和“超过 100 元”。远离门槛时,它们给出相同结果;只有门槛本身能暴露漏掉的等号。

有限测试必然需要选择输入。有效的选择先把预期处理方式不同的输入分开,再把注意力放到规则发生切换的位置。代表值提供对一类处理的观察,边界值区分相邻规则;它们都需要明确的需求和能让差异显现的其他条件。

本文使用一条假设规则:金额以整数分表示,合法范围为 0 至 100,000,000;金额达到 10,000 分,且会员或另一项优惠资格至少有一种有效,享受一次折扣。折扣额是金额的十分之一向下取整,应付金额为原金额减去折扣额。非法输入返回错误,不计算应付金额。这里只分析计算约定,不涉及真实交易。

文章目录

    • 输入分组建立的是假设,不是证明
    • 边界值为什么能够区分相似实现
    • 一个边界能否被测到,还取决于其他输入
    • 拒绝输入,也有不止一种失败方式
    • 分区和性质都要随真实规则调整

输入分组建立的是假设,不是证明

先固定会员有效、另一项资格无效。金额可以按预期处理分成四组:小于 0 应拒绝,0 至 9,999 原价,10,000 至 100,000,000 计算优惠,超过上限应拒绝。按照处理方式将输入分组,再从每组选择代表的方法,叫作等价类划分。

例如 −1、5,000、20,000、100,000,001 分别触及四类行为。它们适合检查几条基本处理是否存在,但不能证明组内每个值都正确。“等价”是基于已知规则作出的测试假设,不是已经证明程序对这组输入完全一致。

同一优惠区间里,还存在取整差异。20,000 的十分之一是整数,10,006 的十分之一则不是。若程序错误地四舍五入折扣,前者看不出问题,后者才有辨别力:规定折扣额为 1,000,应付 9,006;错误取整可能算成折扣 1,001、应付 9,005。

因此,分区不只来自一条外层条件。若当前风险涉及取整,就应进一步关注金额除以 10 的余数;若风险涉及数值转换,还要关注相关表示范围。并不需要立刻枚举每个值,而是让分区随着已确认的处理差异细化。原先一个代表值失效,往往说明模型过粗,不能靠继续引用旧的分区覆盖来消除这个事实。

边界值为什么能够区分相似实现

固定有效资格后,门槛附近的结果为:

金额,单位分是否优惠预期应付,单位分
9,999否9,999
10,000是9,000
10,001是9,001

10,000 区分“大于等于”与“大于”;两侧邻近值则检查切换位置及其方向。围绕已识别的边界选择输入,称为边界值分析。边界不是因为数值特殊才有用,而是许多实现差异只会在这些位置转化为不同输出。

只测边界与外侧,仍可能放过另一类错误。要求 x≤10,代码却写成 x=10:输入 10 时都为真,输入 11 时都为假,加入 9 才能看出范围被误缩成一个点。因此,选择两侧邻居应当能说清它们排除什么错误,而不是机械套用固定数量。

邻近的含义由输入单位决定。本例用整数分,10,000 的相邻金额是 9,999 和 10,001。若用整元输入的 99、100、101,检查的是另一种离散尺度。接口允许十进制字符串时,还需要明确小数位、解析与舍入约定,不能把浮点表示误差与业务门槛混成一个问题。

边界方法也有适用前提。金额、长度和时间通常有明确顺序;会员等级、文件类型等类别没有同样意义的左右邻居。类别差异应靠分组和组合建模,不能为了套方法给它们虚构数值距离。

一个边界能否被测到,还取决于其他输入

如果三条门槛用例都使用非会员且无其他资格,所有输入都原价。金额确实经过门槛附近,错误的比较符号却不会改变应付结果,因为资格条件已经使优惠不可能发生。

要观察金额边界,就需要先让资格有效;要观察会员资格,则应固定金额达标,并关闭另一项资格,避免它替会员条件满足整个规则。选择其他输入的作用,是让当前关心的差异能够影响结果。

还要考虑前置校验。金额输入在解析阶段被拒绝时,后面的优惠判断根本没有执行。测试数据含有“10000”这几个字符,并不等于整数门槛已经被检查。失败位置和观察结果必须与所声称的规则对应。

这种安排并不是要求每次只改变一个参数。它是在设计具有辨别力的背景条件:研究哪个风险,就避免其他条件把它遮住。涉及多个资格相互作用时,可以增加组合测试;需要证明复杂判定中每个条件的独立作用时,可以使用成对比较。但这些方法不会替代金额门槛本身的精确取值。

拒绝输入,也有不止一种失败方式

合法区间的下限与上限,是优惠门槛以外的边界。−1 与 0 区分拒绝和接受;100,000,000 与 100,000,001 同样如此。恰好 0 应按规则接受并返回 0,不能因“金额必须为正”的未经确认假设把它拒绝。

非法输入也不能永远合成一组。负整数可能在范围检查失败,空值可能在必填检查失败,字符串可能在类型检查失败,小数可能被错误截断后接受。它们处于不同处理阶段,一条负数用例不能代替所有非法类型。

多项无效条件同时出现时,前一项错误还可能遮住后一项。假设一条请求既缺少资格字段,金额又超过上限,程序在缺字段处返回了错误,并不能说明上限检查存在。若要检查金额拒绝,应先让其他必需字段有效;若接口规定错误优先级,则另有理由检查同时无效时返回什么。

对于本例计算函数,拒绝的观察可以是指定错误类型以及没有应付金额。若它被用于实际订单系统,页面报错后后台是否仍创建订单,则属于更外层的行为,需要在连接这些部件的范围观察。输入方法可以复用,结论却不能从计算函数直接扩展为整项业务安全。

分区和性质都要随真实规则调整

一份测试集覆盖了已识别的四个金额分区,可以说这四个分区都有代表输入,不能说全部金额正确率为 100%。增加空值、类型和取整方面的分区后,统计对象也随之变化。边界覆盖同样要说清范围、步长以及检查了哪些边界;优惠门槛附近测得很细,不表示合法上限也已验证。

预期结果不能从程序当前输出反推。有些看起来合理的关系,在优惠规则下反而错误。例如“购物金额提高,应付金额不能下降”:有资格的用户从 9,999 增加到 10,000 分,应付金额会从 9,999 降至 9,000。这是规则造成的正常跳变。用直觉替代需求,会让测试拒绝正确实现。

更适合本例的关系是:固定金额与另一项资格,将非会员改为会员,应付金额不应增加。但它单独仍很弱,始终返回零的错误实现也符合。因此,性质检查需要配合可信的具体金额,明确能排除什么、不能排除什么。

分组、边界和预期是一套连续判断:规则决定哪些输入处理不同,边界揭露处理切换的错误,其他条件保证差异能显现,输出核对再确认实际结果。增加一个输入的价值,来自它对尚未解决问题的辨别力,而不是它让用例表多了一行。


来源:ISTQB CTFL 官方入口;v4.0.1 大纲中的等价类划分与边界值分析;测试判定依据综述。范围判断 x≤10 与 x=10 的辨别例依据大纲;金额和资格规则为假设示例。

GitHub 知识库