单元测试如何提高生产力?

时间:2009-08-12 06:46:00

标签: unit-testing

我目前正在寻找提高团队效率的方法。我已经在很多地方读过,可以使用单元测试来提高生产率。我可以想象,现在编写单元测试在将来会有所帮助,但它在短期内也有帮助吗?因为我不明白如何编写更多代码(=更多潜在的错误)可以帮助我们满足最后期限。

15 个答案:

答案 0 :(得分:14)

单元测试不是每天产生更多代码行。

确保每天都有新的代码行不会导致更多错误。

当您尝试评估“生产力”时,您需要非常小心。然而,它可能会帮助您满足最后期限,因为您将花费更少的时间来修复内容。

这不是针对“短期”的目标,因为“我们将使用单元测试,我们的下一个项目将在80%的时间内完成”。

答案 1 :(得分:7)

不是一词,但不是一词,通过自动化测试可以让您检测错误导致的问题(回归) - 修正或错误发展,更快;这绝对是件好事。

这意味着当您的应用程序处于测试阶段时,每次更正错误时,您引入新错误的风险就会降低。
只要应用程序仍在开发中,这也是正确的:每次开发人员提交一个新模块时,你知道它不会破坏应用程序的其余部分(或者,至少,它不会破坏自动化测试所涵盖的内容)

