什么是功能测试?

已完成

在本部分中,你加入了 Tailspin 团队,因为他们将为其管道定义功能测试。 功能测试可验证软件的每个功能是否都能正常工作。

团队首先定义功能测试所涵盖的内容。 他们探讨了某些类型的功能测试。 然后,他们决定了要添加到其管道中的第一个测试。

每周会议

团队正在进行每周会议。 Andy 正在展示发布管道。 团队监视着一个成功的生成在管道中移动,从一个阶段移动到另一个阶段。 最后,该 Web 应用升级到了“过渡”。

Amita:我对管道感到非常满意。 它使我的生活变得更加轻松。 一方面,我可以自动将发布部署到测试环境。 这意味着我不必在测试服务器上手动下载和安装生成工件。 这可以节省大量时间。

此外,Mara 和 Andy 编写的单元测试可在我进行发布之前消除所有回归 bug。 这消除了一个主要的挫折来源。 我无需花时间查找和记录回归 bug。

但我担心我的所有测试仍是手动的。 此过程很慢,在完成之前我们无法向管理层展示任何内容。 这很难,因为测试非常重要。 测试可确保用户获得正确的体验。 但现在的压力是加快交付速度。

Andy:我相信我们能帮你。 什么类型的测试会占用你大部分时间?

Amita:我认为是 UI 测试。 我必须单击每个步骤,以确保我得到正确的结果,并且我必须针对我们支持的每个浏览器执行此操作。 这很费时。 而且随着网站复杂性的增长,从长远来看,UI 测试将不再实用。

Mara:UI 测试被视为是功能测试。

Tim:相对于什么,非功能测试?

Mara:没错。 非功能测试是你特别关心的内容。

Tim:好吧,我很困惑。

什么是功能测试和非功能测试?

Mara:功能测试可验证软件的每个功能是否都能正常工作。 在这些测试中,软件如何实现每个功能并不重要。 重要的是,软件的行为正确。 你提供输入,并检查输出是否符合预期。 这就是 Amita 测试 UI 的方式。 例如,如果她选择了排行榜上的顶级玩家,则她希望看到该玩家的个人资料。

非功能测试会检查性能和可靠性等特性。 非功能测试的一个示例是检查多少人可以同时登录该应用。 负载测试是非功能测试的另一个示例。 Tim,这些性能和可靠性方面的问题是你关心的内容。

Tim:的确如此。 对于这一点,我需要考虑一下。 我可能也想向管道添加一些自动化功能,但我不确定我想做什么。 我可以运行哪些类型的自动测试?

Mara:现在,让我们重点关注功能测试。 Amita 所做的就是这种测试。 这似乎是一个需要改进的领域。

我可以运行哪些类型的功能测试?

功能测试有很多种。 它们因需要测试的功能和运行所需的时间或工作而异。

以下各节介绍了一些常用的功能测试。

冒烟测试

冒烟测试可验证应用程序或服务的最基本功能。 这些测试通常会在执行更完整和详尽的测试之前运行。 应快速运行冒烟测试。

例如,假设你正在开发一个网站。 冒烟测试可能会使用 curl 来验证该站点是否可访问,以及提取主页是否会产生 200(正常)HTTP 状态。 如果提取主页时产生了另一种状态代码,如 404(未找到)或 500(内部服务器错误),则表明该网站无法正常运行。 同时还表明没有理由运行其他测试。 相反,你应诊断错误,进行修复,然后重新启动测试。

单元测试

你在使用 Azure Pipelines 在生成管道中运行质量测试模块中使用了单元测试。

简而言之,单元测试将验证程序或库的最基本组件,例如单个函数或方法。 可以指定一个或多个输入以及预期结果。 测试运行程序将执行每个测试,并查看实际结果与预期结果是否匹配。

例如,假设你有一个函数,该函数执行包含除法的算术运算。 你可以指定一些希望用户输入的值。 还可以指定如 0 和 -1 这样的极端值。 如果期望某个输入会产生错误或异常,则可以验证该函数是否会产生该错误。

稍后将在本模块中运行的 UI 测试是单元测试。

集成测试

集成测试可验证多个软件组件是否可以一起构成一个完整的系统。 例如,电子商务系统可能包含网站、产品数据库和支付系统。 你可以编写一个集成测试,将商品添加到购物车,然后购买商品。 该测试可验证 Web 应用程序是否可以连接到产品数据库然后完成订单。

可以将单元测试和集成测试结合起来以创建分层测试策略。 例如,你可以在运行集成测试之前,对每个组件运行单元测试。 如果所有单元测试均通过,则可以更有信心地进行集成测试。

回归测试

添加或更改功能后,现有行为更改或中断时,会发生回归。 回归测试有助于确定代码、配置或其他更改是否会影响软件的整体行为。

