公平地说,设计良好的单元测试不需要高代码覆盖率和高性能吗?

时间:2009-06-15 19:38:00

标签: unit-testing

在设计单元测试时,从我的阅读中你应该尝试坚持这些原则:

  • 将测试彼此隔离
  • 一次只测试一个行为
  • 确保测试可重复

另一方面,这些功能似乎并不总是与良好的测试相关:

  • 高代码覆盖率
  • 高性能

这是一种公平的方法吗?

9 个答案:

答案 0 :(得分:1)

性能通常不是单元测试的关注点。高代码覆盖率。您编写单独的测试来狭窄地测试单个函数。你编写了足够的(窄)单元测试来覆盖你的大部分功能。

答案 1 :(得分:1)

我会说单个单元测试很可能不会涵盖大部分代码,因为这会破坏目的,所以是的,我同意你的第一点。

现在,至于高性能,我认为这不是“必需品”,但是,在开发具有数百个测试的系统时,您希望尽可能高效地执行它们,以便您可以快速执行测试。

答案 2 :(得分:1)

高代码覆盖率更能说明您对代码库进行了多大程度的测试,例如,如果您已经测试了系统中可能的所有代码路径等。它们没有说明单个测试的质量,但是一个衡量单位测试整体质量的指标。

至于高性能,您需要对测试进行分类,分离出触及数据库或其他高延迟服务的测试。将性能测试也保持在单独的类别中。还要确保密切关注集成(或端到端测试),例如打开Web浏览器的测试,发布然后验证响应。如果这样做,您实际上不必担心测试的性能。

答案 3 :(得分:1)

覆盖范围不是单个测试的(有意义的)属性。正如您所说,一个测试应该只涵盖一个行为。性能虽然(通常)只是总体而言非常重要,但非常重要,这就是原因。

我们出于很多原因进行测试。编写和运行它们的障碍越少,我们将拥有的测试越多 - 我们的代码覆盖率就越高。如果我们不运行测试,因为它太麻烦 - 我们不运行测试;我们没有发现我们的错误;我们的生产力受损。所以它们应该是自动化的(零麻烦)。如果我们不进行测试,因为它需要时间来编码 - 或者因为他们花费时间分散我们的注意力,我们集中注意力:我们不进行测试;我们没有发现我们的错误;我们的生产力受损。所以他们应该足够快,运行它们不会分散注意力。如果我们的测试对文件系统或数据库造成太大影响,那么会减慢它们的速度,我们会更少地运行它们。所以避免这样做;抽象的慢点。经常测试。测试批次。如果它们很慢,你就不会。所以保持他们的速度。

答案 4 :(得分:1)

每个单元测试应该专注于测试单个行为,因此理想情况下,单个测试的代码覆盖率应该非常小。然后当你有成百上千次这样非常集中的测试时,他们的总覆盖率应该很高。

表现既不是也不重要。

在不应该进行微观优化的意义上,性能并不重要。首先,您应该专注于测试的可读性。例如,“清洁代码”一书中有一个测试示例,用于验证温度警报的状态。最初每个测试都有五个断言检查布尔值,例如assertTrue(hw.heaterState()),但断言然后被重构为一个字符串比较assertEquals("HBchL", hw.getState()),其中大写表示启用,小写表示禁用。后一个代码的性能较低,因为创建了一些额外的字符串并进行了比较,但它的可读性要好得多,因此测试代码更好。

性能很重要,因为运行所有单元测试应该是快速的,每秒数百或数千次测试(我平均每次测试不到1毫秒)。您应该能够在几秒钟内完成所有单元测试。如果测试需要很长时间才能完成,那么在进行一些小改动之后你就会犹豫不决,而只是在去喝更多咖啡时才运行它们,那么它们需要花费很长时间。如果测试套件很慢,您应该打破并模拟对其他组件的依赖关系,以便测试中的系统尽可能小。特别是,单元测试不应该使用数据库,因为这会使它们无可救药地变慢。

除了单元测试之外,还需要集成/验收测试来测试整个系统。它们在开发中作为单元测试具有不同的作用,因此接受测试套件可以接受缓慢(没有双关语)。它们应该每天至少一次由持续集成服务器运行。

答案 5 :(得分:0)

重新阅读问题时:

关于第一点,单元测试套件应该具有高代码覆盖率,但不一定关注性能。就其涵盖的代码量而言,单个单元测试应该相当小。一个细胞不会覆盖你的身体,但如果你想要一个细胞,那么它们中的一组形成覆盖人体大部分的皮肤将是一个生物学隐喻。

答案 6 :(得分:0)

是的,我认为这样说是公平的。您可以通过创建许多不同的测试来获得高代码覆盖率。

答案 7 :(得分:0)

表演与表现覆盖率是整个测试套件的目标。每个单独的测试不应该试图“抓住”尽可能多的覆盖范围,也不应该关注性能。

我们确实希望整个测试套件能够在合理的时间内运行,并且应该涵盖大部分代码功能,但不能以编写“ba”单元测试为代价。

答案 8 :(得分:0)

高代码覆盖率 对于单个单元测试,它不必覆盖100%的测试方法或方法。最终,单元测试套件需要覆盖尽可能多的测试方法或方法,因为您认为重要。可能是1%,可能是100%,并且它可能与代码的不同部分不同。

我通常会尝试70%-80%的覆盖率,然后更多地关注覆盖率而不是实际值。

高效: 比单个单元测试的速度更重要的是运行套件中所有测试所需的时间。如果花费的时间太长,开发人员可能会决定不经常运行它们。但是你经常无法花费大量时间进行优化,特别是在单元测试方面。您需要整个套件运行得足够快。

对于我正在进行数百次单元测试的系统,并且仍然在2分钟内运行,这种情况并不少见。一个非常慢的测试,或者一堆稍慢的测试,可以真正减慢构建测试重构周期。