如何进行单元测试

时间:2013-10-22 09:49:24

标签: unit-testing

我有一个方法CreateTask(UserId)

对于这种方法,检查UserIdnull或空和无效值是否足够?

或者我应该检查是否为特定的Task创建了UserId

我是否还应该检查创建的任务数量及其日期和时间?

2 个答案:

答案 0 :(得分:1)

我认为这里没有足够的信息来回答这个问题。但是,我会解决你的一些观点:

  

对于这个方法,这是否足以检查UserId null或空和无效的Id?

方法本身可以在内部执行此操作,但这不是测试的一部分。这只是运行时执行某些错误检查的方法。这通常被称为“防御性编程”。

  

或者我应该检查是否为特定的UserId创建了任务。?

这是多云的地方。这就是你想要退一步看看大局的地方。确保您没有将单元测试与实现逻辑紧密耦合。测试应该验证业务逻辑,而不知道实现。

很可能“创建任务”不是业务逻辑,而是简单的实现细节。您应该测试的是,当执行步骤A时,会观察到结果B.系统如何生成结果B本质上是正在测试的,但不是直接或明确的。

保持单元测试高级别的一个重要原因是,如果实现细节发生变化,那么您不希望用它们更改测试。这大大降低了这些测试的价值,因为它不仅为任何更改增加了更多的工作,而且还将测试作为这些更改的验证点,因为测试本身也会发生变化。测试应该相当简单和静态,作为一组用于验证代码的规则。如果测试很复杂且经常发生变化,则会失去验证代码所需的置信水平。

您不必测试每种方法。您应该测试系统执行的每个可观察的业务操作。执行这些操作的方法由此得到测试。那些不执行这些操作的方法在一开始就是否需要它们是有问题的。代码覆盖工具非常适合确定这一点。

例如,假设您有MethodA(),任何测试都不会使用它。没有测试直接调用它,因为它只是一个实现细节,测试不需要知道它。 (在这种情况下,甚至可能将方法设置为私有或以其他方式隐藏在外部调用代码中。)这为您提供了两个选项:

  1. 测试不完整,因为未经测试的业务流程需要MethodA()。添加该业务流程的测试。
  2. 测试已完成,系统实际上并不需要MethodA()。删除它。
  3. 如果您的测试盲目地测试每个方法而不管业务逻辑的大局,您将永远无法确定系统何时不需要某些内容。弃用不再需要的代码是保持简单和可维护代码库的巨大部分。

答案 1 :(得分:0)

1)保持你的方法简短,所以单元测试很容易(顺便说一句TDD鼓励设计良好的原因之一)

2)检查所有边界条件(无效输入,无关紧要的输入等)(顺便说一句,使TDD容易的方法之一)

3)检查所有可能的场景以实现高覆盖率(通过最简单的输入实现此方法的所有可能的执行流程)(顺便说一句TDD工作的原因之一)

4)检查几个(可能是一个)典型情景,其中包含演示方法典型用法的实际数据

正如您可能已经注意到的那样 - 考虑使用TDD,这样您就不必担心“测试现有方法”的问题了:)