回归测试很重要,因为一个组件的更改可能会影响另一个组件的行为。 例如,假设你优化了数据库以提高写入性能。 该数据库的读取性能(由另一个组件处理)可能会意外下降。 读取性能的下降就是一种回归。

你可以使用各种策略来测试回归。 这些策略通常会因你运行测试的次数而异,以验证新功能或 bug 修复不会破坏现有功能。 但是,当你对测试进行自动化时,回归测试可能会涉及在每次软件更改时运行所有单元测试和集成测试。

健全性测试

健全性测试包括测试一款软件的每个主要组件,以验证软件是否可以正常运行,并且可进行更全面的测试。 可以将健全性测试视为不如回归测试或单元测试彻底,但健全性测试比冒烟测试更广泛。

尽管可自动执行健全性测试,但通常会手动完成此操作,以响应功能更改或 bug 修复。 例如,验证 bug 修复的软件测试人员还可以通过输入一些典型值来验证其他功能是否正常运行。 如果该软件按预期正常运行,则可以进行更全面的测试。

用户界面测试

用户界面 (UI) 测试可验证应用程序用户界面的行为。 UI 测试有助于验证用户交互的顺序是否会产生预期的结果。 这些测试还有助于验证输入设备(例如键盘或鼠标)是否会正确影响用户界面。 可以运行 UI 测试来验证本机 Windows、macOS 或 Linux 应用程序的行为。 或者,可以使用 UI 测试来验证 UI 在 Web 浏览器中的行为是否符合预期。

单元测试或集成测试可以验证 UI 是否正确接收数据。 但是 UI 测试有助于验证用户界面是否正确显示,以及结果是否符合用户预期。

例如,UI 测试可以验证单击按钮后是否会显示正确的动画。 第二次测试可以验证在调整窗口大小后,是否会正确显示同一动画。

在本模块中,你将使用手动编码的 UI 测试。 但也可以使用捕获和重播系统来自动生成 UI 测试。

可用性测试

可用性测试是一种手动测试形式,可以从用户的角度验证应用程序的行为。 可用性测试通常由构建软件的团队来完成。

UI 测试侧重于功能是否按预期方式运行,而可用性测试则有助于验证软件是否直观并且满足用户的需求。 换句话说,可用性测试有助于验证软件是否“可用”。

例如,假设你有一个网站,其中包含指向用户个人资料的链接。 UI 测试可以验证该链接是否存在,以及在单击该链接时是否会显示用户的个人资料。 但是,如果人们无法轻松地找到此链接,则当他们尝试访问其个人资料时可能会感到沮丧。

用户验收测试

用户验收测试 (UAT) 与可用性测试一样,侧重于从用户的角度看待应用程序行为。 与可用性测试不同,UAT 通常由真正的最终用户完成。

根据软件的不同,可能会要求最终用户完成特定任务。 或者,他们可以在不遵循任何特定准则的情况下浏览软件。 对于自定义软件,UAT 通常直接在客户端上进行。 对于更通用的软件,团队可能会运行 beta 版本测试。 在 beta 版本测试中,来自不同地理区域的用户或具有特定兴趣的用户可以提前使用软件。

测试人员的反馈可以是直接的也可以是间接的。 直接反馈可能以口头评论的形式出现。 间接反馈可以通过测量测试人员的肢体语言、眼部动作或完成特定任务所花费的时间来体现。

我们已经介绍了编写测试的重要性。 但为了强调这一点,下面有一个简短的视频,其中 Abel Wang(Microsoft 的云大使)介绍了如何帮助确保 DevOps 计划的质量。

询问 Abel

团队的选择是什么?

Tim:所有这些测试听起来都很重要。 我们应首先解决哪一个?

Andy:我们已经有了工作单元测试。 我们尚未准备好执行用户验收测试。 根据我的观点,我认为应该将重点放在 UI 测试上。 目前,这是我们流程中最慢的部分。 Amita,你同意吗?

Amita:是的,我同意。 这次会议还剩一些时间。 Andy 或 Mara,你们想帮助我规划自动 UI 测试吗?

Mara:当然。 不过,让我们进行一些初步的准备。 我想讨论一下我们应该使用哪种工具,以及如何运行这些测试。

可以使用哪些工具来编写 UI 测试?

