51testing论坛版主,专注于软件测试及测试吐槽,屌丝测试攻城师一枚。。。。。。。。。。。。。。。。。。。。。。。。。新浪微博:@没翅膀的飞鱼-------邮件交流:wzb_minitester@126.com------

制定一个有效的测试策略

上一篇 / 下一篇  2014-07-26 11:00:33 / 个人分类:测试管理

在近期的一个大型项目中,我们在初期就制定了目标,我们不想让很多的QA人员手动测试我们的软件。通过手工测试来发现漏洞是非常耗时的,成本也很昂贵, 尝试尽可能从软件内部着手构建高质量的产品。这并不是说,手工测试应经无用武之地, 手动测试常常能触发某些你无法预期到的软件使用行为。

这是一个18个月左右的长期项目, 后续还会有持续更新。先前我们就发现,一个好的测试策略对项目的成功是至关重要的,特别是让我们的团队能够:1)随着时间的推移持续提高我们的效率,2)有信心应对我们的应用程序的大大小小的变更。

为了建立一个有效的策略,我们花了相当长一段时间。这主要是因为我们不得不学习如何在应用程序的每一层来设计我们的应用程序的可测试性。我们的团队成员之前都有很丰富的TDD经验,但这并不是我们需要创建一个有效的测试策略的唯一技能。

测试的层次

为不同的测试分类是很麻烦的。你需要有功能测试、集成测试、单元测试、验收测试,缓慢测试,快速测试,界面测试,等等。我们发现我们的测试属于三个主要类别:

*系统测试

*皮下测试

*单元测试

每个测试所测的内容的视角都是不同的。一个完整系统测试通过外部接口测试应用程序,测试诸如浏览器,文件下拉菜单,队列,WinForms应用程序这类问题。

皮下测试工作直接针对用户界面以下的内容。在一个web应用程序的环境中, 我们的我们用例的其中一个皮下测试是在所有的真实的类和实现都部署到位的前提下,通过命令行处理器发送的表单对象。我们绕过仅仅包含界面逻辑的控制层,直接到领域层。发送表单对象后,就能获取成功/失败的测试结果。

最后,我们有单元测试。单元测试的目的是测试一个类,可以是快或慢的测试。快速测试是正常的TDD测试,用于构建类的设计。根据需要进行重复测试,但严格interaction-based测试没有多大价值,除非我们找到非常有趣的交互。我们也有缓慢的单元测试,也可以归类为集成测试。这些将是诸如库测试、持久性测试,等等。

不同类型测试的比例,单元测试:皮下测试:系统测试在10:2:1附近徘徊。我们完成的这个项目大约有5000个单元测试,1000个皮下的测试中和500完整系统测试,使用WatiN和Gallio来驱动一个浏览器。这6000个单元/皮下测试大约10分钟执行完毕,然而500个UI测试需要大约50分钟完成。

单元测试策略

单元测试是在一个相当严格的TDD方式。在任何设备投入使用之前,我们都会编写测试,并使用测试驱动代码的设计。这些测试帮助识别设计问题,封装问题,代码问题等等。

我们努力避免编写纯粹用于提供测试的代码。它们常常意味着我们有设计问题、责任错位或封装已被破坏。

当我们进一步深入到项目管道,我们开始越来越少使用交互测试。也仅仅是满足对此真正感兴趣的人的兴趣而已但更多的时候,我们更感兴趣的是它的副作用,而交互是一个实现细节而已。我们经常所做的反而是模拟缓慢或不可测试,如存储库,在外部服务facade,配置等。否则,我们模拟仅限于我们很感兴趣观察点。在大型项目中,它可以变得很明显,你的设计需要一个large-level重构,提取其中的概念使其更快实现交付功能。在我们最后的项目,一些概念发现包括:

§  AutoMapper

§  处理的形式作为单独的命令消息

§ Input builders

