我过去使用持续集成服务器取得了巨大成功,并且不需要在源代码控制系统上执行代码冻结。
然而,最近似乎在我所见的任何地方,大多数商店在准备发布时使用代码冻结的概念,甚至是他们产品的新测试版本。这个想法甚至在我当前的项目中运行。
当您提前且经常签入,并使用单元测试、集成测试、验收测试等时,是否还需要冻结代码?
我过去使用持续集成服务器取得了巨大成功,并且不需要在源代码控制系统上执行代码冻结。
然而,最近似乎在我所见的任何地方,大多数商店在准备发布时使用代码冻结的概念,甚至是他们产品的新测试版本。这个想法甚至在我当前的项目中运行。
当您提前且经常签入,并使用单元测试、集成测试、验收测试等时,是否还需要冻结代码?
持续集成是一种“构建”,但它是开发周期编程部分的一部分。就像 TDD 中的“测试”是开发周期的编程部分的一部分。
作为整个开发周期的一部分,仍然会有构建和测试。
持续集成和测试的重点是缩短反馈循环并为程序员提供更多可见性。最终,这确实意味着测试和构建中的问题更少,但这并不意味着您不再执行开发周期的原始部分 - 它们只是更有效并且可以提升到更高的水平,因为正在解决更多琐碎的问题在开发周期的早期发现。
因此,您仍然必须冻结代码(或至少是一个分支),以确保您交付的产品的基线符合预期。仅仅因为某人可以高度自信地实现某些东西并不意味着它会在不经过相同的最终周期的情况下进入您的版本,而代码冻结是其中的重要部分。
使用 CI,您的代码冻结可能会非常短,因为您的最终构建、测试和发布可能非常可靠,并且代码冻结甚至可能不存在于小型项目中,因为不需要分支 - 您发布并立即返回很快就开始开发下一组功能。
我还想补充一点,CI 和 TDD 允许最终的构建和测试阶段恢复到更接近传统的瀑布(做所有的开发,做所有的测试,然后发布),而不是已经完成的更持续的 QA在每周或每月构建的项目上。您的测试人员可以使用 CI 构建来提供早期反馈,但它实际上是一种与最终测试不同的反馈,在最终测试中,您正在寻找稳定性和可靠性而不是功能(显然在单元“测试”中遗漏了功能)开发商建造的)。
代码冻结很重要,因为持续集成不会取代运行时回归测试。
构建应用程序并通过单元测试只是挑战的一小部分,理想情况下,当您冻结发布代码时,您将签署两件事:
如果您使用现代 SCM,只需在此时分叉代码并开始在分支中处理下一个版本,并在部署项目时进行合并。(当然,放置一个标签,以便在需要应用中断补丁时回滚该点)。
一旦代码处于“发布模式”,就不应触摸它。
我们的典型流程:
Development
||
\/
QAT
||
\/
UAT => Freeze until deploy date => Deploy => Merge and repeat
\ /
\- New Branch for future dev -------/
当然,我们在开发过程中通常有许多并行分支,它们在 UAT 之前合并到发布流中。
代码冻结与 QA 的关系比与 Dev 的关系更大。代码冻结是 QA 说的:“够了。我们只有带宽来全面测试到目前为止添加的新功能。” 这并不意味着开发人员没有足够的带宽来添加更多功能,只是 QA 需要时间来处理静止的代码库,以确保一切都能协同工作。
如果您都处于持续集成模式(包括 QA),这可能只是很短时间的冻结,而 QA 会在整个软件包发布之前对其进行最终批准。
这完全取决于您的 QA 和回归测试与开发周期的集成程度。
我会支持已经提到的关于 SCM 分支的投票,并允许开发人员继续使用与 QA 测试的代码分支不同的代码分支。这一切都回到了同一件事上。QA 和回归测试需要在发布前一段时间的静态代码库。
我听起来像是一个上下文驱动的人,但答案是“这取决于”。
代码冻结是一种应对问题的策略。如果您没有它擅长解决的问题,那么不,不需要它。如果您有另一种解决问题的技术,那么不,不需要它。
代码冻结是一种降低风险的技术。如果带来的优点是稳定性和简单性。它带来的缺点是
另一种技术是使用分支,例如使用“特征分支”。分支的缺点是处理分支和合并更改的成本。
您描述的降低风险的技术是自动化测试,以提供快速反馈。这里的权衡是增加一些风险的速度(你会错过一些错误)。
在我和你在一起的这些方法中,我更喜欢自动化测试。但是在某些情况下,例如非常高的失败成本,代码冻结确实提供了很多价值。
我认为代码冻结很重要,因为每个新功能都是潜在的新错误来源。当然回归测试很棒,有助于解决这个问题。但是代码冻结允许开发人员专注于修复当前突出的错误并将当前的功能设置为值得发布的状态。
充其量,如果我真的想在代码冻结期间开发新代码,我会分叉冻结的树,在那里完成我的工作,然后在冻结之后,将分叉的树合并回来。