我目前正在为 ASP.NET MVC 2 网站编写 Selenium 2 WebDriver 测试(这些测试是用 C# 编写的,并以 NUnit 作为测试运行程序运行)。我熟悉单元测试(并且也为这个项目编写了单元测试)。因此,我知道每个单元测试都应该是自包含的(应该让系统保持与它开始时相同的状态,无论它是通过还是失败)和独立的(测试的顺序应该无关紧要,并且可以运行测试一次一个或作为一个完整的套件没有得到不同的结果)。
我也一直在尝试用我的 UI 回归测试来做到这一点,但我遇到了这样的情况,这样做似乎我在重复自己做很多事情。例如,在测试称为产品的东西的 CRUD 时。独立的测试会是这样的(这里只列出步骤,而不是代码):
测试登录:
- 设置:无。
- 测试:导航到登录页面,输入登录信息,点击提交,验证登录并重定向成功。
- 拆除:注销。
测试创建:
- 设置:执行登录测试中的逻辑。
- 测试:导航到创建产品页面,填写表单值,提交,验证产品已创建并且重定向成功。
- 拆除:删除产品,注销。
测试更新:
- 设置:执行登录测试中的逻辑和创建测试中的逻辑。
- 测试:导航到编辑产品页面,更改一些值,提交,验证更新是否成功。
- 拆除:删除产品,注销。
同样用于测试删除、注销等。
如您所见,测试之间有很多重复 - 作为一个测试的“测试”部分完成的操作在其他测试的设置或拆除中重复。如果 CRUD 测试总是一起运行而不是让每个测试独立运行,这将大大减少重复 - 首先是登录测试,然后是创建、更新、删除,最后是注销测试。然而,这显然违背了单元测试的核心。
鉴于有多少网站具有基本的 CRUD 操作,我想这种情况一定会出现在很多开发人员身上。所以我的问题是:在这种情况下最佳做法是什么?拥有一堆独立测试是否更好,它们在设置/拆卸代码中不同程度地相互重叠?或者,在自动化 UI 测试/回归测试的情况下,是否可以(甚至更可取)让测试相互依赖?或者作为第三种选择,是否应该将所有 CRUD 测试汇总到一个巨大的 CRUD 测试中?
还是有一些我不知道的方法总体上更好?我已经阅读过诸如 PageObjects 之类的东西,但除非我遗漏了什么,否则 PageObjects 实际上只是将常用操作重构为独立的方法/类(为了便于代码维护和 DRY 原则,我完全同意),但它们没有不要改变这样一个事实,即您仍然在设置和拆卸中一遍又一遍地调用相同的逻辑位,而不是登录一次,创建一个产品,更新一个产品,删除一个产品,然后注销一次。