1

我有一个 WCF 服务,它运行并与数据库、文件系统和一些外部 Web 服务交互,然后创建结果并对其进行 Xml 序列化并最终返回它。

我想为这个解决方案编写测试,我正在考虑如何(这一切都使用依赖注入和合同设计)。

我可以采取 3 种主要方法。

1)我可以选择最小的代码/方法单元并为其编写测试。选择一个类并将其与其依赖项(其他类等)隔离开来。虽然它保证了质量,但编写它们需要大量时间,而且速度很慢。

2)只使与外部系统的交互可模拟,并编写一些涵盖从发出请求到响应被序列化并返回的主要场景的测试。这将测试我的类之间的所有交互,但会模拟所有外部资源访问。

3) 我可以设置一个测试环境,在该环境中确实发生与外部 Web 服务的交互、发生文件访问、发生数据库访问等。然后从头到尾编写测试。这需要环境设置和对所有其他系统的依赖才能启动和运行。

关于#1,我认为将时间/金钱/精力投入到为我拥有的每一种方法或代码编写测试上是没有意义的。我的意思是这是浪费时间。

关于#3,由于它依赖于外部资源/系统,因此很难设置和运行。

#2,听起来对我来说是最好的选择。因为它将测试它应该测试的内容。只有我的系统及其所有类和模拟所有其他外部系统。

所以基本上,经过几年的单元测试经验后,我得出的结论是,编写单元测试是一种需要避免的浪费,相反,孤立的系统测试是最好的投资回报。

即使我要先编写测试(TDD)然后是生产代码,我认为仍然#2 是最好的。

您对此有何看法?您会为您的应用程序编写小型单元测试吗?您是否认为这是一种良好的做法和对时间/预算/精力的最佳利用?

4

3 回答 3

1

如果你想谈论质量,你应该拥有所有 3 个:

  1. 单元测试以确保您的代码按照您的想法执行,暴露任何边缘情况并帮助回归。您(开发人员)应该编写这样的测试。
  2. 集成测试以验证整个过程的正确性,组件之间是否正确通信等。同样,您作为开发人员编写此类测试。
  3. 在类生产环境中进行系统范围的测试(自然会有一些限制 - 您可能无法访问客户端数据库,但您应该在本地机器上拥有其精确副本)。这些测试通常由专门的测试人员编写(通常使用不同于应用程序代码的编程语言),但当然也可以由您编写。

第二种和第三种类型的测试(集成和系统)对于测试较小组件的边缘情况来说将是太多的努力。这就是你通常想要的单元测试。您需要集成,因为连接经过测试、验证和正确的模块可能会失败。当然,系统测试是您每天在开发过程中所做的事情,或者是指派人员(手动测试人员)来做这件事。

从列表中选择类型的测试可能会在某种程度上起作用,但远非完整的解决方案或质量软件。

于 2013-03-28T20:24:06.820 回答
1

所有 3 个都很重要,并且针对不同的测试类型,即单元/集成/系统类别的矩阵,每个类别都有正面和负面的测试。

对于代码覆盖率,单元测试将产生最高百分比,其次是集成,然后是系统。

您还需要考虑测试的目的是验证(将满足最终用户\客户的要求,即价值)还是验证(写入规范,即正确)。

总而言之,答案是“视情况而定”,我建议遵循 SEI CMMi 验证和确认模型(即测试),该模型从每个活动的目标(价值)开始,然后对该活动进行最终允许整体过程需要持续改进。通过这种方式,您将“什么”和“为什么”与“如何”隔离开来,并且您将能够针对您的给定环境(可以是生命支持系统或当天的推文,向您最喜欢的阿姨、应用程序)回答时间和价值类型的问题)。

于 2013-03-28T21:18:26.577 回答
0

摘要:#2(集成测试)似乎是最合乎逻辑的,但您应该毫不犹豫地使用各种测试来实现对最需要它的代码库的最佳覆盖。为对“一切”进行测试而拍摄并不是一个有价值的目标。

长版

有一种思想流派,开发人员坚信采用单元\集成\系统测试意味着努力测试每一个被测试的代码。它要么根本没有测试覆盖率,要么致力于测试“一切”。这种二元思维总是使采用任何类型的测试策略看起来都非常昂贵。

事实是,强制测试每一行代码\函数\模块与尽可能快地编写所有代码一样合理。这需要太多的时间和精力,而且大部分收益都很少。另一个事实是,您永远无法在一个重要的项目中实现真正的 100% 覆盖。

测试本身并不是目标。这是实现其他目标的一种手段:最终产品质量、可维护性、互操作性等,同时花费尽可能少的工作量。

考虑到这一点,退后一步并评估您的特定情况。为什么要“为此解决方案编写测试”?您对今天项目的整体质量不满意吗?你经历过高回归率吗?您是否不确定某些模块是如何工作的(更重要的是,它可能有什么错误)?无论您的确切目标是什么,您都应该能够选择具有特殊挑战的作品并将注意力集中在它们上。根据这些部分是什么,可以选择适当的测试方法。

如果您有一个特别棘手的函数或类,请考虑对它们进行单元测试。如果您面临具有多个难以理解的交互的复杂架构,请考虑编写集成测试来为您最棘手的场景建立一个干净的基线,并更好地了解问题的根源(您可能会清除一些错误)道路)。如果您的问题没有在更本地化的测试中得到解决,系统测试会有所帮助。

根据您为特定场景提供的信息,面向外部的单元测试\集成测试(#2)看起来最有希望。似乎您有很多外部依赖项,所以我猜这是大多数复杂性隐藏的地方。综合单元测试(#1)是#2的超集,所有额外的内部内容都带有可疑的价值。#3(完整系统测试)可能不允许您按照您的意愿测试外部边缘情况\错误条件。

于 2013-07-05T05:55:42.740 回答