如何保证所有单元测试在提交之前通过?

时间:2011-08-18 14:48:35

标签: unit-testing svn tortoisesvn continuous-integration

最近我们遇到了一些问题,即开发人员将代码提交给SVN但没有通过单元测试,无法在所有平台上编译,甚至无法在自己的平台上编译。虽然这一切都被我们的CI服务器(巡航控制)所取代,并且我们已经制定了试图阻止它发生的流程,但我们真的希望能够阻止流氓提交的发生。< / p>

基于这里的一些其他问题,在服务器端强制将其作为预提交钩子似乎是一个坏主意,主要是由于构建+运行测试所需的时间长度。我做了一些谷歌搜索并发现了这个(所有开发者都使用TortoiseSVN):

http://cf-bill.blogspot.com/2010/03/pre-commit-force-unit-tests-without.html

哪个会解决至少两个问题(它不会在Unix上构建),但如果失败则不会拒绝提交。所以我的问题:

  • 有没有办法在TortoiseSVN中进行预提交挂钩导致提交失败?
  • 有没有更好的方法来做我一般想做的事情?

3 个答案:

答案 0 :(得分:21)

绝对没有理由为什么你的预提交钩子不能运行单元测试!你所有的预提交钩子必须做的是:

  • 将代码签出到工作目录
  • 编译所有内容
  • 运行所有单元测试
  • 如果单元测试失败,则失败。

完全可以做到。而且,之后,开发商店的每个人都会讨厌你的胆量。

请记住,在预提交挂钩中,整个挂钩必须先完成才能允许提交 并且控制权可以返回给用户

进行构建并运行单元测试需要多长时间? 10分钟?想象一下做一个提交并坐在那里等待你的承诺发生10分钟。 这就是为什么你被告知不要这样做的原因。

您的持续集成服务器是进行单元测试的好地方。我比CruiseControl更喜欢HudsonJenkins。它们更易于设置,并且其网页更加用户友好。更好的是他们有各种各样的插件可以提供帮助。

开发人员不喜欢知道他们破坏了构建。想象一下,如果您组中的每个人都收到一封电子邮件,说明您提交了错误的代码。在你提交之前,你不确定你的代码是否合适吗?

Hudson / Jenkins有一些不错的图表可以显示单元测试的结果,因此您可以从网页上看到测试通过和失败的情况,因此很清楚究竟发生了什么。 (CruiseControl的网页对普通人来说难以解析,因此这些事情并不那么明显。)

我最喜欢的Hudson / Jenkins插件之一是持续集成游戏。在这个插件中,用户可获得良好构建,修复单元测试以及创建更多传递单元测试的分数。他们因糟糕的构建和破坏单元测试而失去积分。有一个记分板显示所有开发人员的观点。

我很惊讶开发人员如何认真对待它。一旦他们意识到他们的CI游戏分数是公开的,他们就变得非常有竞争力。当构建服务器本身由于某些奇怪的原因而失败时,他们会抱怨,并且他们为错误构建丢失了10分。但是,失败的单元测试数量逐渐减少,单位测试的数量猛增。

答案 1 :(得分:2)

有两种方法:

  1. 学科
  2. 工具
  3. 根据我的经验,#1只能让你到目前为止。

    所以解决方案可能就是工具。在你的情况下,障碍是Subversion。将其替换为像Mercurial或Git这样的DVCS。这将允许每个开发人员在他们自己的分支上工作而没有Subversion的合并噩梦。

    每隔一段时间,开发人员就会将一个功能或分支标记为“完整”。这是将功能分支合并到主分支的时间。将其推送到CI服务器监视的“临时”存储库中。然后,CI服务器可以提取最后一个提交,编译和测试它们,并且只有在它通过时才将它们推送到主存储库。

    所以循环是:主要回购 - &gt;开发者 - &gt;分期 - &gt;主

    这里有很多答案可以为您提供详细信息。从这里开始:Mercurial workflow for ~15 developers - Should we use named branches?

    [编辑] 所以你说你没有时间解决开发过程中的主要问题......我会让你猜到这听起来对任何人来说......; - )

    无论如何......使用hg convert从Subversion树中获取Mercurial repo。如果你有一个标准的设置,那不应该占用你的大部分时间(它只需要很多时间在你的计算机上,但它是自动的)。

    克隆回购以获得工作回购。这个过程是这样的:

    • 开发你的第二个克隆。为此创建功能分支。
    • 如果您需要更改某人,请转换为第一个克隆。从那里拉到你的第二个克隆(这样,你总是从subversion获得一个“干净”的副本,万一你搞砸了。)
    • 现在合并Subversion分支(default)和您的功能分支。这应该比使用Subversion更好。
    • 当合并正常(为您运行所有测试)时,请从两个分支之间的差异中创建补丁。
    • 将补丁应用于Subversion的本地签出。应该没有问题。如果没有,您可以清理本地结帐并重复。没有机会在这里失去工作。
    • 提交subversion中的更改,将它们转换回repo#1并进入repo#2。

    这听起来像很多工作,但在一周内,你会想出一两个脚本来完成大部分工作。

    如果您发现有人破坏了构建(测试不再为您运行),请撤消合并(hg clean -C)并继续处理您的工作功能分支。

    当你的同事抱怨有人打破了这个版本时,告诉他们你没有问题。当人们开始注意到你的生产力要好得多,尽管你必须跳过所有的箍,但要提到“如果我们要划伤SVN会更简单。”

答案 2 :(得分:1)

要做的最好的事情就是努力改善团队的文化,这样每个开发人员都会对这个流程做出足够的承诺,以便在不确定其正常工作的情况下以任何方式确保其无法正常工作你们都同意了。