我应该测试那些方法不会抛出exception吗?

我正在进行unit testing的第一步,并编写了(以及其他)这两种方法:

[TestCase] public void InsertionSortedSet_AddValues_NoException() { var test = new InsertionSortedSet(); test.Add(5); test.Add(2); test.Add(7); test.Add(4); test.Add(9); } [TestCase] public void InsertionSortedSet_AddValues_CorrectCount() { var test = new InsertionSortedSet(); test.Add(5); test.Add(2); test.Add(7); test.Add(4); test.Add(9); Assert.IsTrue(test.Count == 5); } 

真的需要NoException方法吗? 如果要抛出exception,它也将被抛出CorrectCount方法。

我倾向于将它保留为2个测试用例(可能将重复的代码重构为另一种方法),因为测试应该仅测试单个事物,但也许我的解释是错误的。

用最简单的话来说,IMO测试哪种方法不会做得很滑,因为你可以在想到它时提出越来越多的场景。 反过来说,断言你的代码完成你打算做的事情就是unit testing的目的。


有两个简单的问题,通常可以帮助我发现可疑的测试,并解决测试是否有任何意义:

  • 所需function的哪一部分是测试锻炼?
  • 我可以在测试类中进行哪些简单的更改来打破测试?

请注意,处理那些考虑了第二次测试( _CorrectCount )的问题非常容易 。 我们还没有真正看到Add方法代码,但我们很可能会产生不错的猜测,可以改变什么来打破这个测试。 经过测试的function更加明显。 答案很直观,看起来很快(这很好!)。

现在让我们尝试回答第一个测试的问题( _NoException )。 它立即提出了新的问题( 工作代码是一个实际的function吗?是不是很明显?这是不是暗示了?这不是我们一直在努力的目标吗?为什么最后没有断言?我怎么能让它失败? ? )。 对于第二个问题,情况更糟 – 打破那个测试可能需要明确地抛出exception……我们都同意这不是要走的路。

结论

很简单。 第二次测试是精心编写的单元测试的完美示例。 它很简单,只测试单一的东西,它很容易理解。 第一次测试不是 。 即使它简单而且(似乎是)简单,它引入了新的问题(虽然它真的应该回答已经说明的问题 – Add实际上是否Add ?是的。 ) – 结果带来了不必要的复杂性。

更有意义的是,制作一个方法来测试被测方法在您期望的时候抛出exception。 您所做的第一个测试没有声明第二个测试没有涵盖的行为。

我总是测试工作和非工作情况。 这样,您可以validation代码是否有效,返回正确的结果,以及以预期的方式处理错误。

Imo,如果你确定InsertionSortedSet列表工作(我不知道它来自哪里),我会跳过测试InsertionSortedSet_AddValues_NoException ,如果有必要的话。

当然,最好尽可能多地进行测试。

这里没有100%正确答案。

一方面你是对的,一个测试应该测试一件事。
在其中一个测试将来可能发生变化的情况下尤其如此,然后您将无法确定是否正在检查是否要通过其他测试。

另一方面,您正在创建冗余,因为两个测试实际上都检查了相同的事情。
只有在你的测试需要花费太多时间才能运行的情况下,这种冗余才会很糟糕,但是因为(看起来)你只有几个测试,这应该不是问题。

在第一次测试中没有断言或预期的exception,我认为应该重构。

IMO,一个测试应该检查不正确的行为(期望抛出错误),另一个测试应该检查正确的行为(没有exception,返回好的值)。