我们应该单独测试实际做什么方法,或者它应该做什么?

时间:2017-06-27 13:37:00

标签: unit-testing

这个问题可能看起来有点奇怪,但我会解释它。

考虑以下事项: 我们有一个服务FirstNameValidator,我为其他开发人员创建了这个服务,因此他们有一致的方法来验证一个人的名字。我想测试它,但因为全套可能的输入是无限的(或非常大),我只测试几个案例:

Assert.IsTrue(FirstNameValidator.Validate("John"))
Assert.IsFalse(FirstNameValidator.Validate("$$123"))

我也有LastNameValidator,它有99%的相同,我也为它写了一个测试:

Assert.IsTrue(LastNameValidator.Validate("Doe"))
Assert.IsFalse(LastNameValidator.Validate("__%%"))

但后来出现了一个新的结构 - PersonName,它由名字和姓氏组成。我们也想验证它,所以我创建了一个PersonNameValidator。显然,为了可重用性,我只需要调用FirstNameValidator和LastNameValidator。一切都很好,直到我想为它写一个测试。

我应该测试什么?

FirstNameValidator.Validate实际上是用正确的参数调用的吗?

或者我需要创建一些案例并对其进行测试?

这实际上是个问题 - 我们应该测试预期会提供哪些服务?我们希望验证PersonName,它是如何做到的,我们实际上并不关心。因此,我们传递几个有效和无效的输入,并期望相应的返回值。

或者,也许,它实际上做了什么?就像它实际上只是调用其他验证器一样,所以测试(.net模拟框架允许它)。

2 个答案:

答案 0 :(得分:1)

单元测试应该是正常运行的代码单元的验收标准...... 他们应该测试代码应该不应该做什么,在撰写测试时,你经常会发现极端情况。

如果你重构代码,你经常需要重构测试......这应该被视为原始努力的一部分,并且应该让你的灵魂高兴,因为你已经使产品和过程得到了如此大的改进。

当然,如果这是一个具有外部(或内部,取决于公司文化)消费者的图书馆,您需要在完成之前考虑文档。

编辑:这些测试也相当薄弱,你应该对每个测试中的合法内容进行定义,并且实际测试包含和排除至少所有类别的glyphps ...他们仍然可以使用相关代码进行测试...即isValidUsername(name,allowsSpace)可以同时使用名字和全名,具体取决于是否允许使用空格。

答案 1 :(得分:0)

您提出的问题有点奇怪:您描述的两个选项都将测试函数的行为,但每种情况下的粒度级别不同。在一种情况下,您将根据功能用户可用的API测试行为。该功能是否以及如何借助其他功能/组件来实现其功能无关紧要。在第二种情况下,您将单独测试行为,包括功能与其依赖组件的交互方式。

一般来说,不可能说哪个更好-根据情况,每个选项可能都是最好的。通常,隔离一个软件通常需要更多的精力来实施测试,并使测试对于实现更改更加脆弱。这意味着,仅在有充分理由的情况下才应进行隔离。在讨论您的特定情况之前,我将介绍一些建议隔离的情况。

  • 使用原始的依赖组件(DOC),您可能无法测试所需的一切。假设您的代码在DOC返回错误代码的情况下进行了错误处理。但是,如果不能轻易使DOC返回错误代码,则很难测试错误处理。在这种情况下,如果您将DOC加倍,则可以使Double返回一个错误代码,从而也测试您的错误处理。
  • DOC可能具有不确定性或特定于系统的行为。一些示例是随机数生成器或日期和时间函数。如果这使测试功能变得困难,那么用双倍的DOC替换DOC就成为一个论点,因此您可以控制提供给函数的内容。
  • DOC可能需要非常复杂的设置。假设需要提供一个复杂的数据库或一些复杂的xml文档。一方面,这可能会使您的设置变得相当复杂,另一方面,如果DOC发生更改,您的测试将变得脆弱并且可能会中断(请考虑一下XML模式是否已更改...)。
  • DOC的建立或对DOC的调用非常耗时(想象从网络连接中读取数据,计算下一个国际象棋棋步,解决TSP,...)。或者,使用DOC会大大延长编译或链接时间。使用double可以大大缩短执行或构建时间,这越有趣,您执行/构建测试的频率就越高。
  • 您可能没有DOC的工作版本-DOC仍在开发中并且尚不可用。然后,仍然可以通过加倍开始测试。
  • DOC可能不成熟,因此使用您所测试的版本是不稳定的。在这种情况下,您可能会失去对测试结果的信任,并开始忽略失败的测试。
  • DOC本身可能还有其他依赖性,这些依赖性具有上述一些问题。

这些标准可以帮助您做出关于是否需要隔离的明智决定。考虑您的特定示例:您描述情况的方式给我的印象是上述标准均未满足。对于我来说,这将得出一个结论,即我不会将函数PersonNameValidator与它的DOC FirstNameValidatorLastNameValidator隔离开来。