我应该使用TDD吗?

我是我(非常小)公司中唯一的开发人员,我即将开始使用适用于所述公司的中型ASP.NET Web应用程序。

我试图找出是否应该学习testing驱动开发(TDD),并在这个应用程序中实现它。

我需要很快开始开发新的应用程序,我很担心testing。 我已经编程了很多年,但从未做过任何unit testing。

我已经阅读了许多有关TDD的在线资源,但是我不确定是否对其有足够的了解,以使其在应用程序中有效。

这取决于你的优先事项在哪里。 如果您有兴趣以开发人员的身份进一步发展自己,那么TDD绝对值得一看。 它会帮助你重新思考你的代码,并可能使你成为一个更好的开发者。

但是,这可能轻而易举地被多lessTDD阻碍了您及时获得产品的能力。 你提到你是在这家公司工作的唯一开发人员,这就意味着你要完成项目的压力。 TDD当然是一个很好的做法,但有时候真正的生活约束和实用性必须先来。

所以,简而言之,如果您可以节省时间,那么请使用TDD。 实际上没有太多的开销,你总是可以跳过testing。 但是,如果你真的时间紧张,没有把产品和工作置于危险之中,那么你就不能把它整合起来,没有人会因为跳过它而让你失望。 纯粹主义者会不同意,但这不是一个黑白世界,有时必须妥协才能完成任务。

记住这一点:唯一不好的testing是你不执行的testing。

现在,你需要直接潜入TDD吗? 也许不会。 但是你绝对应该开始进行unit testing。 你不能很好的unit testinggraphics用户界面,这很好 – 保存那些UAT。

但是你可能会在幕后执行任何types的逻辑? 是的,你应该testing它。

首先尝试testing单个方法。 随着你走,你会开始痛苦,因为很可能你的代码不是被devise为testing。 这可以; 重构你的代码! 继续这样做,直到你可以testing你的代码。 记住你下一次编写代码时要做的第一次。

经过几次迭代,你会学到你需要学习的东西(真的,你只能通过这样做来学习),痛苦就会消失。 当发生这种情况时,我build议你可能已经准备好考虑TDD了。

我不能强调基于TDD的开发方法的优势。 当你采用TDD时,你的unit testing和你所写的代码一起成为一stream的公民,而不是为了进行unit testing而保持的代码,而不是保持最新。

在TDD中,使用unit testing作为组件应该执行的可执行规范。 你可以通过考虑你希望你的组件做什么,然后编写testing来实现这个function。 由于您的代码最初不会具有任何此function,因此您编写的所有新testing都将失败或显示为红色。 一旦你有了testing,开始实施这个组件。 渐渐地,当您添加所需function时,红色testing将变成绿色。 好的是,当你已经实现了足够的function来使所有的testing通过之后,你就知道你已经完成了预期的规范,并确切地知道在哪里停止。 我经常见到开发人员已经完成实现所需function但不停止的情况,而是增强了组件,增加了额外的function和视觉效果,这些都不是所需规范的一部分,浪费了有效的开发时间。

一旦你进行了unit testing,很容易在持续的集成环境中进行设置。 这个环境会从你的仓库检出最新的代码,编译它,然后运行你的unit testing。 如果发生任何回归,如果任何人检查了打破unit testing的任何代码,那么您将知道它是否属于pronto,而不是在将它部署到生产环境之后发现它。 为了确保新代码不会引入回归,我们在存储库上设置了login挂钩,以确保所有提交的代码都已经执行了相应的testing并通过了testing。 当你有多个人在一个项目上工作时,这是非常有用的,因为他们可以通过任何监控仪表板看到你可以使用的信息库是否可以很好地同步到这个时间点。 在本地化一个特定的版本库也是很容易的,这个版本可以工作,让人们用已知好的版本工作,而其他人正在努力解决目前打破你的构build的任何问题。 这也可能意味着,如仪表板所示,任何“绿色”构build都是非常有可能在推向生产环境时没有遇到问题的构build。

