# 软件测试

# bug

  • 用户使用一个软件,可能发现一些问题、缺陷,俗称为 bug 。

    • 例如软件不能启动,软件显示的字符串乱码。
    • 用户认定的一个 bug ,在程序员看来可能并非 bug 。
      • 例如,软件的某个功能正常运作,但用户不习惯该功能,就认为它有问题。
      • 尽管如此,开发软件时,应该尽量满足用户的需求、符合用户的习惯。
  • 根据严重程度的不同,可将 bug 分类为:

    • 致命错误
      • :不能实现基础功能、重要功能。可能造成大幅损失,必须立即处理该问题。
    • 严重错误
      • :没有实现次要功能,或者性能差。
    • 一般错误
      • :一些轻度问题,不急着处理。
    • 不重要
      • :比如代码排版问题。
    • 建议
      • :一些建议,试图优化软件。
  • 解决一个软件 bug 的流程:

    1. 描述这个 bug 是什么样子。
    2. 描述该 bug 的复现步骤,从而分享给同事排查。
    3. 估计该 bug 的大致原因,然后逐步排查,逐步缩小嫌疑范围。
  • 对 bug 的认知:

    • 测试的目标,不是找出多少个 bug ,而是为了改善用户使用该软件的体验,以用户需求为核心。
    • 不要害怕发现软件的 bug 。因为一个 bug 只要存在,早晚都会被发现。越早发现,就能越早解决。

# 测试用例

  • 正式测试一个软件之前,需要为每项测试任务,编写一个测试用例(Test Case),保存成 word 文档或 pdf 文档。

  • 每个测试用例的基本内容:

    • 标题
    • 测试前的准备工作
    • 测试步骤
    • 测试结果
    • 预期结果
  • 测试时,应该先故意让软件出错,证明该测试用例可以发现问题。

  • 测试覆盖率

    • :表示全部测试用例,能检查软件的多少特征。
    • 理想的测试覆盖率是 100% ,但这是不切实际的。
      • 测试环节不可能发现软件的所有 bug 。
      • 一味地追求测试覆盖率,会大幅增加测试成本。
    • 如何统计测试覆盖率?
      • 测试时,触发了软件中多少代码
      • 测试时,尝试了多少种可能的输入值
  • 如何设计一个测试用例?常见的几种方法如下

    • 评定表法
      • :已知软件的判断逻辑时,将各种判断逻辑整理成一个评定表,然后逐一测试软件能否实现这些判断逻辑。
      • 例如当输入为 True 时,软件应该怎么做。当输入为 False 时,软件应该怎么做。
    • 正交分析法
      • :将影响软件运行的各个输入变量,整理成表,就得到了大量变量组合,然后分析每个变量组合对软件的影响。
    • 等价类划分法
      • :软件的输入值可能有无数种,不可能每种都测试一遍。因此,通常将输入值划分为几种类型,每种类型选出一个代表,用于测试。
      • 例如,11 和 12 都属于 int 类型,hello 和 world 都属于 string 类型。
    • 边界值分析法
      • :已知软件输入值的有效范围时,尝试输入这个范围的边界值,看软件是否正常。
      • 例如,一年里,1 月和 12 月是边界值,软件可能不会正确处理边界值。
    • 错误推测法
      • :已知软件可能出错的几种情况时,故意在这些情况下测试软件。
    • 模糊测试
      • :测试各种意外的情况、随机的输入值,看软件是否正常。
    • 流程分析法
      • :检查软件的运行流程是否符合预期。

# 测试方式

  • 根据是否自动测试,可将测试方式分类为:

    • 手动测试
    • 自动测试:主要用于一些经常重复执行的测试用例。
  • 根据是否启动待测试的软件,分类为:

    • 静态测试
      • :不启动软件,只是检查源代码、配置文件等内容。
    • 动态测试
      • :启动软件,然后检查软件的运行状态、使用效果。
  • 根据是否阅读软件的源代码,分类为:

    • 白盒测试(white box test)
      • :阅读源代码,理解软件的原理,找出软件内部的问题。
    • 黑盒测试(the black box test )
      • :不阅读源代码,只是分析软件的外部特征。
    • 灰盒测试
      • :综合使用白盒测试和黑盒测试。
  • 根据软件的开发阶段,分类为:

    • 单元测试(unit test)
      • :修改软件的某个功能单元之后,单独测试该功能单元。此时不测试其它功能单元,因为集成测试的耗时更久。
    • 集成测试(integration test)
      • :等单元测试通过之后,需要将修改的功能单元集成到软件中,测试全部功能单元。因为修改某个功能单元之后,可能干扰其它功能单元。
    • 系统测试(System test)
      • :对于整个软件系统,执行大量测试用例。
      • 集成测试偏向于白盒测试,针对软件的各个功能单元。而系统测试偏向于黑盒测试,不了解软件的原理,只关注它的外部特征。
    • 验收测试(acceptance test)
      • :一个软件交付给客户时,客户通常会自己测试一遍该软件,检查该软件是否满足合同的各项要求。
    • 回归测试(regression test)
      • :如果修改了一个已交付的软件,即使改动幅度很小,也要重新执行一遍系统测试,检查软件能否通过所有测试用例。
  • 根据测试目标的不同,分类为:

    • 冒烟测试(smoke test)
      • :检查软件能否实现一些基本需求。
      • 比如软件能否启动?如果软件不能启动,就不能展开进一步的测试。
    • 功能测试(functional test)
      • :检查软件的某个功能是否正常,是否与预期结果一致。
    • 异常测试
      • :检查软件的容错性怎么样。
      • 例如软件能否处理一些异常情况、软件出错时是否会提示用户、是否会输出日志。
    • 性能测试(performance test)
      • :即使软件能实现某个功能,但还需要检查其实现效果。
      • 例如软件运行时占用多少计算机内存、能支持多少人同时使用、能否长时间稳定运行。
    • 负载测试(load test)
      • :测试几种不同负载情况下,软件的运行状态。
      • 例如被 10 个、100 个用户同时使用。
    • 压力测试(stress test)
      • :逐渐增加负载压力,找到软件的最大承受能力。
    • 稳定性测试
      • :在某种程度的负载压力下,测试软件长时间运行的稳定性(比如延迟多大)。
    • 极限测试
      • :施加最大负载压力,测试软件在极限情况下能坚持运行多长时间,稳定性怎么样。
    • 兼容性测试
      • :测试软件对 Linux、Windows 等不同平台的兼容性。
    • 安全性测试
      • :检查软件保护用户的隐私数据,能否抵御各种黑客攻击方式。
      • 例如故意尝试 SQL 注入,看软件是否受影响。
  • AB 测试

    • :制定两种方案,交给用户试用,然后检查哪个方案更让用户满意。
    • 例如 Web 网站发布两种 UI ,分别给两组用户试用。
  • Mock 测试

    • :当测试对象不容易获得时,仿制一个假对象来进行测试。
    • 例如测试一个创建用户的 API 时,输入一些假人名。