TDD测试应该有多精细?


18

在基于医疗软件案例的TDD培训期间,我们实现了以下故事:“当用户按下保存按钮时,系统应添加患者,添加设备并添加设备数据记录”。

最终的实现将如下所示:

if (_importDialog.Show() == ImportDialogResult.SaveButtonIsPressed)
{
   AddPatient();
   AddDevice();
   AddDeviceDataRecords();
}

我们有两种方法可以实现它:

  1. 调用了三个测试,每个测试都验证一个方法(AddPatient,AddDevice,AddDeviceDataRecords)
  2. 一种验证所有三种方法的测试称为

在第一种情况下,如果if子句条件发生错误,则所有三个测试均将失败。但是在第二种情况下,如果测试失败,我们不确定到底是什么错误。您会选择哪种方式。

Answers:


8

但是在第二种情况下,如果测试失败,我们不确定到底是什么错误。

我认为这很大程度上取决于测试产生的错误消息的质量。通常,有多种方法可以验证方法是否已被调用。例如,如果您使用模拟对象,它将为您提供精确的错误消息,描述在测试期间未调用哪个预期方法。如果您通过检测调用的效果来验证该方法已被调用,则由您决定是否产生描述性错误消息。

实际上,选项1和2之间的选择也取决于情况。如果看到您在旧项目中上面显示的代码,则选择案例2的实用方法,只是为了验证在满足条件时可以正确调用这三种方法。如果我现在正在开发这段代码,则最有可能在不同的时间点(彼此之间可能相隔数天或数月)一个接一个地添加这3个方法调用,因此我将添加一个新的单独的单元测试验证每个电话。

还要注意,无论哪种方式,您都应该有单独的单元测试,以验证每种方法都可以实现预期的功能。


您认为最终将这三个测试合而为一是否合理?
SiberianGuy

@Idsa是一个合理的决定,尽管在实践中我很少为这种重构而烦恼。再说一次,我正在处理优先级不同的旧代码:我们专注于增加现有代码的测试覆盖率,并使不断增长的单元测试数量可维护。
彼得Török

30

您的示例中的粒度似乎是单元测试和验收测试之间的差异。

单元测试将测试单个功能单元,并尽可能减少依赖项。在您的情况下,可能有4个单元测试

  • AddPatient是否添加患者(即调用相关的数据库功能)?
  • AddDevice添加设备吗?
  • AddDeviceDataRecords是否添加记录?
  • 在示例中执行unamend主函数调用AddPatient,AddDevice和AddDeviceFunctions

单元测试是针对开发人员的,因此他们可以放心,他们的代码在技术上是正确的

验收测试应该从用户的角度测试组合的功能。它们应该根据用户故事进行建模,并具有尽可能高的层次。因此,您不必检查是否调用了函数,而是可以查看对用户可见的好处:

当用户输入数据时,单击“确定”并...

  • ...转到患者列表,他应该会看到具有给定名称的新患者
  • ...转到设备列表,他应该看到一个新设备
  • ...转到新设备的详细信息,他应该看到新的数据记录

验收测试是针对客户的,或者是为了与客户建立更好的沟通。

要回答“您希望什么”的问题:什么是您现在面临的更大问题,错误和回归(=>更多的单元测试)或理解和形式化大局(=>更多的验收测试)


13

我们有两种方法可以实现它:

错了

调用了三个测试,每个测试都验证一个方法(AddPatient,AddDevice,AddDeviceDataRecords)

必须执行此操作以确保它可以工作。

一种验证所有三种方法的测试称为

必须执行此操作,以确保API正常运行。

该课程-作为一个单元-必须经过全面测试。每种方法。

您可以从涵盖所有三种方法的测试开始,但是并不能告诉您太多。

如果测试失败,我们不确定到底是什么错误。

正确。这就是测试所有方法的原因。

必须测试公共接口。由于该类执行三项加一项操作(即使由于用户故事而将它们捆绑在一个方法中),因此您必须测试所有四项。三个低级别和一个捆绑包。


2

我们为有意义的功能语句编写单元测试,这些语句多次映射到一个方法(如果您已经很好地编写了代码),但有时会变得更大,包含许多方法。

例如,假设将患者添加到系统中需要调用一些子例程(子函数):

  1. 验证患者资格
  2. 确保医生存在
  3. CheckInsuranceHistory
  4. 确保空床

我们可能还会为每个函数编写单元测试。


2

我一直遵循的一条简单的经验法则是为测试命名,以便准确描述测试的功能。如果测试名称过于复杂,则表明该测试可能做得太多。因此,例如命名测试以执行您在选项2中建议的操作,可能看起来像“耐心保存”,“保存时保存设备数据记录”,这比三个单独的测试要复杂得多。我还认为,可以从BDD中吸取的教训非常有趣,其中每个测试实际上代表了可以用自然语言描述的单个要求。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.