Skip to content

软件测试 - 测试级别

软件测试是一个多层面过程,涉及各种阶段(称为级别)和不同侧重点(称为类型)。理解这些有助于构建全面的测试策略。本章描述了常见的测试级别和基本的测试类型。

测试级别通常指在软件开发生命周期(SDLC)中执行测试的阶段,通常包括单元测试 (Unit Testing)、集成测试 (Integration Testing)、系统测试 (System Testing) 和验收测试 (Acceptance Testing)。在这些级别内部和跨级别,根据评估软件的哪个方面,会进行各种类型的测试。主要类别包括功能测试 (Functional Testing) 和非功能测试 (Non-functional Testing)。

功能测试是一种黑盒测试 (Black-box Testing),用于根据指定的软件功能需求验证软件。它侧重于系统做什么。测试人员提供输入,并验证输出是否与需求文档(例如,用户故事、用例、功能规范)中定义的预期结果相符。目标是确保软件从用户角度来看按预期运行,涵盖功能、操作和业务逻辑。

功能测试的过程通常包括以下关键步骤:

步骤描述
I根据需求确定软件预期执行的功能。
II为每个功能创建测试数据并定义预期结果。
III开发涵盖各种场景的测试用例,包括正面路径和负面路径。
IV通过提供输入并观察系统行为来执行测试用例。
V比较实际结果与预期结果,并报告任何差异(缺陷)。

有效的功能测试对于交付满足用户需求的优质产品至关重要。它可以在所有测试级别(单元测试、集成测试、系统测试和验收测试)执行。例如,行为驱动开发 (BDD) 框架(如 Cucumber 或 SpecFlow)有助于以人类可读的格式定义功能测试,从而弥合技术团队和业务利益相关者之间的差距。通过搜索“行为驱动开发实践”了解更多信息。

单元测试是第一个测试级别,通常由开发者执行。它侧重于测试源代码的单个、独立的组件或模块(例如,函数、方法或类),以验证它们是否正确工作。开发者经常使用单元测试框架(如 JUnit (Java)、NUnit (.NET)、PyTest (Python) 或 Jest (JavaScript))来编写和执行这些测试。

单元测试的主要目标是隔离程序的每个部分,并确保其在逻辑和功能方面是正确的,然后再将其与其他部分集成。这种早期发现缺陷的方法显著降低了修复成本。测试驱动开发 (TDD) 是一种流行的实践,开发者在编写实际代码之前编写单元测试,从而指导开发过程。

虽然单元测试是基础性的,但理解其范围很重要。它验证独立单元,通常使用 Mock 对象或 Stub 来模拟依赖项。它不能保证集成后的系统将正确工作,也不能发现所有 bug。然而,一套全面的单元测试提供了一个重构的安全网,简化了调试,并提高了代码质量。这些测试通常是自动化的,并且频繁运行,通常作为持续集成 (CI) 流水线的一部分。

实际应用:一个编写 ‘calculateDiscount’ 函数的开发者会编写单元测试来涵盖各种场景:普通客户的折扣、高级客户的折扣、无折扣、无效输入等,确保该函数在每种情况下都按预期运行。

集成测试是将单个软件模块、组件或服务组合在一起并作为一个组进行测试的级别。主要目的是暴露这些集成单元之间交互中的缺陷。这在现代架构(如微服务)中至关重要,其中许多独立的服务的通过 API 进行通信。Postman、REST Assured 或 Karate DSL 等工具常用于 API 集成测试。

常见的集成测试策略包括:

策略描述
大爆炸集成 (Big Bang Integration)一次性或大部分模块组合在一起进行测试。难以隔离故障。通常不推荐用于大型系统。
自顶向下集成 (Top-Down Integration)从顶层模块开始测试,低层模块逐个集成。可能需要 Stub 来模拟缺失的低层模块。
自底向上集成 (Bottom-Up Integration)从最低层模块开始测试,然后将其与高层模块集成。可能需要 Driver 来模拟高层模块。
三明治/混合集成 (Sandwich/Hybrid Integration)结合了自顶向下和自底向上方法。先测试中间层,然后同时向上和向下进行集成。

在复杂系统中,经常使用服务虚拟化或 Mock 框架(例如 Mockito、WireMock)来模拟不可用或不稳定的依赖项,从而允许进行更集中的集成测试。有效的集成测试可确保应用程序的不同部分无缝协同工作。