越早检测到错误,修复越简单且成本越低:如果错误没有时间影响其他开发人员,那么它也会更好。
如果开发人员认为某些“bug”(他不知道是一个bug)作为一个功能并开始依赖它,该怎么办?当这开始被视为一个错误并被修复时会发生什么?我想其他代码断了: - (


好的一点是,开发自动化测试可能意味着更多的开发人员更多地了解应用程序的代码:特别是如果某些测试由其他开发人员开发/审查,而不是首先编写代码的开发人员。
不确定它是“好的实践”,但如果以这种方式完成,则意味着将会进行某种代码审查 - 这些确实很有帮助。

随着越来越多的开发人员了解代码,更多的开发人员将能够修复他们最初没有开发的部分中的错误。

答案 2 :(得分:6)

Increasing productivity with unit testing

另请阅读Test Driven Development

  

测试驱动开发(TDD)是一个   软件开发技术   使用简短的开发迭代   基于预先编写的测试用例   定义所需的改进或新的   功能。每次迭代都会产生   通过它所需的代码   迭代的测试。最后,   程序员或团队重构代码   适应变化。一个关键的TDD   概念是之前准备测试   编码有助于快速反馈   变化。注意测试驱动   开发是一种软件设计   方法,而不仅仅是一种方法   测试

答案 3 :(得分:5)

“测试”是单元测试的错误单词。 “定义行为”可能是一个更好的术语。

单元测试和TDD可以通过多种方式提高生产率(甚至是中期)。

  • 具有明确定义的行为的代码更容易调试,因为预期的行为是已知的。
  • 使用TDD方法编写的代码往往具有更清晰的“接缝”,允许独立验证代码库的各个部分。这样可以更容易在问题发生时缩小范围。
  • 由于强大的测试套件和定义明确的行为,重构变得更加容易。这样可以以更低的风险解决设计问题,即使它们影响了许多个别类别。
  • 由于上述原因,一旦出现问题,通常更容易确定修复的正确位置。
  • 由于TDD编写的代码往往不依赖于单例/静态行为或全局状态,因此存在较少的全局行为。通过减少全局行为,您可以减少副作用。

根据我的经验,TDD编写代码的最大优势在于它定义良好。首先定义代码应该执行的操作,然后再进行操作。这与“常规”开发实践形成对比,后者通常涉及编写一堆代码,然后对其进行测试以查看其实际功能。

使用类似TDD的方法的另一个好处是,即使端到端解决方案不到位,您几乎可以立即获得工作代码。并且几乎总是更容易添加到工作代码以获得更多工作代码,而不是编写一堆处于未知状态的代码,然后找出哪些代码无法正常工作。

答案 4 :(得分:4)

虽然严重过度紧张,但越早发现错误就越便宜。因此,单元测试至少会预先捕获一些错误。

我怀疑在生产力方面,这是一个问题,是否更容易修复程序员心中新鲜的代码中的错误,而不是几个月前的代码中的错误等等。但是,它有点理想主义者认为单位测试(在更大的测试制度之外)是某种形式的银弹。

答案 5 :(得分:3)

如果没有单元测试,你将如何进行测试?通过点击,可视地检查答案?是编写代码一次并运行它多次成本还是节省?

你是否会运用各种错误条件?如果不及时修复错误的相对成本,你可能会在以后找到错误吗?

然而对我来说,最重要的原因是一个不那么明显的原因:如果你先写测试(真正的TDD),或者甚至在你去的时候你几乎都会考虑边缘情况。结果是代码更好。减少返工。

另一种理论认为,人类非常注重目标。我们喜欢奖励,并重复行为,给予我们奖励(mmm声誉mmmm ...给我一个问题来回答:-)看到那些小绿蜱我们的测试通过激励我们。您可能会获得更多代码,但编写得更快。

答案 6 :(得分:2)

  

我现在可以想象编写单元测试   可以在将来有所帮助,但确实如此   它在短期内也有帮助吗?

是的,因为你强迫你的开发人员和架构师一次解决一个问题。

  

因为我不懂写作方式   更多代码(=更多潜在的错误)可以   帮助我们完成最后期限。

额外代码的数量完全相同。 n行逻辑= n行测试。但是正如您所知,原始编码不是花费更多时间的部分,特别是因为您可以非常好地并行化它。因此,编写更多代码并不是真正的问题。为了满足最后期限,您必须生成要发布的 top 质量代码,并且无需测试即可

  1. 无法知道质量是否最高。
  2. 无法测量何时可以进行释放。 (当所有测试都作为第一个必要条件通过时)

答案 7 :(得分:2)

以下是一些想法。对于我的回答,我将生产率定义为行数除以错误数量。如果应用得很好,平均而言,我认为单元测试会提高生产率。

  1. Stuart Halloway使用双重分类账会计的比喻:测试代码可能看似多余,但拥有其他分类帐对于获得质量感是一个巨大的回报。

  2. 通过单元测试,开发人员(或程序员)是该软件的第一个客户端。正如其他人所指出的那样,这就是为什么发现错误的原因。但是,此人也是OO模型,API等的第一个客户。如果涉及高级开发人员(做工作或成对),从设计角度来看质量将会提高。这具有中长期效益。 (这经常被忽视。)

  3. 良好的单元测试将揭露并运用角落案例。可能无法通过开发人员手动运行的vanilla测试来访问这些情况。如果您考虑在该领域发现的错误:有多少是由于一些奇怪的情况?根据我的经验,很多

  4. 确实,在错误的手中,单元测试可以感觉到轮子在沙子中旋转。但凭借一些经验,即使在短期内,这种回报也是值得的。是的,可能会有更少的生产代码,但错误率会更好。

答案 8 :(得分:1)

当您专注于在编写实际代码之后或之后编写测试时,您将无法编写太大的块。当你有很多小测试时,你很可能构建你的代码,这样你就可以编写这些小测试。

这意味着这些类不需要很多基础设施来运行等。依赖注入之类的东西也派上用场,因为你可能想为你的测试注入模拟类。这导致更松散耦合的类,这将提高整体代码质量并使代码更易于维护。此外,单元测试的安全网将在软件发展过程中为您提供帮助(而且不仅仅是在产品准备好之后)。

虽然编码大多数(也就是所有)人都会产生错误。这导致小功能的更长时间的发展。如果你编写测试,错误的可能性会降低,如果你发现了一个错误,你可以确定你的错误修复不会产生副作用(如果你对“其他”代码的测试覆盖率很好)。这样可以节省大量时间,因为您不必搜索可能受上次更改影响的代码。毕竟,这会带来更高的开发速度。

当然,开发人员需要练习编写测试,但很快就会更快。特别是如果你习惯了libs来帮助你编写像easymock这样的测试。

答案 9 :(得分:1)

短期内我认为单元测试没有那么大帮助,因为它只会减少一些测试时间。项目越小,其影响就越小。

然而,单元测试的好处在于,通过编写它们,您可以确保始终检测到您编码的特定类型的错误。从长远来看,它们是必须的,中期我会推荐它们。

从短期来看,它们可能会降低生产力,但如果项目本身不是短期的,那么你一定会从中受益。

答案 10 :(得分:1)

如果您在短期内意味着一两个月,我认为答案是肯定的。怎么样?当我需要对我自己的代码进行更改时,可能只需要几周时间,或者编写团队中其他人编写的代码,如果有单元测试并且代码覆盖率是好。如果没有测试我会更倾向于修补,解决方案并且通常避免触及主算法。做了几次,代码变得难以理解。

  

场景:项目会议

     

产品所有者:“我们需要制作一个   更改为X并添加Y功能。是   它可行吗?“。

     

团队:“等待会更好   乔回来了。他写了那段代码。“

     

几个星期后..

     乔:“当然,可以做到但是   考虑所有的测试   进入那个模块并不是一件容易的事   修复”。

     

产品所有者:“哦。所以..让我们推迟改变......”

我不确定我是否在回答你的问题。这实际上取决于短期有多短。 ; - )

