在传统的基于瀑布的项目中,发生在开发阶段末尾的端到端集成测试活动经常会遇到很多问题。在开发团队和测试团队之间,要么代码没有正确集成,要么期望不匹配,要么围绕着测试数据、环境和参与系统的可用性存在约束。这会导致大量的胃灼热,返工和错过分娩。在相当长的一段时间里,甚至在敏捷实践实际要求自动化测试之前,自动化测试已经被采用,特别是在需要最终集成或回归测试的地方。一个流行的自动化工具的例子是Quick Test Professional,更广为人知的是它的缩写QTP。但是在开发周期的后期仍然存在一些众所周知的挑战:
- 很难追踪缺陷的起源,因为现在很多代码都是建立在缺陷之上的。
- 缺陷可能从一个生命周期阶段传播到另一个阶段,增加了复杂性和移除的成本。
- 如果环境(代码+数据+配置)不相同,或者问题是偶发的,那么在较低的环境中可能很难模拟该缺陷。
- 环境可能不适合测试+缺陷修复+重新测试的漫长过程。在一些极端的情况下,项目团队共享构建测试环境的基础设施,一个项目可能会饥饿(并延迟),因为环境可能被另一个项目阻塞或保留,而另一个项目本身也可能延迟。这就产生了多米诺骨牌效应,通常会影响最终客户。
- 由于完成测试和缺陷修复的时间通常受到项目进度的限制,项目团队成员可能不得不做出短期决策,以提供战术修复或变通方案。通常情况下,这些战术决策会导致产生的软件中的技术债务。
- 缺陷通常只需要由编码的开发人员进行筛选、模拟、定位和修复,他或她可能在其他地方忙着。
- 尽管服务于同一个项目,开发和测试团队仍然可能在竖井中工作并相互竞争。
- 测试团队总是必须“赶上”维护自动化测试套件,否则它将变得非常脆弱和没有价值。
那些地方用到自动化测试
- 自动化红色路由,即模块或组件将被大量使用或遇到大量数据(例如,月底处理)。
- 自动化那些需要同时测试的(例如,同时模拟多个用户)。
- 自动化对业务非常关键、对故障容忍度低的场景或用例(例如,如果某个特定组件故障,整个应用程序将不可用,可能会造成财务影响)。
- 自动化“高接触”领域,这些领域需要重复编码和测试,通常使用相同的测试用例和相同的输入测试数据。
- 自动化需要在多个(几乎相似的)环境下进行测试的领域(例如,在多个浏览器上测试相同的UI,在不同手持设备上测试相同的UI,在Android、iOS等多个操作系统上测试移动应用)。
- 自动化非功能测试,这些测试通常处理大量数据(如持久性和性能测试)和长测试周期(如寿命测试)。
- 如果可以收集到信息,自动化预期有较长的货架期的区域。
- 自动化创建、使用和销毁使用虚拟化环境或云的测试环境。
自动化测试等级
- 单元测试(Unit testing):这是最基础级别,大多数测试用例应该驻留在这里,并作为其他测试用例的基础。开发人员可以使用诸如Junit(针对Java)和Nunit(针对C#和net)这样的框架来编写自动化的单元测试用例。自动化单元测试对开发人员很有吸引力,因为它们是用相同的编程语言编写的,而且几乎可以精确地指出代码中缺陷的位置。通常,这些单元测试可以与构建代理集成,这样每当代码被检入时,自动构建就会被触发,并且在编译和生成运行时可执行文件之后,这些测试用例就会自动执行。如果测试用例失败(例如,junit中的assert语句失败),开发人员就会得到通知。
- 中间层测试(Middle tier testing):开发人员可以使用Cucumber和fitness这样的工具测试业务逻辑和中间层代码,比如组件、web服务(就像面向服务的体系结构)
- 前端或用户界面测试(Front end or user interface testing):这应该是最难的实现自动化(不鼓励做自动化测试,尤其是在项目早期),随着用户界面还不断的变化保持更新UI自动化测试套件测试,对于团队是一个相当大的挑战,无论使用什么工具。开发人员可以使用工具记录和回放用户与UI的交互。测试脚本与唯一可识别的用户界面元素绑定,并且能够采取像数据输入、按钮点击、滚动等操作,就像一个真正的用户一样。正在使用的流行工具包括Jasmine、7Selenium、Loadrunner和JMeter。
- 回归测试(Regression testing):回归测试套件的目的是确保不仅当前迭代工作中添加的功能,而且现有的功能也能按照预期继续发挥作用。请注意,编程的某些方面(如数据库测试)不能有效地回归,并且没有足够的工具进行回归。因此,如果不是100%,那么我们应该尽可能地使回归测试自动化。回归测试中的人工干预越少,迭代的开销就越少。