系统测试是验证完整且完全集成的软件产品是否符合其指定需求的测试级别。它通常是由专门的测试团队或 QA 工程师执行的黑盒测试。目标是从端到端视角评估系统是否符合功能需求和非功能需求。

系统测试很重要,因为:

  • 它验证整个系统作为一个整体,模拟真实用户场景。
  • 它检查应用程序是否满足所有指定的功能、技术和业务需求。
  • 它通常在与生产环境非常相似的环境中执行(例如,预演环境或预生产环境)。
  • 它有助于发现不同组件之间交互、系统稳定性、性能和安全性方面的问题,这些问题可能在较低级别的测试中无法发现。

实际应用:对于一个电商网站,系统测试将涉及测试整个用户旅程:搜索商品、加入购物车、用户注册/登录、结账、支付处理和订单确认,确保所有集成部分协同工作正确。

回归测试用于确保新的代码变更、bug 修复或增强功能没有对现有功能产生不利影响或引入新的缺陷。它涉及在修改后的软件上重新运行先前执行过的测试用例。目的是验证系统在变更后仍然按预期运行。

回归测试对于长期保持软件质量至关重要,因为:

  • 它提供了对最近更改未破坏现有功能的信心。
  • 它有助于降低与软件修改相关的风险。
  • 它是持续集成/持续交付 (CI/CD) 流水线的关键组成部分,自动化回归测试套件经常运行。
  • 有效的回归测试有助于保持测试覆盖率并支持更快的发布周期。

由于其重复性,回归测试是自动化的理想选择。选择正确的回归测试用例子集(例如,基于风险或变更影响)对于平衡覆盖率和执行时间非常重要。有关更多信息,请研究“回归测试选择技术”。

验收测试通常是软件发布前的最终测试阶段,用于确定系统是否满足业务需求并可供交付。它通常由最终用户、客户、产品负责人或专门的用户验收测试 (UAT) 团队执行。重点是从业务或用户角度验证软件的适用性。

验收测试的关键方面:

  • 根据用户需求、需求和业务流程验证软件。
  • 通常涉及执行反映真实世界使用情况的测试场景。
  • 让利益相关者相信系统已准备好进行部署。
  • 在从供应商接受软件之前,可能是合同要求的一部分。

常见的验收测试形式包括:

Alpha 测试是一种内部验收测试,由组织内部团队(例如 QA、产品管理、员工)在向外部用户发布产品之前执行。它在受控环境中进行,通常模拟真实用户场景。目标是尽早识别重大 bug 和可用性问题。

在 Alpha 测试期间,测试人员查找:

  • 主要功能缺陷和崩溃。
  • 可用性问题和令人困惑的工作流。
  • 在典型内部负载下的性能瓶颈。
  • 产品的整体完整性和准备情况。

Beta 测试,也称为发布前测试或现场测试,在 Alpha 测试之后进行。软件发布给有限数量的外部真实用户(Beta 测试人员),在他们的实际环境中进行。这提供了关于软件在真实世界条件下的性能、可用性和可靠性的反馈。

Beta 测试的主要活动和益处包括:

  • 用户在多样化的真实世界环境中、各种硬件和网络条件下安装和使用应用程序。
  • 收集关于 bug、可用性问题、性能和整体满意度的反馈。
  • 有助于发现受控实验室环境中可能无法发现的问题。
  • 允许开发团队在全面公开发布之前解决关键问题并收集用户见解,从而提高产品质量和客户满意度。

非功能测试评估软件系统的非特定功能相关的特征,而是评估系统如何运行。这些方面通常称为质量属性或“-ilities”(例如,性能、安全性、可用性、可靠性、可伸缩性),对于用户满意度和系统成功至关重要。

常见的非功能测试类型包括:

性能测试评估系统在各种负载条件下的响应性、稳定性、可伸缩性和速度。其目标是识别性能瓶颈而非功能 bug。性能差的常见原因包括网络延迟、低效代码、数据库瓶颈或硬件资源不足。

性能测试评估的关键方面:

  • 速度(例如,响应时间、页面加载时间)。
  • 可伸缩性(处理增加负载的能力)。
  • 稳定性(在持续负载下的行为)。
  • 容量(系统可处理的最大负载)。

