我们是否必须为断言或异常编写单元测试?

Do we have to write unit-test for assertion or exception?

如本 post、Exception vs Assert? 中所述,异常用于 运行 时间错误条件,断言用于编码错误。

据我所知,单元测试用于验证函数的功能。除了我们已经知道结果的合法测试用例之外,我们是否还必须在单元测试中编写一些非法测试用例来测试断言是否发生或是否已抛出异常?

可以。当 "bad" 场景发生时,测试断言 and/or 异常是否发生是个好主意。

阅读更多内容:

  • Test a specific exception type is thrown AND the exception has the right properties
  • Exception handling for Unit Tests in c++

PS:一定要吗?嗯,这取决于你的项目。

问问自己:是异常还是断言代码?你为什么要写那个异常和断言?他们有功能!应该保护您的代码免受例如来自 "outside" 的意外数据。因此,如果您需要这种保护,则必须检查代码的功能。

如果您不检查代码会怎样: 也许您检查异常的范围是错误的,并且您在不期望的情况下抛出或者您没有抛出但您的执行现在以未定义的行为运行。

我的论点很简单:您编写代码,异常和断言就是代码。该代码做了一些有用的事情,因此您必须检查它。从逻辑的角度来看,断言和异常与 if/the/else 错误处理没有区别。要获得完整的调用树检查,您必须检查它。 c++ 具有特殊的语言功能并不意味着这会导致不检查使用此功能的那部分代码。

您还应该测试错误情况,以确保被测试的方法正确处理错误(例如,该方法是否真的抛出异常或它只是在压力下发生段错误?)。

如果您使用 gtest,则可以使用 EXPECT_THROWASSERT_THROW.

测试是否抛出了特定异常

您的问题无法笼统地回答。

完美的单元测试是不可能的,甚至 "very good" 单元测试也非常困难,只有在测试 "very good" 代码时才有可能。小心不要落入这个陷阱,全看你的素质要求了。

您是否在故障可能导致生命损失的情况下开发关键任务系统?加倍努力并尽可能多地进行测试。无论如何,任何改变都必须通过许多官僚步骤。否则适应您的要求。自动化测试的主要好处之一是简化重构,此时您可以更改(有时是显着)您的实现并仍然确保它在一定程度上有效。太多的测试和这把枪指向你,因为任何改变都需要在测试中进行大量改变,最终会阻碍你的进步。

像往常一样没有灵丹妙药