有了所有这些,单元测试实际上是重构的一个保障。但只有我们依赖这些测试来覆盖应用程序中所有有趣的行为时,才能起到保障的作用。为了有效地允许大型和中型的重构,我们需要额外的测试级别。

皮下测试策略

皮下测试,就像他们的名字所暗示的, 测试一切都只是用户界面的表面之下。在MVC应用程序中, 所有这些测试将只是控制器下的所有内容。对于一个web服务,一切都在端点。这个想法是,最上层的应用程序不执行任何实际的业务逻辑,而只是连接的外部接口与相关服务。

皮下测试的重要性体现在我们希望在绕开如用户界面和外部服务来测试业务逻辑的情况下单元测试只是聚焦在小规模设计上,皮下测试并没有关注设计, 而是将被测系统作为一个整体来关注输入和输出。

为了构建一个有效的皮下测试,我们可以试着通过共同的逻辑流构建统一的压力点。例如,我们可以构建一个命令消息处理系统,或者一个通用的查询接口。在最近的一个项目中,批处理文件中的每一行变成了一条消息。我们可以起草一个消息,通过系统发送,然后验证处理该消息的所有副作用。

由于皮下测试解决高层次的行为,而不是设计,他们非常适合基于场景的测试策略,如BDD或测试类夹具的模式。如果我们希望能够执行大的重构,我们需要这些高级测试创建wide-cast安全网的业务行为。皮下测试也是调用功能的大目标点,他们关注的更多是终端到终端的逻辑。

而皮下测试使我们能够安全地执行较大的重构,他们仍然不提供一个我们的系统将在生产中运行的令人满意的信心水平。


全面的系统测试策略

我们的团队最初称这些测试为“UI测试”,直到我们更多的项目和更多的整合策略。其中输入我们的系统的不是一个浏览器,而是消息,一个REST端点,或FTP下拉菜单,批文件的处理。UI测试是全系统测试的子集。一个完整的系统测试背后的想法是,我们想要测试我们的软件,因为它可能会用于生产。对于一个MVC应用程序,这些将是基于浏览器的测试。对于批处理文件,我们将使用实际的文件。REST中,是实际的HTTP请求。消息,是真正的队列和消息。

在产品上线前,如果我们想知道应用程序能否按照预期运行,一个有效和高效的方法是创建一个自动化的测试,测试完整的系统。如果我的基于UI的测试可以登录应用程序,并下订单,然后可以验证是否生成一个订单。我感觉是一件很不错的事情。


有关完整的系统测试中一个常见的误解是,他们是黑盒测试。他有自身的特点,全系统测试要求必须能了解系统内部发生了什么。实际上,全系统测试甚至可以采用领域模型来构建数据,而不是通过纯粹为了测试的系统后门来创建测试数据。团队中常犯的错误是,不按照与产品实际应用一直的路径来测试代码,导致系统处于奇怪的、失效的和无法处理的状态。


在我们的项目中,全系统测试时我们生成一个特性/用户故事完成之前所写的最后的代码。手工测试的成本太高,而且也无法可靠地验证一个特性已完成。但如果我可以通过外部接口来验证产品实际使用时的操作,这是成功的。


整体策略

对于一个待测系统,为了提高覆盖率,我们发现最有效的测试策略是从全系统测试开始,逐渐深入到单元测试。首先使用宽松的但是简单的断言,然后逐渐深入单元级别的逻辑。对于一个新的应用程序,我们倾向于不只是关注一个区域,对于一个长期维护的系统来说,所有的测试都是很重要的。

我们这种测试策略确实需要一定程度的投入。当知道这个应用程序对于客户的业务来说至关重要时,我们发现这种整体策略是非常有效的。如果应用程序是关键业务, 它定会发生变更,如果发生需求变更,我们最好能安全的实施变更,而不会影响我们的客户的业务。



【英文原文:http://lostechies.com/jimmybogard/2010/08/25/an-effective-testing-strategy/


TAG:

引用 删除 ladyjo   /   2014-08-01 18:18:45
5
 

评分:0

我来说两句

Open Toolbar