答案 11 :(得分:1)

单元测试从以下意义上提高了短期生产力:它使您的代码更有可能更早地解决正确的问题。在创建测试时花费神经元周期将使程序员考虑不同的用例和该代码的用户界面(或API)。

相反的情况是代码离开几周,然后才意识到代码解决了一半的问题。现在你必须修补你的代码,或者甚至把它扔掉并重新开始。

答案 12 :(得分:1)

单元测试如何提高生产力?

这个问题的隐含假设是单元测试确实提高了“生产力”。 如果我们将生产率定义为在工时为特定工作量生成完美的可交付成果,那么提高生产率可以被解释为以低于给定的努力产生可交付成果。 如果编码员直接生成“完美”代码,那么进行单元测试会降低生产率。

测试不是主要用于提高生产力,而是用于验证和验证软件实体,因为您正在检查正确的产品是否构建以及正确构建了正确的产品。创建测试并运行它们确实有副作用,最重要的是让软件创建者理解他们试图用软件解决的问题。

答案 13 :(得分:1)

现代单元测试不是为了捕获错误 - 而是关于设计和记录接口。编写测试可以帮助您思考代码的使用方式,并记录它们的使用方式。

单元测试可以捕获重构时引入的错误,但这通常不是项目错误的主要来源。

总而言之,单元测试将使创建质量更好的代码更容易(即更便宜/更快)。但它不会直接帮助您更快地完成任务。

阅读有关单元测试的神话和好处的文章:

答案 14 :(得分:1)

很容易理解为什么最初可能会因单元测试提高生产率而感到困惑。大多数人提出单元测试的方式,自然的反应似乎是"你告诉我做更多的工作会让我更有成效吗?如何?" 。这真的来自这样一个事实,即大多数人对单元测试存在根本性的误解。当您正确地构建单元测试的概念时,生产力的好处变得显而易见。因此,为了实现正确的框架,请备份并讨论角色测试(不是单元类型,而只是验证程序功能的常规旧概念)作为软件开发反馈的来源。

我们都听过来自战斗强硬的高级开发人员的恐怖故事,他们谈到90年代一些被诅咒的名字曾经让整个公司离线一周,因为他们推动了改变生产而没有运行它。有人可能会说这里的问题是代码没有经过测试,但它肯定经过了测试;它是在最昂贵的测试人员:客户的最新可能阶段进行测试的。它并没有让大师认识到这种情况非常昂贵,并且通过在测试环境中而不是在生产中捕获问题可以节省大量成本。更好的是,如果解决问题意味着重做一个月的代码,你可以通过识别之前一个月的代码得到的代码来节省大量资金它。在接下来的几段中,我将尝试通过假设的情况来传达这个概念,但基本思想可以概括为较短的反馈周期比较长的反馈周期更有效。

