实战演练:用等价类划分法为城市电话号码设计测试用例

实战演练:用等价类划分法为城市电话号码设计测试用例

1. 等价类划分法入门:从电话号码说起

刚入行测试那会儿,我最怕接到验证电话号码格式的任务。直到组长扔给我一本《软件测试基础》,里面提到的等价类划分法简直打开了新世界的大门。简单来说,这个方法就像给数据做垃圾分类——把相似的输入归到同一个桶里,每个桶选几个代表测试就够了。

拿城市电话号码来说,常见的格式规则包括:

  • 地区码:要么空白,要么是3位纯数字
  • 前缀:3位数字,但不能以0或1开头
  • 后缀:必须是4位纯数字

这就像我们小区快递柜的取件码:前三位是柜子编号(不能为0开头),后四位是验证码。测试这种规则时,没必要把所有数字组合都试一遍,只需要验证典型情况即可。

2. 实战拆解:电话号码的等价类划分

2.1 地区码的划分技巧

地区码这个字段很有意思,它允许空白也允许3位数字。根据这个特点,我们可以划分出:

有效等价类:

  1. 空白(比如" 234-5678")
  2. 3位纯数字(比如"(021)234-5678")

无效等价类:3. 包含字母(如"(A21)234-5678") 4. 不足3位(如"(12)234-5678") 5. 超过3位(如"(0213)234-5678")

我曾经踩过一个坑:测试时漏掉了带空格的无效情况(如"(02 )234-5678"),结果上线后发现有用户这样输入导致系统崩溃。所以划分时要像侦探一样,把所有可能的异常情况都考虑到。

2.2 前缀的特殊规则处理

前缀的规则更复杂些,需要特别注意"不能以0或1开头"这个限制:

有效等价类:6. 200-999之间的3位数字(如"234-5678")

无效等价类:7. 包含非数字字符(如"2A4-5678") 8. 以0开头(如"034-5678") 9. 以1开头(如"134-5678") 10. 不足3位(如"24-5678") 11. 超过3位(如"2345-5678")

这里有个实用技巧:测试边界值时,除了测试200和999这两个边界,还要测试199和1000这两个刚好越界的情况。

2.3 后缀的简单规则

后缀的规则相对简单,但也不能掉以轻心:

有效等价类:12. 4位纯数字(如"234-5678")

无效等价类:13. 包含非数字字符(如"234-56A8") 14. 不足4位(如"234-568") 15. 超过4位(如"234-56789")

3. 测试用例设计实战

3.1 有效用例设计原则

设计有效测试用例时,要记住两个黄金法则:

  1. 一个用例尽量覆盖多个有效等价类
  2. 确保所有有效等价类都被覆盖

比如这两个典型用例:

  • "(021) 805-9321":覆盖了地区码(3位数字)、前缀(非0/1开头)、后缀(4位数字)
  • " 276-2345":覆盖了地区码(空白)、前缀(非0/1开头)、后缀(4位数字)

3.2 无效用例设计要点

对于无效用例,必须遵守"一次只破坏一个规则"的原则:

  1. 地区码无效用例:

    • "(20A)123-4567"(含字母)
    • "(33 )234-5678"(不足3位)
    • "(7777)345-6789"(超过3位)
  2. 前缀无效用例:

    • "(777)34A-6789"(含字母)
    • "(234)045-6789"(以0开头)
    • "(777)145-6789"(以1开头)
  3. 后缀无效用例:

    • "(777)345-678A"(含字母)
    • "(777)345-678"(不足4位)
    • "(777)345-56789"(超过4位)

4. 常见踩坑与优化建议

4.1 新手容易忽略的测试点

  1. 极端空格情况:

    • 地区码括号内的空格"( 21)234-5678"
    • 连接符两侧的空格"234 -5678"
  2. 特殊字符注入:

    • SQL注入尝试"234'); DROP TABLE users--"
  3. 全角数字:

    • 使用中文输入法输入的数字"234-5678"

4.2 自动化测试实践

用Python+unittest实现基础验证:

import re import unittest def validate_phone(phone): pattern = r'^(\(\d{3}\)|\d{3})[- ]?\d{3}[- ]?\d{4}$' return bool(re.match(pattern, phone)) class TestPhoneValidation(unittest.TestCase): def test_valid_cases(self): self.assertTrue(validate_phone("(021)234-5678")) self.assertTrue(validate_phone("234-5678")) def test_invalid_cases(self): self.assertFalse(validate_phone("(02A)234-5678")) self.assertFalse(validate_phone("134-5678")) if __name__ == '__main__': unittest.main()

4.3 测试覆盖率提升技巧

  1. 使用边界值分析法补充用例:

    • 前缀测试199、200、999、1000
    • 后缀测试999、1000、9999、10000
  2. 组合测试:

    • 有效地区码+无效前缀+有效后缀
    • 无效地区码+有效前缀+无效后缀
  3. 国际化考虑:

    • 不同国家的电话号码格式
    • 带国家码的情况(如+86-21-12345678)

5. 从电话号码到复杂系统

掌握了电话号码这个案例后,可以将其扩展到更复杂的系统:

  1. 电商系统:

    • 商品价格(正数、最多两位小数)
    • 库存数量(非负整数)
  2. 用户注册:

    • 密码强度规则
    • 邮箱格式验证
  3. API接口测试:

    • 参数取值范围
    • 必填项验证

最近在测试一个物流系统,就用这个方法设计了运费计算模块的测试用例,发现了3个边界值处理的bug。关键是要把每个输入条件都当成独立的维度来分析,就像解魔方一样,一层层拆解才能看到全貌。