代码之家  ›  专栏  ›  技术社区  ›  darron

独立开发人员应该使用TDD的原因有哪些?

  •  35
  • darron  · 技术社区  · 17 年前

    我是一个有很多经验的合同程序员。我已经习惯了被客户雇佣去做一个软件项目,这种或那种形式是我自己做的,通常是从无到有。这意味着几乎每一次都是一笔勾销。我可以引入我为快速入门而开发的库,但它们总是可选的。(取决于合同中是否有正确的知识产权条款)很多时候,我可以指定甚至设计 硬件

    我可以看到为某些代码构建自动化测试的用途:库的功能不仅仅是琐碎的,核心功能有大量的引用,等等。基本上,当一段代码的价值通过大量使用而提升时,我可以看出,自动测试该代码将越来越有价值,这样我就知道我不会破坏它。

    然而 在我的情况下 ,我发现很难找到比这更合理的理由。我会采纳那些被证明有用的东西,但我不会盲目追随任何东西。

    我发现我在“维护”中所做的很多事情实际上都是一些小的设计变更。在这种情况下,测试不会为我保存任何东西,现在它们也必须更改。一种高度迭代、存根优先的设计方法对我来说非常有效。我看不出用更广泛的测试来节省自己那么多时间。

    爱好项目更难证明是合理的。。。它们通常是从周末到一个月的任何东西。Edge case bug很少有问题,这都是关于玩一些东西。

    阅读问题,如 this one ,投票最多的回答似乎是,根据该海报的经验/意见,如果你的人数少于5人,TDD实际上会浪费时间(即使假设TDD具有一定的能力/经验)。然而,这似乎涵盖了初始开发时间,而不是维护时间。目前还不清楚TDD在项目的整个生命周期中是如何累积的。

    我认为TDD可能是朝着提高整个行业产品质量这一值得追求的目标迈出的一大步。然而,理想主义本身在激励我方面已不再那么有效。

    我认为TDD在大型团队中是一种很好的方法,或者在任何规模的团队中至少包含一个不可靠的程序员。这不是我的问题。

    为什么一个拥有良好业绩记录的唯一开发者会采用TDD?

    如果做不到这一点,你个人经历的轶事也会很好

    请避免陈述没有经验支持的观点。让我们不要让这成为一场意识形态战争。还有“跳过更多就业选项”的论点。 这只是一个效率问题。

    20 回复  |  直到 9 年前
        1
  •  19
  •   Bill the Lizard    17 年前

    我不会盲目地追随任何事情。

    这是正确的态度。我一直在使用TDD,但我没有像某些人那样严格遵守它。

    我使用TDD的另一个原因是编写测试让我提前考虑API。在编写类之前,我不得不考虑如何使用它。让我的头脑进入这个高层次的项目对我来说很有用。还有其他方法可以做到这一点,如果你已经找到了其他方法(有很多)来做同样的事情,那么我会说继续做适合你的事情。

        2
  •  14
  •   Kilhoffer Guffa    17 年前

    我发现单飞时它更有用。由于周围没有人可以提出想法,也没有人可以执行同行评审,所以您需要确保自己的代码是可靠的。TDD/BDD将为您提供该保证。不过TDD有点矛盾。其他人可能完全不同意我说的话。

    编辑:我想补充一点,如果操作正确,您可以在编写测试的同时为您的软件生成规范。这是BDD的一个很大的副作用。如果你能自己编写出可靠的代码和规范,你可以让自己看起来像超级开发人员。

        3
  •  12
  •   Gishu    17 年前

    好的,轮到我了。。。我甚至会自己做TDD(对于非峰值/实验/原型代码),因为

    • 三思而后行 :迫使我在开始编写代码之前思考我想做什么。我想在这里完成什么……”如果我想我已经有了这首歌。。“我期望它如何工作?”对象设计中的接口。
    • :我可以自信地修改..'当我改变步骤5时,在步骤1-10中我没有破坏任何东西。“回归测试是即时的。”
    • 当前位置我发现,如果我不在设计活动中投入精力,就会出现更好的设计。测试优先+重构导致松散耦合、使用最少方法的最少类。。不要过度设计。。没有雅格尼代码。这些类具有更好的公共接口、较小的方法,并且可读性更强。这是一种禅宗的东西。。你只有在“得到”的时候才注意到你得到了它。
    • 调试器不再是我的拐杖 当前位置我知道我的程序做什么。。而不必花上几个小时逐行检查我自己的代码。现在如果我在调试器上花费超过10分钟。。精神警报开始响起。
    • 帮助我按时回家 我注意到,自TDD以来,我的代码中的bug数量显著减少。。即使断言类似于控制台跟踪,而不是xUnit类型。
    • :它帮助我确定下一个离散的婴儿步骤,这将带我走向完成。。。保持雪球滚动。TDD帮助我更快地进入节奏(或XPers所称的流程)。我在单位时间内完成了比以前更多的高质量工作。红绿重构周期变成。。。一种永动机。
    • 我可以证明我的代码是有效的 一按按钮
    • 熟能生巧

    如果我想到更多,我会更新的。。这是我在最后2分钟的反思中得出的结论。

        4
  •  6
  •   Ian Nelson    17 年前

    我也是一名合同程序员。这是我的 12 Reasons Why I Love Unit Tests

        5
  •  3
  •   Jay    17 年前

    我对TDD的最佳体验集中在 pyftpdlib

        6
  •  2
  •   azamsharp    17 年前

    不管你是否是唯一的开发者。你必须从应用的角度来考虑。所有的应用程序都需要正常工作,所有的应用程序都需要维护,所有的应用程序都需要减少bug。当然,在某些情况下,TDD方法可能不适合您。这是在最后期限即将到来,没有时间执行单元测试的时候。

    无论如何,TDD不依赖于个人或团队环境。它取决于整个应用程序。

        7
  •  2
  •   chessguy    17 年前

    我没有太多的经验,但我有过观察对比鲜明的测试方法的经验。

    在一项工作中,没有自动测试。“测试”包括在应用程序中四处翻找,尝试你头脑中突然出现的任何东西,看看它是否坏了。不用说,完全破译的代码很容易到达我们的生产服务器。

    在我目前的工作中,有很多自动化测试和完整的CI系统。现在,当代码被破坏时,这是显而易见的。不仅如此,在我工作的过程中,测试真正记录了哪些功能在我的代码中工作,哪些功能还没有工作。能够添加新功能给了我很大的信心,因为我知道,如果我破坏了现有的功能,它不会被忽视。

    因此,对我来说,这并不取决于团队的规模,而是取决于应用程序的规模。你能跟踪应用程序的每个部分吗?所有要求?为确保应用程序正常运行而需要运行的每个测试?如果您没有测试来证明,那么说应用程序正在“工作”意味着什么?

        8
  •  2
  •   tvanfosson    17 年前

    测试使您能够自信地重构,确信您没有破坏系统。首先编写测试允许测试定义系统的工作行为。根据定义,任何没有被测试定义的行为都是副产品,在重构时允许更改。首先编写测试也会推动设计朝着好的方向发展。为了支持可测试性,您发现需要解耦类,使用接口,并遵循良好的模式(例如,控制反转),以使代码易于测试。如果您在之后编写测试,则无法确保您已经在测试中涵盖了系统的所有预期行为。您还发现,由于设计的原因,有些东西很难测试——因为它很可能是在没有考虑测试的情况下开发的——并且很容易忽略测试。

    我通常是单独工作,主要是做TDD——我不这样做的情况只是我没有达到我的实践要求,或者还没有找到一种适合我做TDD的好方法,例如使用web界面。

        9
  •  1
  •   Korbin    17 年前

    TDD不是关于测试,而是关于编写代码。因此,它甚至为单个开发人员提供了很多好处。对于许多开发人员来说,编写更健壮的代码是一种思维转变。例如,在编写没有TDD的代码后,您多久会想到“现在这个代码怎么会失败?”?对于许多开发人员来说,这个问题的答案是没有。对于TDD实践者来说,它将思维方式转变为在使用对象或字符串之前检查对象或字符串是否为空,因为您编写的测试就是为了专门这样做(破坏代码)。

    另一个主要原因是变化。无论何时你与客户打交道,他们似乎都无法做出决定。唯一不变的是变化。TDD作为一个“安全网”有助于找到所有其他可能出现问题的领域。即使是在小项目上,这也可以防止您在调试程序中浪费宝贵的时间。

    我可以继续说下去,但我认为说TDD更多的是关于编写代码,而不是任何东西,这足以证明它作为唯一的开发人员使用的合理性。

        10
  •  1
  •   Ilya Kochetov    17 年前

    我倾向于同意你关于“一个开发人员”或“爱好”项目的TDD开销的观点的正确性,这不能证明费用是合理的。

    然而,你必须考虑到,最好的做法是相关的和有用的,如果他们始终如一地应用很长一段时间。

    例如,从长远来看,TDD为您节省了测试/错误修复时间,而不是在您创建第一个单元测试后的5分钟内。

    你是一名合同程序员,这意味着你将在当前项目完成后离开,转而从事其他工作,很可能是在另一家公司。您当前的客户必须维护和支持您的应用程序。如果你不给支持团队留下一个好的框架,他们就会陷入困境。TDD将有助于项目的可持续发展。它将提高代码库的稳定性,这样其他经验较少的人就不能在试图更改代码时造成太大的损害。

    这同样适用于爱好项目。你可能厌倦了它,想把它传给别人。你可能会在商业上取得成功(想想Craiglist),除了你之外还会有5个人在工作。

    对适当流程的投资总是有回报的,即使只是获得了经验。但大多数情况下,当你开始一个新项目时,你会感激地发现,你决定把它做好

    你必须考虑 当人们做某事时。你必须提前考虑,为未来做好计划 发育 持续性 .

    注:同样的情况也适用于其他实践:

    • 如果你不注释你的代码,并且你有理想的内存,你会很好,但是其他阅读你代码的人不会。

    无限期

        11
  •  1
  •   S.Lott    17 年前

    如果没有一组合理的单元测试,我不再重构任何东西。

    我不会先进行单元测试,然后进行代码测试,然后再进行TDD。我做一些计算——编码一点,测试一点——开发。通常,代码是第一位的,但并不总是这样。

    然后我意识到我忘了一些东西,我又回到了CALTAL开发公司,开发新的东西。

    然后我看到我忘了删除的东西——但它们是吗 真正地 到处都不用?删除它们,看看测试失败的地方。

    就在昨天,在一次大的重构过程中,我意识到我仍然没有完全正确的设计。但是测试仍然必须通过,所以在我完成第一次重构之前,我可以自由地重构我的重构。(唷!)这一切都很好,因为我有一组测试来验证所做的更改。

    因为单飞TDD是我的副驾驶。

        12
  •  1
  •   Craig Buchek    17 年前

        13
  •  0
  •   ZombieSheep    17 年前

    我将很快回答这个问题,希望你能开始明白其中的一些道理,即使你仍然不同意

    如果您有幸参与了一个长期运行的项目,那么有时您需要先编写数据层,然后可能是业务层,然后再向上移动。如果您的客户随后做出需要在数据层上重新工作的需求更改,那么数据层上的一组单元测试将确保您的方法不会以不希望的方式失败(假设您更新测试以反映新的需求)。但是,您可能也会从业务层调用数据层方法,并且可能会在多个地方调用。

    假设在业务层中有3个方法调用,但只修改了2个。在第三种方法中,您可能仍然从数据层获取看似有效的数据,但可能会打破几个月前编写的一些假设。这个级别(及以上)的单元测试应该被设计为发现错误的假设,如果失败,它们应该向您强调,有一段代码需要重新访问。

        14
  •  0
  •   itsmatt    17 年前

    首先编写测试的要点是,它强制执行您正在制定的需求和设计决策。当我修改代码时,我想确保这些代码仍然是强制的,并且很容易“破坏”某些东西,而不会出现编译器或运行时错误。

    我有一种测试优先的方法,因为我希望对我的代码有高度的信心。当然,这些测试必须是好的测试,否则它们不会强制执行任何东西。

    我有一些相当大的代码基础,我在工作,有很多非琐碎的东西正在进行。很容易做出一些改变,当X永远不会发生时,会产生涟漪并突然发生X。我的测试让我在很多情况下避免了一个关键(但微妙)的错误,而这个错误可能没有被人类测试人员注意到。

        15
  •  0
  •   David Holm    17 年前

    我觉得作为一个项目的单独开发人员,尤其是一个更大的项目,你往往会被分散得非常少。
    你正处于一个大的重构过程中,当突然发现一些关键错误时,由于某些原因在预发布测试中没有出现。在这种情况下,你必须放下一切,修复它们,在花了两周的时间把头发扯下来之后,你终于可以回到你以前做的任何事情上。
    一周后,您的一位最大客户意识到,他们绝对必须拥有这一酷炫的全新闪亮功能,否则他们将不会订购一个月前就应该订购的100万台。
    现在,三个月后,你甚至不记得当初为什么要开始重构,更不用说重构的代码应该做什么了。谢天谢地,您编写这些单元测试做得很好,因为至少它们告诉您重构后的代码仍然在做它应该做的事情。
    起泡,冲洗,重复。

    …我过去6个月的生活故事:-/

        16
  •  0
  •   Rinat Abdullin    17 年前

    新手在没有测试的情况下使用代码会非常困难。他们会打破东西。

        17
  •  0
  •   Jamie Ide    17 年前

    交付产品时,您的客户是否拥有源代码?如果你能让他们相信,通过单元测试交付产品会增加价值,那么你就是在推销你的服务,交付更好的产品。从客户机的角度来看,测试覆盖率不仅可以确保质量,还可以让未来的维护人员更容易地理解代码,因为测试将功能与UI隔离开来。

        18
  •  0
  •   Argelbargel    17 年前

    我认为TDD作为一种方法论不仅仅是“在进行更改时进行测试”,因此它不依赖于团队,也不依赖于项目规模。这是关于在开始真正思考如何实现所注意到的行为之前,注意自己对代码/应用程序的期望。TDD的主要焦点不仅是对编写的代码进行测试,而且还要编写更少的代码,因为您只需执行使测试绿色化的操作(稍后再进行重构)。

    如果您像我一样,发现在不考虑如何实现的情况下很难思考部分/整个应用程序的功能,我认为在代码之后编写测试并让代码“驱动”测试是很好的。

        19
  •  0
  •   darron    17 年前

    以下是一些模因和我的回答:

    “TDD让我想到它将如何失败,这使我成为一名更好的程序员”

    “应用程序需要正常工作”

    这假设您完全能够测试所有内容。您在正确地覆盖所有可能的测试方面不会比在一开始正确地编写功能代码方面做得更好。“应用程序需要工作 较好的 “这是一个好得多的论点。我同意这一点,但它是理想主义的,不足以像我希望的那样激发人们的积极性。这里的指标/轶事会很好。

    “为我的<库组件X>工作得很好”

    我在问题中说,我看到了这些案例的价值,但谢谢你的轶事。

    “想想下一个开发者”

    当您继承了一种不推荐的“必须做”方法时,您对使用这种方法完成的项目会有多大的欣赏?有人吗?如果TDD没有大家想象的那么好,想想TDD对下一个开发者意味着什么。

    “重构要容易得多”

    重构和其他任何技术一样是一种技能,迭代开发当然需要这种技能。如果我认为新的设计从长远来看会节省时间,我倾向于扔掉大量的代码,而且感觉也会扔掉大量的测试。哪个更有效?我不知道。

    ...

    我可能会向任何一个新手推荐某种程度的TDD。。。但对于那些已经在这个街区呆过几次的人来说,我仍然很难享受这些福利。我可能会开始向库中添加自动测试。有可能在做了这些之后,我会发现一般来说做这些更有价值。

        20
  •  0
  •   Bruce McGee    17 年前

    有动机的自我利益。

    在我的例子中,唯一的开发者就是小企业主。我已经写了相当数量的库代码(表面上)使我的生活更轻松。很多这样的例程和类都不是火箭科学,所以我可以通过查看代码、一些现场测试和调试方法来确保它们正常工作(至少在大多数情况下是如此),以确保它们按照我认为的方式运行。蛮力,如果你愿意的话。生活是美好的。

    随着时间的推移,该库不断增长,并被用于不同客户的更多项目中。测试变得更加耗时。尤其是在我(希望)修复bug并且(更希望)没有破坏其他东西的情况下。这不仅仅是针对我代码中的bug。我必须小心添加功能(客户不断要求更多的“东西”),或者确保代码在迁移到新版本的编译器(Delphi!)、第三方代码、运行时环境或操作系统时仍然有效。

    如果走到极端,我可以花更多的时间来审查旧代码,而不是从事新的(付费)项目。将其视为软件的休息角度(在未经测试的软件倒下之前,您可以将其堆叠到多高:)。

    像TDD这样的技术为我提供了一些方法和类,这些方法和类的设计更周密,测试更彻底(在客户得到它们之前),并且以后需要的维护更少。

        21
  •  -1
  •   Lance Kind    5 年前

    我们都是有良好记录的开发人员。毕竟,我们都在阅读Stackoverflow。我们中的许多人都使用TDD,也许这些人有很好的记录。我之所以被录用,是因为人们希望有人能写出优秀的自动化测试,并能将其传授给其他人。当我独自工作时,我在家里对我的编码项目进行TDD,因为我发现如果我不这样做,我会花时间进行手动测试,甚至调试,而谁需要这些。(也许那些人只有良好的业绩记录,我不知道。)

    说到成为一名优秀的汽车驾驶员,每个人都相信自己是一名优秀的驾驶员。这是所有司机都有的认知偏见。程序员有自己的偏见。本文将介绍开发人员(如OP dont do TDD)的原因 Agile Thoughts podcast series . podcast归档还包含测试自动化概念的内容,例如 test pyramid ,并介绍什么是TDD以及为什么要从第9集开始编写测试 podcast archive .

    推荐文章