大。我们确定了一个非常吸引人的口号,以确定我们的新管理策略。任务完成?嗯,不太好。我们需要定义我们的反馈实际上是什么,以实现我们的短反馈周期'。让我们想象一下,我们正在为一家贷款银行工作,而我们编写的代码就是为银行发行的各种贷款制定摊销时间表。这些摊销计划在任何地方都使用,而且它们是正确的非常重要。我们希望得到的反馈能够告诉我们,我们的代码是否为我们的贷款制定了正确的摊还时间表,而且首席执行官希望反馈不会以集体诉讼的形式提出。客户可以理解为多收利息而感到愤怒。所以不幸的是,在我们发布代码之前,我们必须想出一种方法来确定摊销计划是否正确。

我们可以试着说这是会计部门的用途。因此,我们编写了一堆我们认为应该工作的代码,并将其发送给审计员进行查看。他们发现了一堆问题,并将其发回。这似乎是公平的,因为期望像贷款软件这样复杂的东西首先尝试是不合理的。所以我们做了一些修改并将其发回。但它仍然不完美。这个周期一直持续到第5或第6次,当会计部门礼貌地通知你他们已经厌倦了你的错误代码,并且如果你发送一个更糟糕的工资总账可能会在下一个周期有一些较小的数字安排看看。

您可以获得一些样本贷款的电子表格及其正确的摊销时间表,通过该计划运行所有这些方案,并比较付款和分配,并确保一切都匹配。但是,贷款是一个复杂的领域;您可能需要测试40种不同的方案,其中一些贷款需要360次付款才能验证。运行所有这些方案需要很长时间。我们在过程的早期阶段尽可能地提供关于短反馈周期,迭代设计和捕获错误的所有这些好主意。我们也知道将问题分解成微小的步骤可以使它们更容易解决。我们知道重构使我们的代码更清晰,更易于使用,使未来的更改更快,更少痛苦。 但是,我们无法花时间在每次更改几行代码时验证所有场景。这是单元测试发挥作用的地方。< / p>

如果没有单元测试,我们必须做出妥协。我们要么花费大量时间来验证我们的代码在每次更改几行代码时实际工作,或者我们必须延长反馈周期。根据我们上面的公理原则,较长的反馈周期效率会降低。如果我们自动化我们对这些摊销计划的测试,那么这种妥协的任何一方都可以获得生产力增益。如果我们每次进行更改时都在逐字验证摊销计划,那么生产力效益就是直接的,并且来自消除所有验证时间。如果我们延长了我们的反馈周期,那么生产力效益就是间接的,并且来自于允许我们缩短反馈周期。

从这个意义上讲,单元测试只不过是一种生产力工具。人们经常引用单元测试的所有这些好处实际上是更短的反馈周期和这些周期产生的迭代设计的好处。单元测试只是使这些想法变得实用。您可以仅使用手动测试技术来实践短反馈循环和迭代设计。但是,执行所有手动验证所涉及的开销会使这种方法完全不切实际。当您将TDD视为重复运行程序的替代品时,看看您的更改是否符合您的预期,生产力提升真的开始变得有意义了。

我的观点也有一个有趣的推论,即实际来自较短的反馈周期带来的好处,而不是直接进行单元测试:完全有可能编写单元测试并输掉而不是获得从那以后的生产力。我曾在货物狂热编程商店工作,需要进行单元测试,但开发人员从未在实践中接受过适当的培训。在这些类型的商店中,有一些开发人员以老式的方式完成所有编码,一旦他们认为他们已经完成,他们就开始编写测试来覆盖&#39;他们写的代码。然后,一旦他们对他们的新测试进行了改造,他们就会推动他们的分支机构,因为他们没有运行任何现有的测试,因此无法进行CI构建。然后,他们继续花费数小时调试并重新编写一个分支,进行为期一周的更改以修复他们破坏的所有测试,并在事后处理新的测试代码。以这种方式发展的人正在编写单元测试,但对于他们而言,单元测试是一个额外的成本而不是生产力的好处,因为他们不会接受短的反馈周期。

<强> tldr;单元测试使得获得反馈的时间更少,因此您可以更频繁地进行反馈,并且更频繁地获得反馈意味着在返回绘图板期间减少工作量。时刻,复杂问题可以更容易地分解为更简单的问题,设计可以更自信地重构,以便更容易接受未来的变化。所有这些事情被广泛认为是更有效的软件开发方法,并且它们都是通过单元测试允许的短反馈周期来实现的!