TDD和版本控制


25

我目前正在学习TDD,并试图在我的个人项目中将其付诸实践。在许多这些项目中,我还广泛使用了版本控制。我对这两个工具在典型工作流程中的相互作用感兴趣,尤其是在使提交保持较小的原则上。以下是一些示例:

  1. 我开始一个新项目,并编写一个简单的测试以创建一个尚不存在的类。即使测试甚至无法编译,我也应该在编写类之前提交测试吗?还是应该在提交之前编译测试所需的最少代码量?

  2. 我找到一个错误并编写测试以重新创建它。我应该提交失败的测试还是实施错误修复然后提交?

这是两个立即想到的例子。随时在您的答案中提供其他示例。

编辑:

我在两个示例中都假设,在编写测试之后,我将立即编写代码以使测试通过。可能还会出现另一种情况:我在使用TDD的项目上工作了几个小时而没有提交。当我最终提交内容时,我想将我的工作分解成小块。(即使您只想在单个文件中提交某些更改,Git也会使此操作相对容易。)

这意味着,我的问题是一样关于为什么承诺,因为它是何时提交。

Answers:


21

即使测试甚至无法编译,我也应该在编写类之前提交测试吗?还是应该在提交之前编译测试所需的最少代码量?

当然不是。您应该同时完成测试和课程。提交甚至没有编译的东西1是没有意义的,并且如果您定期执行,肯定会使同一个项目上的人生气。

我找到一个错误并编写测试以重新创建它。我应该提交失败的测试还是实施错误修复然后提交?

不,不要提交失败的测试。勒布朗法律规定:

以后等于永远。

测试可能会长时间失败。最好在发现问题后立即修复。

另外,TDD的开发风格表明

测试驱动的开发不断重复添加失败的测试用例,传递它们并进行重构的步骤。

如果您未通过测试,则表示您没有完成该过程。


1当我说提交时,我的意思是真正地提交到主干(对于git用户,请推送您的更改,以便其他开发人员可以获取它们)。


4
“如果发生以下情况,肯定会令生气的人从事同一项目” –居住在SVN世界中的人使用GIT,而您不会让任何人生气
Mateusz 2013年

3
我认为在编写测试后提交就可以了,只是在完成后才推送它。
Matsemann 2013年

4
@radarbob这甚至适用于在提交和推送之间有区别的DVCS吗?我可以想象这样一种情况:我对本地git repo进行了几次提交,在最后一次提交时,构建没有中断,但在任何临时提交中,它都可能被破坏了。
Code-Guru

6
不,不要提交失败的测试。但是,TDD的要点之一就是在编码之前进行一次失败的测试。因此,进行失败的测试是有道理的。
mouviciel 2013年

4
@ Code-Guru:对于DVCS,该规则应为:“不要将损坏的代码提交给其他人经常从中提取的分支”。如果其他人没有从您的本地存储库中提取信息,那么您可以处于任何状态。
Bart van Ingen Schenau 2013年

6

即使测试甚至无法编译,我也应该在编写类之前提交测试吗?

没有。

我应该参加失败的考试吗

没有。

您在这里谈论两个范例:

  1. 测试驱动的开发-关于提交代码一言不发。实际上,它告诉您如何编写代码以及完成的时间。因此,我将每一个“完成”都视为提交的候选人。
  2. 敏捷开发,特别是:“尽早并经常提交”(不需要TDD)。其背后的想法是尽早与系统中的其他组件集成,从而获得早期反馈。如果您在本地提交DVCS而不进行推送,那么这毫无意义。本地提交只会帮助开发人员构建其工作。

我的建议是:按照TDD的规则进行操作,直到代码编译,测试变为绿色并且对系统有所贡献。因此,您应该垂直切割功能,例如,对于新的UI蒙版,不要创建整个表单并在没有业务逻辑的情况下进行提交,而是在前端以及业务逻辑和持久层中实现一个微小的方面。

对于较大的错误修正,请在每次改进(例如重构)后提交,即使该错误尚未修复。测试应该是绿色的,但是代码必须编译。


5