性能测试包括几种子类型:

负载测试评估系统在预期正常和高峰负载条件下的行为。它有助于确定系统是否可以在可接受的性能目标范围内处理预期的并发用户和事务数量。Apache JMeter、K6、Gatling 或 Micro Focus LoadRunner 等自动化工具常用于模拟虚拟用户 (VUser) 并生成负载。

压力测试将系统推至其正常操作极限之外,以观察其在极端条件下的行为。这有助于识别其崩溃点以及如何从故障中恢复。场景可能包括非常高的事务量、低内存或网络中断。其他相关类型包括尖峰测试 (Spike Testing)(负载突然爆发)和浸泡/耐久性测试 (Soak/Endurance Testing)(长时间持续负载)。

可用性测试评估软件产品对其目标用户来说有多容易、高效和令人满意。它通常是一种黑盒技术,涉及观察真实用户在使用系统时执行任务。目标是识别可用性缺陷并收集反馈进行改进。

通常考虑的关键可用性因素(受 Nielsen 启发式原则启发)包括:可学习性 (Learnability)、效率 (Efficiency)、可记忆性 (Memorability)、错误预防/恢复 (Error prevention/recovery) 和用户满意度 (User Satisfaction)。可以使用各种方法,例如有引导/无引导测试、A/B 测试、启发式评估和调查。有关更多信息,请研究“Nielsen 的可用性启发式”。

UI 测试与可用性测试 (UI vs. Usability Testing)

Section titled “UI 测试与可用性测试 (UI vs. Usability Testing)”

UI (用户界面) 测试侧重于验证应用程序的图形元素——确保按钮、菜单、表单和其他视觉组件外观和功能符合规范(例如,正确的颜色、对齐方式、响应能力)。Selenium、Cypress 或 Playwright 等工具可以自动化 UI 检查。

另一方面,可用性测试范围更广。它评估整体用户体验和易用性,这包括 UI,但也包括任务流、信息架构和直观性。虽然 UI 测试可以高度自动化,但可用性测试通常需要定性的人工观察和反馈。

安全测试旨在发现软件系统中的漏洞,并确保其数据和资源免受威胁。关键的安全原则(通常称为 CIA 三元组等)包括:

  • 机密性 (Confidentiality):保护敏感信息免遭未经授权的披露。
  • 完整性 (Integrity):确保数据准确性并防止未经授权的修改。
  • 可用性 (Availability):确保系统及其数据在需要时可供授权用户访问。
  • 认证 (Authentication):验证用户或系统的身份。
  • 授权 (Authorization):根据身份授予或拒绝资源访问权限。
  • 不可否认性 (Non-repudiation):确保操作可以追溯到其发起者。

常见的安全测试实践包括漏洞扫描、渗透测试 (Penetration Testing / Pentesting)、安全代码审查以及针对 OWASP Top 10 中列出的常见攻击手段的测试(例如,SQL 注入、跨站脚本攻击 (XSS)、失效的认证)。现代开发通常将 SAST (静态应用安全测试) 和 DAST (动态应用安全测试) 工具集成到 CI/CD 流水线中,作为 DevSecOps 方法的一部分。有关更多详细信息,请查阅“OWASP Top 10 项目”。

可移植性测试评估软件在不同环境中转移和运行的容易程度。这些环境可以包括各种操作系统(Windows、macOS、Linux)、浏览器(Chrome、Firefox、Safari、Edge)、硬件配置或云平台。

可移植性测试的关键方面包括:

  • 可安装性 (Installability):确保软件可以在不同的目标环境中正确安装。
  • 兼容性 (Compatibility):验证软件与其他软件一起或在同一平台的不同版本之间按预期运行。
  • 适应性 (Adaptability):检查软件是否可以适应不同的屏幕尺寸、分辨率或本地化。
  • 平台独立性 (Platform Independence):对于设计为跨平台的应用程序,确保行为一致。容器化技术(例如 Docker)通过将应用程序及其依赖项打包在一起,极大地有助于可移植性。

有效可移植性测试的前置条件包括从一开始就为可移植性进行设计,适当地使用跨平台框架,以及能够访问多样化的测试环境或模拟器 (Emulator/Simulator)。