很多人认为采用TDD意味着额外的工作和麻烦,而且这样会花费更多的时间。 不过考虑到编写testing的额外时间会阻止任何正在testing的function被打破,而且你会更快地find这些中断,而不是晚些时候。

使用TDD的另一个优势是您可以更加关注您的devise,并且可以通过非TDD方法更好地实现结构化和组件化。 这种组件化对于能够具有快速执行和非易碎的unit testing套件是重要的。

GUItesting是困难的,但并非不可能。 考虑一下networking用户界面testing技术,如Selenium,W​​ebDriver和Watir,它们可以通过编程来实现networking用户界面。 使用这些工具进行昂贵的端到端testing也很容易误用这些工具。 一个更好的方法是抽象你的UI层,以便它可以独立于你的业务逻辑进行独立testing。 您不希望进行UItesting并对数据库执行操作。

为了重新上限,你想写出高效的unit testing,使TDD使用愉快的体验,而不是一个负担。 你的testing应该是快速的,单独testing组件,理想情况下应该始终运行。

我在这里描述的是一个理想的情况。 您不必采用所提及的每一个想法,但是您可以select任何工作来使您的开发过程更高效。

请注意,TDD不是关于testing; 这是一个发展过程。 testing不会取代testingfunction – 这是什么定义开发过程。

这听起来像是在谈论unit testing和其他自动化testing。 testing是好的。 自动化testing是很好的。 不要害怕犯错。 如果你考虑一下你的代码,并尽可能地自动化testing,那么你处于一个很好的位置 – 然而,这是一个收益递减的界限。 100%的自动化testing可能不是成本效益的 – 特别是对于你所描述的组织而言。

如果你真的在谈论TDD(专家们称之为TDD),那也可能是好的。 有许多开发过程。 要记住,发展进程是框架和指南 – 不是一个像追求一样的宗教。 没有一个过程是一刀切的。 做什么对你有意义,并随着你的进步而改进。 在一个开发组织中只有一个人使得改变过程非常轻松。 首先解决您的高风险问题,并在为低价值问题做好准备之前为他们设置一些轻量级stream程。

学习的最好方法就是做。 如果你已经阅读了很多内容,现在是时候了 – 作为一个开发者,unit testing可能是天赐之物,因为没有另外一双眼睛来看你的代码。

我仍然是一个新的开发者,并进入一个应用程序开发已经在进行的公司。 TDD帮助我确保新的更改不会破坏已经完成的工作,并且在我工作时帮助我在添加或修改代码时不得不大量增加bug。

我爱过从中学到的一切,强烈build议花时间学习TDD。

我.02

只有一个开发人员实际上是一个相当小的开发工作。 即使你期望很多屏幕,单个编码器也需要很长时间才能进入中等程度(除非他们已经完成了剪切和粘贴)。

我不是TDD的忠实粉丝,但是如果你是一个相对较新的程序员(不到10年),你自己就是一个人,担心质量问题,我相信这会让你放慢脚步,帮助你改善工作。 对于年轻的程序员来说,这会迫使他们更专注于代码的真实潜在行为,并逐步实现一步一步的工作(一个早期常见的错误是大量代码太重,然后尝试一次全部debugging旧的编码器可以逃脱,年轻的编码器通常需要一次处理更小的部分)。 粉丝经常说它大大改变了他们编码的方式(通常使整体工作更容易)。 至less你可以从它开始,如果没有真正的帮助,以后再抛弃它。

你最大的问题,TDD不会帮助,为web应用程序获得一个良好的架构结构。 一个你不想在五个月内丢掉的东西。 networking应用程序可能非常棘手,在前十到十二次,很less有人能够做到。

我最近也开始在所有新代码上使用TDD。 是的,起初看起来只是浪费时间,因为我所有的逻辑与Gui都紧密结合在一起,所以我不能写任何unit testing,真的可以保证我的代码完成它应该做的事情。
但是过了一段时间,我意识到编写unit testing真是太痛苦了,因为代码写得不好。 我开始用这种方式重构我的代码,所以我可以为它写unit testing。 我开始缩短我的方法,更多地使用接口,并试图尽可能地将逻辑与桂分开。
我认为在testing和validation代码之外使用unit testing的目的是让你成为一个整体更好的程序员。 无论如何,值得努力学习它。

