CRUD 操作的 Selenium 2 WebDriver 测试是否应该是自包含和独立的?

软件测试 硒2
2022-01-29 18:09:17

我目前正在为 ASP.NET MVC 2 网站编写 Selenium 2 WebDriver 测试(这些测试是用 C# 编写的,并以 NUnit 作为测试运行程序运行)。我熟悉单元测试(并且也为这个项目编写了单元测试)。因此,我知道每个单元测试都应该是自包含的(应该让系统保持与它开始时相同的状态,无论它是通过还是失败)和独立的(测试的顺序应该无关紧要,并且可以运行测试一次一个或作为一个完整的套件没有得到不同的结果)。

我也一直在尝试用我的 UI 回归测试来做到这一点,但我遇到了这样的情况,这样做似乎我在重复自己做很多事情。例如,在测试称为产品的东西的 CRUD 时。独立的测试会是这样的(这里只列出步骤,而不是代码):

测试登录:

  • 设置:无。
  • 测试:导航到登录页面,输入登录信息,点击提交,验证登录并重定向成功。
  • 拆除:注销。

测试创建:

  • 设置:执行登录测试中的逻辑。
  • 测试:导航到创建产品页面,填写表单值,提交,验证产品已创建并且重定向成功。
  • 拆除:删除产品,注销。

测试更新:

  • 设置:执行登录测试中的逻辑和创建测试中的逻辑。
  • 测试:导航到编辑产品页面,更改一些值,提交,验证更新是否成功。
  • 拆除:删除产品,注销。

同样用于测试删除、注销等。

如您所见,测试之间有很多重复 - 作为一个测试的“测试”部分完成的操作在其他测试的设置或拆除中重复。如果 CRUD 测试总是一起运行而不是让每个测试独立运行,这将大大减少重复 - 首先是登录测试,然后是创建、更新、删除,最后是注销测试。然而,这显然违背了单元测试的核心。

鉴于有多少网站具有基本的 CRUD 操作,我想这种情况一定会出现在很多开发人员身上。所以我的问题是:在这种情况下最佳做法是什么?拥有一堆独立测试是否更好,它们在设置/拆卸代码中不同程度地相互重叠?或者,在自动化 UI 测试/回归测试的情况下,是否可以(甚至更可取)让测试相互依赖?或者作为第三种选择,是否应该将所有 CRUD 测试汇总到一个巨大的 CRUD 测试中?

还是有一些我不知道的方法总体上更好?我已经阅读过诸如 PageObjects 之类的东西,但除非我遗漏了什么,否则 PageObjects 实际上只是将常用操作重构为独立的方法/类(为了便于代码维护和 DRY 原则,我完全同意),但它们没有不要改变这样一个事实,即您仍然在设置和拆卸中一遍又一遍地调用相同的逻辑位,而不是登录一次,创建一个产品,更新一个产品,删除一个产品,然后注销一次。

3个回答

Blobinator,欢迎来到 SQA。

就您的问题而言,将 UI 测试视为两个重叠的活动可能会有所帮助:交互(例如单击/键入)和验证(确认站点行为正确)。交互和验证重叠,因为除非站点行为正确,否则可能无法按您预期的方式进行交互。例如,如果单击第 1 页上的编辑按钮没有将您带到第 2 页,则您无法与第 2 页交互。尽管有重叠,但交互和验证也是不同的;例如,无论页面上的数据是否正确,导航按钮都可能做正确的事情。

你的测试应该是独立的,因为测试的成功或失败不应该取决于之前是否有其他测试。这并不意味着测试不会共享代码或共享通用工作流。如果您担心不必要的工作,您可以考虑对测试进行编码,以便测试可以选择是否验证特定步骤。听起来你可能已经在做一些事情了。

有支持广泛的端到端测试以及更狭窄的特定于操作的测试的论据。端到端测试更好地反映了您认为该软件将如何实际使用。狭义的测试更适合问题隔离。如果您是一名时间紧迫的开发人员,并且您有一个 QA 团队,并且您想在专注于狭窄测试和广泛测试之间进行选择,我建议您专注于狭窄测试并将广泛测试留给您的 QA 团队,因为无论如何他们都需要手动进行广泛的测试。

+1 对 user246 的回答。这是他已经概述的内容的补充。

其他一些需要记住的事情:您可以进行不是 UI 自动化的设置,因此如果您可以直接调用 rest API 或其他一些 API 来创建您的产品并节省时间和通过 UI 步骤,那就去做吧(当然,除非您正在测试 UI 的那部分)。我经常为这样的事情创建一个界面并实现 UI 和非 UI 版本,这样我就可以轻松地选择我想在测试中执行哪一个。

报告是将事情完全分解为单独测试的主要原因。如果您从失败中获得足够的信息以确切地知道测试失败的原因并能够可靠地报告它(在登录时获取上个月的所有失败),那么将测试串在一起可能对您来说是可以的,尽管我一般还是尽量避免。

我将我们所有的 CRUD 测试写到一个类中,分解成依赖的方法。我创建并断言记录存在,编辑记录并断言更改持续存在,编辑然后撤消并断言更改不存在,然后删除记录并断言它不再存在。

这使应用程序处于测试开始时的状态。正如您所说,它不是“单元测试”,但它最有意义,因此您不会运行相同的测试 4 次。