5

我的每个单元测试应该检查多少?例如我有这个测试

[TestMethod]
public void IndexReturnsAView()
{
    IActivityRepository repository = GetPopulatedRepository();
    ActivityController activityController = GetActivityController(repository);
    ActionResult result = activityController.Index();
    Assert.IsInstanceOfType(result, typeof(ViewResult));
}

并且

[TestMethod]
public void IndexReturnsAViewWithAListOfActivitiesInModelData()
{
    IActivityRepository repository = GetPopulatedRepository();
    ActivityController activityController = GetActivityController(repository);
    ViewResult result = activityController.Index() as ViewResult;
    Assert.IsInstanceOfType(result.ViewData.Model, typeof(List<Activity>));
}

显然,如果第一个测试失败,那么第二个测试也会失败,那么这两个测试是否应该组合成一个带有两个断言的测试?我的感觉是,测试越细化,每次测试检查的越少,找到失败原因的速度就越快。但是,拥有大量非常小的测试会产生开销,这可能会花费时间来运行所有测试。

4

5 回答 5

12

我建议尽可能地分解它们。

这有很多原因,恕我直言,最重要的原因是:

  • 您的一项测试失败时,您希望能够尽可能快速且安全地准确找出问题所在。让每个测试方法只测试一件事是实现这一目标的最佳方式。

  • 每个测试都需要从一张白纸开始。如果您创建存储库一次,然后在 2 个或更多测试中使用它,那么您对这些测试的顺序有隐含的依赖关系。假设 Test1 将一个项目添加到存储库,但忘记删除它。Test2 的行为现在将有所不同,并可能导致您的测试失败。唯一的例外是不可变数据。

关于您的速度问题,我不会担心。对于像这样的纯代码处理,.NET非常快,您永远无法分辨出其中的区别。一旦您摆脱代码处理并进入数据库之类的事物,您就会感受到性能问题,但是一旦您这样做,您就会遇到如上所述的所有“白板”问题,所以您可能只是必须忍受它(或使尽可能多的数据不可变)。

祝您测试顺利。

于 2009-06-07T21:12:02.500 回答
3

越细粒度越好。当测试用例中的断言失败时,测试用例将不再运行。案件的后半部分可能会发现其他错误。

如果测试用例之间有共享代码,请使用 setup/teardown 函数来处理它,而不要过多地重复自己。时间成本通常可以忽略不计。如果设置/拆卸需要太多时间,您可能不是在进行单元测试,而是在进行一些更高级别的自动化测试。理想情况下,单元测试不应具有文件系统、网络、数据库等依赖项。

于 2009-06-07T21:12:35.570 回答
2

我认为“标准”的答案是,如果代码中存在错误,它应该打破一个测试,但不隐藏任何其他失败(不阻止其他测试运行)当这个失败时. 每个测试测试一件事,两个测试不测试同一件事。这是一个理想,并不总是可以实现。称之为指导。

话虽如此,这确实是一门艺术。我最初会抛开性能问题,而更多地关注可维护性。那里有两行半到三行重复。如果设计发生变化,那将很难维护。在这种情况下,重复本身可以通过类中的设置方法和文件来解决,但主要要担心的是可维护性。

测试应该足够小,以便可维护、易于理解,并且让其他人(或经过一段时间后的您)能够理解代码在做什么并能够维护测试。

于 2009-06-07T22:08:17.563 回答
0

单元测试应该从功能设计的角度准确测试您的技术设计中描述的内容。

于 2009-06-07T21:15:36.360 回答
0

测试测试量的方法绝对是您需要预先决定并坚持下去的事情。我不认为每个人都应该统一遵循相同的方法,因为不同的团队和/或项目在编码、性能、故障排除、测试基础设施等方面有不同的优先级。但保持一致总是有帮助的:

  1. 由于您事先知道要挖掘多深,因此可以更快地发现问题;
  2. 花更少的时间来构建你的测试;
  3. 在实现测试时使用相同的测试助手类集。
  4. 足够快地运行测试:不要太快也不要太慢。
  5. 组织测试(套件、包等)

如果您认为性能更重要,那么使用更多的验证/断言来实现更厚的测试。如果您认为故障排除是最重要的,那么尽可能多地隔离您的测试。我不明白为什么厚重且结构良好的测试是有缺陷的。这样的测试将完成与更薄测试相同的工作,而且效果也一样。

当然,每个测试仍然需要关注特定的功能/特性,但这不是这个线程的真正主题。

于 2009-07-20T16:16:36.153 回答