以为我会总结和评论一些上述评论:

  1. 是的TDD是关于devise。 这不是关于testing。
  2. 不知道为什么QA参与乔治的devise阶段。 这听起来像他们正在指定自动化testing。 正如Tim指出的那样,这是一个发展过程。
  3. 凯文,你说'跳过testing'。 再来一次。 TDD是关于devise的,不是关于testing。 好吧,你可以跳过devise,但完成的应用程序将是越野车和不支持。
  4. Roshan提到,“你的组件应该做什么的可执行规范”。 这意味着完全最新的文档。 当您刚接触一个项目时,您可以快速掌握速度,您可以准确了解原始开发人员的意图。 而且,正如乔恩所说,你可以改变代码,确保没有任何东西被破坏。

你有容易unit testing的组件吗? 你可以构build你的应用程序是一套unit testing组件? 在TDD环境中工作的时候,这是一种思维方式。

它很容易说“它的GUI应用程序!它不可能unit testing我的东西”! 这可以是一个自我实现的预言。 当然,你不能简单地unit testing所有你的小部件的布局,但是你的程序有多less与你的小部件的布局有关呢? 您可能会阻止自己做好TDD,因为某些方面与您的GUI小部件的布局紧密耦合,或者与其他不太容易进行unit testing的其他方面耦合得太紧密。 停下来挑战自己 – 这是真的吗? 我是否可以对代码进行划分和模块化,使其可以更好地与系统的这些部分隔离开来? 这样做是否合适(unit testing收益是否值得?)。 不要接受单纯的软件不可能只是因为你的软件绑定到非unit testing组件。

TDD的开销随着您获得的经验而降低,并很快变得小于不使用TDD开发的开销。

然而,开始的开销可能很大,你会因为缺乏经验而失去时间做错事情。 一个关键的项目是一个危险的地方,包括学习一种新的开发技术所需要的时间

迦勒 – 我想要build立一个网站,帮助你自己在家学习TDD。 如果你没有承受压力,你会学得更好。 只是谷歌“tdd问题”,你会发现它。

如果做到实事求是,这可能是一个巨大的好处。 反对这个论点似乎总是花费太多时间,但大家都知道,如果许多故意牺牲质量的案例会更加不利。

我学TDD已经3年了,我可以诚实地说,我看到它带来了巨大的价值,我也看到这是一个完全浪费时间。

这是每个例子…

有益的:在一个相当复杂的解决scheme上工作,有许多依赖和变化,并不断发展。 devise考虑testing,并有unit testing回归套件,使我们能够快速适应变化,并能够重构代码以提高可维护性。 我们在创buildunit testing时使用了80/20规则,而忽略了低值testing用例。

不是有益的:(以教条的方式)决定我们必须对QA可以想到的每个testing用例,甚至UI案例进行自动化testing。 许多案例是如此简陋,涉及很less,很简单的代码。 让这些工作中的许多需要大量的设置和增加testing的数量来保持这么多,这显着减慢了我们的速度。

TDD是一个伟大的做法,我不能说得够高。

但是,如果我处于你的位置,我现在不用担心TDD,而是专注于在代码上进行一些很好的unit testing。

当棘手的商业逻辑出现时,你总是可以在你的项目中稍后开始使用TDD。

我不希望你有一个不愉快的TDD经验,如果你在交付压力下,没有使用这种做法的经验,这可能会发生。

在工作中使用之前,可以尝试在家中尝试几个TDD Katas来熟悉它。

一些好的Katas可以在这里find

TDD,伪TDD和准TDD。 许多不同的方法。 这取决于谁来执行TDD的级别。 还有很多的优点和缺点,这也取决于你的人员。 这是双刃剑的哲学之一。 如果你不知道自己在做什么,或者在你的团队中有一个单独的理解层次,它会让你陷入困境,并导致内部斗争,最终导致完全消除TDD。 TDD也不同于(只是写作testing)。