当然,您首先要使用健康的源代码控件(如git)。

然后,您可以按照自己喜欢的方式工作,并在每个角落进行承诺-任何步骤或子步骤都是公平的游戏。

然后,在推送内容之前,将整个工作压缩为一次提交。或一对夫妇,在一切都是绿色且构图合理的地方。并推动那些明智的承诺。对于多重情况,使其成为与--no-ff合并的分支。

源控件不是工作跟踪系统也不是历史学家。提交应呈现出合理的连贯增量,而结帐状态至少应在编译中。中间人可以保留一段时间以供审查,但是一旦一切正常,每个功能只需一次提交就可以了。


5

我对这个世界的理解是,人们致力于标记可能希望返回的一点。测试失败(但可以编译)的点肯定就是这样的点。如果我要朝错误的方向走去尝试通过测试,那么我希望能够将代码还原到起点,然后重试;如果我没有承诺,我将无法做到这一点。


我同意你的看法。我更喜欢使用其他分支来遵循“不破坏构建”的规则,并且仅在测试通过时才合并主干中的更改。
2015年

5

即使测试甚至无法编译,我也应该在编写类之前提交测试吗?

使用分支SCM(我看到您使用过Git),无论何时需要备份点(“我搞砸了;我将工作目录重置为最后一个备份点”)或版本稳定时,都应提交。当您拥有一个稳定的版本(所有测试都通过)时,您还应该考虑将当前功能分支合并到您的主要开发分支中。

还是应该在提交之前编译测试所需的最少代码量?

由您自己决定(git使您可以随时随地进行提交,而不会影响团队中的其他成员,也不会影响您使用不同功能的能力)。只要确保您没有在同一分支中同时拥有多个不完整(不起作用)的功能(那么它们将相互阻塞)。

我找到一个错误并编写测试以重新创建它。我应该提交失败的测试还是实施错误修复然后提交?

我通常为此提交两次提交,除非测试代码非常小/编写起来很简单。

这是两个立即想到的例子。随时在您的答案中提供其他示例。

编辑:

我在两个示例中都假设,在编写测试后,我将立即编写代码以使测试通过。

这可能是一个错误的假设。如果您一个人工作(个人项目),没有什么可以阻止您始终这样做。在我最成功的项目之一中(关于在整个项目开发过程中保持较高的代码质量和TDD),我们有时在实施测试之前数周就定义了测试(例如,我们将“ test_FOO_with_null_first_parameter”测试定义为空函数,然后,我们会花一个冲刺(或半个冲刺),有时一个月或更晚,因为只是增加了模块的测试覆盖率。

可能还会出现另一种情况:我在使用TDD的项目上工作了几个小时而没有提交。当我最终提交内容时,我想将我的工作分解成小块。(即使您只想在单个文件中提交某些更改,Git还是相对容易实现的。)这意味着我的问题与提交内容和提交时间有关。

我想肯定会创建备份点。这对于探索性测试(“我将在整个代码库中添加一些打印件,运行并git reset --hard在完成后删除它们)非常有用”。


2
注意建议使用git reset --hard。它是git中少数会导致您失去工作的命令之一。
gnash117 2013年

2

在我的工作流程中,只要有可能,我都会在个人源代码控制分支上做不确定的工作。因此,我可以尝试,失败,在必要时再试一次,直到它起作用为止,只有当我有实际的工作代码时,才提交给更大的项目。

从TDD的角度来看,“您首先要检查吗?”这个问题。完全取决于您正在处理的代码。如果是新代码,则只有在您需要进行检入之前,您才可以检入任何内容。但是,如果它是在已编译或已发布的代码中发现的错误,那么值得进行检查以重现该错误(通过ITSELF)。尤其是在工作日结束时,您将在修复之前离开办公室。代码。

(当然,如果您的商店有一个自动构建过程,如果任何单元测试失败都会终止,那么您可能不希望在修复该错误之前签入一个失败的测试。但这似乎是一种奇怪的工作方式,因为“找到和文档错误”和“修复错误”可以由两个完全不同的团队来完成。)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.