Mara:编写 UI 测试时,我们有哪些选项? 我知道有很多。 一些工具是开源的。 其他一些提供付费的商业支持。 以下是一些可供考虑的选项:

  • Windows 应用程序驱动程序 (WinAppDriver):WinAppDriver 可帮助你在 Windows 应用上自动执行 UI 测试。 可以通过通用 Windows 平台 (UWP) 或 Windows 窗体 (WinForms) 来编写这些应用。 我们需要一种可在浏览器中使用的解决方案。
  • Selenium:Selenium 是适用于 Web 应用程序的可移植开源软件测试框架。 它可在大多数操作系统上运行,并且支持所有新式浏览器。 可以通过多种编程语言(包括 C#)编写 Selenium 测试。 事实上,你可以使用一些 NuGet 包轻松地将 Selenium 作为 NUnit 测试运行。 我们已将 NUnit 用于单元测试。
  • SpecFlow:SpecFlow 适用于 .NET 项目。 它的灵感来自一个叫做 Cucumber 的工具。 SpecFlow 和 Cucumber 都支持行为驱动开发 (BDD)。 BDD 使用称为 Gherkin 的自然语言分析器来帮助技术团队和非技术团队定义业务规则和要求。 可以将 SpecFlow 或 Cucumber 与 Selenium 结合使用来生成 UI 测试。

Andy 看着 Amita。

Andy:我知道这些选项对你来说都是新的,那么你介意我们选择 Selenium 吗? 我有一些相关经验,并且它支持我熟悉的语言。 Selenium 还将为我们提供对多种浏览器的自动支持。

Amita:当然可以。 我们中有人具有一些经验是最好的。

如何在管道中运行功能测试?

在 Azure Pipelines 中,运行功能测试的方式与运行任何其他进程或测试的方式相同。 问问你自己:

  • 测试将在哪个阶段运行?
  • 测试将在什么系统上运行? 它们将在代理上运行,还是在托管应用程序的基础结构上运行?

让我们加入团队,因为他们回答了这些问题。

Mara:我很高兴的一点是,现在我们可以在实际运行着应用的类似于生产环境的环境中进行测试。 在这种情况下,诸如 UI 测试之类的功能测试是有意义的。 我们可以在管道的“测试”阶段运行它们。

Amita:我同意。 如果在运行手动测试的同一阶段运行自动 UI 测试,则可以维护相同的工作流。 自动测试将为我们节省时间,并使我能够专注于可用性。

Tim:Amita 用她的 Windows 笔记本电脑测试了该网站,因为这是我们大多数用户访问该网站的方式。 但我们是在 Linux 上构建,然后部署 Linux 上的 Azure 应用服务。 我们该如何处理?

Mara:很好的问题。 我们还可以选择运行测试的位置。 我们可以在以下位置运行它们:

  • 在代理上:Microsoft 代理或我们托管的代理
  • 在测试基础结构上:本地或云中

现有“测试”阶段包含一个作业。 该作业从 Linux 代理将网站部署到应用服务。 我们可以添加第二个作业,从 Windows 代理运行 UI 测试。 Microsoft 托管的 Windows 代理已设置好,可运行 Selenium 测试。

Andy:同样,让我们沿用我们所了解的。 让我们使用 Microsoft 托管的 Windows 代理。 之后,如果需要其他测试范围,我们可以从运行 macOS 和 Linux 的代理运行相同的测试。

计划

Mara:好的。 下面是我们将要执行的步骤:

  • 从 Microsoft 托管的 Windows 代理运行 Selenium UI 测试
  • 在“测试”阶段,让测试从应用服务上运行的应用中提取 Web 内容
  • 对我们支持的所有浏览器运行测试

Andy:我将与 Amita 合作此过程。 Amita,明天早上见。 在见面之前,我需要稍作研究。

Amita:太棒了! 回头见。

创建功能测试计划

我们看到了团队决定如何实施他们的第一个功能测试。 如果你的团队刚刚开始将功能测试合并到其管道中(或者即使已经在这样做了),请记住你始终需要一个计划。

很多时候,当有人向团队成员询问他们的性能测试计划时,他们通常会用要使用的工具列表进行回答。 但是,工具列表不是计划。 你还必须确定如何配置测试环境。 需要确定要使用的流程,以及确定怎样算成功、怎样算失败。

请确保你的计划:

  • 考虑到公司的期望。
  • 考虑到目标用户的期望。
  • 定义将使用的指标。
  • 定义将使用的 KPI。

从一开始,性能测试就应该成为你计划的一部分。 如果使用的是故事板或看板面板,则可以考虑在其附近安排一个区域,以便在其中规划测试策略。 作为迭代计划的一部分,应突出显示测试策略中的差距。 同样重要的一点是,应确定在部署应用程序后如何监视性能,而不只是在发布应用程序之前衡量其性能。

知识检查

1.

客户服务团队收到了过多的客户退款请求,这些客户不小心从你的移动应用程序中进行了购买。 客户报告“购买”按钮和“取消”按钮距离太近。 哪种功能测试可能有助于在用户遇到此类问题之前捕获问题?

2.

用户体验 (UX) 团队建议对网站主页进行一些重大更改。 你可以使用哪种功能测试来确保页面上的每个按钮都执行正确的功能?

3.

哪种功能测试通常是由人工执行,而不是通过自动化功能执行?