【问题标题】:How Much Should Each Unit Test Test?每个单元测试应该测试多少?
【发布时间】:2009-06-07 21:05:52
【问题描述】:

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

[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>));
}

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

【问题讨论】:

    标签: unit-testing testing tdd testing-strategies


    【解决方案1】:

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

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

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

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

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

    祝您测试顺利。

    【讨论】:

    • 我确实打算写 slate,但 state 也是合适的。 “白手起家”是“白手起家”的俗语
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      p>

      【讨论】:

        【解决方案4】:

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

        【讨论】:

        • 在我看来,这是一个过于笼统的答案。可能有两个断言必须在两个测试中进行测试,有些可以一起测试。
        • 你怎么知道的?就在你的头顶?这是一个好方法吗?您通常对每个逻辑函数至少执行两个断言,一个接受良好的输入并测试良好的输出,另一个则放入垃圾输入并预期失败。但是,如果没有技术设计,您将不知道良好的输出应该是什么;如果没有功能设计,您将不知道应该注意哪些范围的垃圾输入。
        • 您对他的问题的回答是,“您应该准确地测试您的开发主管告诉您要测试的内容”,虽然这在某个层面上可能是正确的,但当问题请求反馈时,这完全没有帮助在一些特定的代码上
        • 实际上,您可以准确地测试您的功能是什么,该功能不是由首席开发人员描述的,而是由想要该应用程序的人描述的。
        【解决方案5】:

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

        1. 更快地发现问题,因为 你提前知道要挖多深;
        2. 花更少的时间在构建 你的测试;
        3. 使用同一套 的测试助手类,而 实施测试。
        4. 足够快地运行测试:不要太快也不要太慢。
        5. 组织测试(套件、包等)

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

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

        【讨论】:

          猜你喜欢
          • 2010-09-05
          • 1970-01-01
          • 1970-01-01
          • 2020-10-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-23
          • 1970-01-01
          相关资源
          最近更新 更多