以下内容是 Florian Motlik 的客座文章。Florian 是 Codeship 的 CTO,Codeship 是一个托管的持续集成和持续部署平台。您可能会问,到底是什么?这是一种用于开发网站的理念和工具集。这可能有点太简单化了,所以我让 Florian 来解释。
一个很棒的开发工作流程可以让您的优秀开发人员变得更出色,让您的出色开发人员变得非凡。糟糕的工作流程会将您最优秀的工程师的生产力降低到初级水平,并让他希望自己能够在其他地方工作。
对于每个团队,尤其是这些团队的领导者来说,让他们的开发工作流程井井有条至关重要。在过去几年中,持续集成和持续部署这两种最佳实践获得了很大的关注。以下是它们的简要定义。
持续集成是指在尽可能早地自动测试对代码库的每次更改的做法。
持续部署紧随持续集成中的测试,并将更改推送到暂存或生产系统。这确保了您的代码版本始终可访问。
首先,我们将仔细研究持续集成,并向您展示如何开始测试。然后,我们将继续进行持续部署,这是下一个合乎逻辑的步骤。
有了这两项,您的开发团队的效率将提高几个数量级。
持续集成
自动化是出色开发工作流程的基石。每个可以由机器完成的任务都应该由机器完成。自动化为您提供了专注的时间。测试就是这样一个任务。
通过测试,您可以确保客户在您的系统中采取的最重要步骤无论您进行何种更改都能正常工作。这使您对进行实验、实施新功能和快速发布更新充满信心。
从上层开始测试
良好的测试从用户视角看待应用程序开始。典型的工作流程是什么?用户经常会使用哪些功能和步骤?
然后开始对这些方面进行测试。使用像 Selenium 或 PhantomJS 这样的工具来确保这些重要的工作流程正常工作。
确定最关键工作流程的一个好方法是让团队中的每个人都写下这些工作流程的清单,然后将这些清单合并起来。您可以在我们的博客文章中阅读有关此技术的深入指南。
以下是一些可用于开始测试 UI 的工具列表
从这个强大的测试基础开始,确保工作流程正常运行,您可以更深入地开始对网站的不同部分进行单元测试。但请注意:您的客户希望您的 UI 正常工作,因此请确保每次更改后它都能正常工作!
有了所有这些工具,您为测试可以采取的最重要步骤就是开始。它会立即带来回报,不仅是技术方面的。您可以在本文中阅读有关 持续集成的业务优势,作者是 Joe Green。
持续运行您的测试
人会犯错误。有时人们认为更改很小,不可能破坏应用程序,因此他们不运行测试。然后您的产品宕机,没有人知道原因。
只有在您持续运行测试,而且对每次更改都运行测试时,自动化测试才能发挥其真正的力量。必须在自动化的独立系统上运行它们,以防止“在我的机器上能正常工作”综合征。只有当持续集成基础设施告诉您测试通过时,测试才算通过。
对每次更改立即运行所有测试的优势在于,您可以立即知道是否有什么东西坏了。假设您正在进行为期 2 周的冲刺。在冲刺的第二天,您的一个开发人员更改了一些内容,这导致测试失败。如果您没有持续运行所有测试,则可能没有人会发现问题。人们会继续工作,在冲刺结束时,您会再次运行整个测试套件。测试失败了。现在距离提交导致失败的更改已经过去了 2 周。找到导致测试失败的更改非常困难,因为从那时起已经提交了很多代码了。
许多团队的周期都比 2 周长。这是非常浪费的,可以通过在您的开发人员将代码推送到存储库时每次运行所有测试来轻松避免。任何错误都可以立即修复。
持续集成是持续部署的第一个,也是非常重要的步骤。
如果您想了解更多信息,Martin Fowler 已在他的博客上发布了一篇有关持续集成的精彩且深入的文章,点击此处查看
持续部署
如果代码没有在任何地方运行,就会腐烂。外部依赖项会更新、服务器包会安装、API 会更改或操作系统会替换。通常我们无法控制基础设施的每个部分。我们依赖于其他产品和公司来维护我们技术栈的一部分。所有这些更改都可能破坏您的应用程序,而您却浑然不知。
这就是为什么持续部署非常重要的原因。只要您存储库中的主开发分支通过了所有测试,您就应该将代码至少推送到暂存环境中,或者最好的情况是推送到生产环境中。然后,您的开发或 QA 团队可以审查应用程序的最新版本并提供反馈。此外,您可以针对该暂存系统运行测试,以确保它在类似生产的环境中正常工作。
这有助于您及早发现问题并在成本仍然较低时修复它们。在开始使用持续部署时需要理解的一个重要概念是部署管道。
部署管道
部署管道定义了从代码库到生产网站所需的所有步骤。自动化这些步骤对于实现快速部署至关重要。但通常,部署管道还包括手动步骤,例如产品经理签署新版本。
部署管道必须易于遵循和复制。这使您能够定期推送新的更改。尤其是在您需要发布修复程序时,预定义的步骤可以帮助您避免对网站造成更大的伤害。
设置部署管道并自动化这些步骤后,您就可以快速发布小型更改,获得客户反馈并改进您的产品。这为其他需要很长时间才能对客户反馈做出反应的公司带来了重大竞争优势。Intercom 发表了一篇关于此主题的精彩博客文章。
将新软件产品推向市场的成本在过去几年中下降了很多,这真是令人惊叹。构建优秀软件从未像现在这样容易或便宜。这为你和你的竞争对手创造了公平的竞争环境。您需要比竞争对手更快地发布新功能,同时提供更高质量和稳定的长期产品。持续部署是帮助您实现这一目标的技术之一。
我该怎么开始呢?
在与数十家公司的访谈以及数千名使用我们产品的开发人员的反馈后,我们确定了几个可用于开始使用持续部署的步骤。
测试,测试,再测试,但要明智地测试
测试是第一步。你需要达到一个状态,你可以更改系统中的几乎任何部分,并确信你没有破坏任何其他功能,因为你的测试会捕获这些错误。一旦你达到这个状态,你就可以不必再考虑这些更改可能带来的影响。你现在可以对你的产品进行实验并迭代,以构建你的客户想要并愿意为之付费的东西。
测试并不是为了让你的开发者开心,而是为了为你的用户构建一个稳定、高质量的产品。它们是让你的用户满意并引入变更而不破坏用户体验的工具。在没有适当且自动地进行测试(就像你的用户使用它那样)的情况下构建产品,就意味着束手束脚。你可能会发布新功能,但你永远不会像你本可以的那样快和好。
测试是持续部署的基础。 测试使软件,就像我们的一位开发者克莱门斯在他的博客文章中解释的那样。
示例
这段脚本 测试谷歌翻译,以确保它将 “早上好” 从德语翻译成英语
#Run with casperjs test translate.coffee
casper.start 'http://translate.google.com/', ->
@.sendKeys('#source', 'Guten Tag');
@.then ->
@.click '#gt-submit'
@.waitForText('Good day')
@.then ->
@.test.assertSelectorHasText '#result_box', 'Good day'
@.then ->
@.capture 'output.png'
casper.run ->
@.test.done(1)
CasperJS 可以帮助你快速开始测试你的应用程序,并且它可以扩展到测试更复杂的场景,根据你的需要。
自动化部署
你的部署中的每一步都应该自动化。一旦设置好,你就不必再考虑需要采取哪些步骤。每一个选择和每一个手动任务都会导致潜在的错误,因此你只需要更少地执行这些操作。通过自动化部署的各个部分,你可以推送新功能,但更重要的是,可以非常快速地推送修复程序。持续部署之所以有效,是因为自动化,因此不要跳过这一步。
自动化回滚
快速推送时,你也希望能够轻松地返回到早期状态。否则,你不会有足够的安全感来像你应该做的那样经常进行推送。
自动化回滚包括你的代码库以及你的数据库。确保定期备份你的数据库,并使用这些备份在测试机器上重建你的系统。如果你不定期恢复你的备份,你就无法确定它们在你迫切需要时是否能正常工作。
部署到预发布环境
创建一个预发布环境,并在进行任何更改时将你的主分支或主要开发线推送到该预发布应用程序。这个预发布应用程序是你的第一道防线,可以帮助你审查所有更改,然后再投入生产。你甚至可以在预发布环境中运行自动化测试,以确保它按预期工作。
使用你的预发布环境
如果你在日常工作中使用你的产品,请使用你的预发布环境,而不是你的生产服务器。随着你将更改持续地推送到预发布环境,你将直接看到出现故障的情况,因为它会立即影响你的团队。“吃自己的狗食”会让你的所有开发者都知道质量下降的时候。
自动部署到生产环境
作为最后一步,持续部署到你的生产环境。这将真正改变你的组织运作方式。更改你的站点将不再有任何恐惧。这意味着你可以快速迭代新功能,但如果你发布了一个错误,你也可以快速发布一个修复程序。你不会受限于任意周期,这些周期会减缓你的团队速度。
总结
迁移到持续部署将彻底改变你的开发工作。它会使你更有成效,并最终带来更稳定、更好的产品。有一些步骤,比如自动化测试,你需要首先开始着手。自动化测试不是构建更好软件的工具,而是为你的用户构建更好产品的流程。一旦设置好,你就可以享受每天部署多个新版本的收益。
如果出现任何问题,或者有任何其他需要我们帮助的地方,请在评论区告诉我们,或者在推特上给我们发送消息 @codeship 。我们最近还发布了一本免费的电子书,它将带你了解我们的开发工作流程,并深入探讨持续部署。 你可以在此处获取这本书。
祝你发布顺利,繁荣昌盛!
更多信息
- 持续集成简介,作者马丁·福勒
- 为什么要进行持续部署,作者埃里克·里斯
- 持续交付,作者杰兹·汉布尔
- 持续集成的商业案例
- 如何从上到下开始测试
- 使用 CasperJS 开始测试你的网站
我再怎么强调持续集成的重要性也不为过。
Healthcare.gov 没有使用它…… 谷歌、亚马逊已经树立了黄金标准。
我很幸运在过去 13 个月中为两家公司工作,它们在这方面做得很好,我们非常高效和敏捷。同样令人惊奇的是,我们的大多数 Web 开发人员都拥抱了 DevOps,并在该领域也取得了成长。
是的,CI 绝对是任何团队最重要的工具之一。它会让你进入一个很棒的工作流程。你们尝试过在 CI 进程之后进行部署吗?你们项目中在这方面有什么经验吗?
很好的建议!我从未在团队中工作过,但每次更改后我都会重新加载页面,看看新编辑是否破坏了任何内容。
虽然作为一个工作流程是可以的,但自动化该流程会帮助很多,这样你就可以知道你的页面是否工作,即使你可能不会查看每个页面。
我看到这种方法越来越普遍,但我不能同意所有观点,我无法理解为什么开发人员没有对此举手反对
你永远不应该在没有 QA 的情况下进入生产环境,发布一个稳定可靠的版本,你应该避免在没有测试的情况下进入生产环境(1,QA,UAT)…… 为什么要如此频繁地推送更改呢?如果你的代码和应用程序很稳定,它应该只需要最少的在线即时更新(2 绝不应该发生)
无论何时看到这种宣传,我都会觉得开发人员变得懒惰和不负责任,你必须避免出现问题…… 更新应该包含最少的错误修复,并且只有新功能…… 但是现代开发人员将最终客户作为他们的 QA,最糟糕的是最终用户允许这种情况发生,他们希望看到应用程序的每周更新…… 为什么我们要在生产环境中进行测试?QA 在做什么?为什么我们要教我们的用户测试并接受我们的错误和劣质软件?
(请注意,我只将产品开发过程分解成 “上线就绪” 和 “出问题就修复”,我们应该保证我们的应用没有bug)
我们发现情况正好相反。通过定期推送,我们被迫投入更多精力进行测试和自动化测试。它推动你对应用程序的每个部分进行充分测试。
QA 应该始终是开发流程的一部分。将代码交给另一个团队处理问题,并不会对开发团队施加正确的质量要求。
总的来说,它迫使我们构建更好的自动化质量控制,同时允许我们快速迭代产品,为客户构建产品。
我认为很多开发者像我一样,要么独自工作,要么可能只与另一个开发者一起工作,并认为他们的项目太小,无法实践 CI。然而,CI 对于任何规模的项目来说都是可能的,可以使用 GruntJs 等工具。我将从构建和集成一个测试开始,确保我的 HTML、CSS 和 JavaScript 不会出错。我可以从这里扩展或自定义。
这看起来像是一个好的基础目标吗?
是的。你不需要这些花哨的工具来在小型团队中实践 CI,说实话,甚至一些更大的团队也不需要。
在大型团队中,最好在一些明确的 CI 技术上标准化,但我不知道团队需要多大才能使其成为必要。
这里提到的某些工具很复杂且功能强大,我认为你可能需要有一个大型团队才能 “浪费时间” (实际上) 学习有效地使用它们,超出这里提供的“Hello World”示例。
如果你规模很小,保持简单。
嗨 Ryan,
设置第一个测试和整个 CI 的自动化工作流程是一个很好的第一步。我们通常会告诉新用户只需编写一个测试 (可以像简单地调用网站或登录一样容易),并使用这个测试构建整个自动化工作流程。一旦你设置好一切,它会一直自动运行,你就会进入一个 “为什么不为它编写一个测试” 的模式,因为整个 CI 已经设置好了,无论如何。我们与之交谈过的团队很快就从这一步扩展到测试所有内容,并真正深入到 TDD。
没错。查看我的项目(refactor 分支更新)的 Github 页面,以了解基于 Grunt 的 CI 开发过程的示例
coffee/md/less 文件在文件保存时编译为 js/html/css
每次页面重新加载时都会执行测试。
你只需输入
grunt
,编辑文件,重新加载浏览器 (还没尝试自动重新加载 : ))。我将评估 Brunch.io 而不是 Grunt,看起来很有希望。
我们在最新的项目中使用 CI……如果我们有时间修复单元测试 (目前大约有 5% 的单元测试失败) 会很好。
但是,它在大多数情况下确实很有帮助,因为你可以立即看到应用程序的哪一部分崩溃了。所以我要说,我喜欢它,并且永远不会考虑在没有它的情况下进行大型项目。
我和很多团队谈过,他们遇到了同样的问题,一些测试总是失败,问题是,你很容易陷入忽视所有测试的工作流程中。我在之前工作过的公司也遇到过这种情况,并且始终值得修复这些测试,或者如果它们确实不必要,就将其删除。如果只有一个测试始终失败,那么它会降低所有测试的实用性。
Selenium 在测试我们组装的捐赠脚本方面是一个救星。我们实际上使用了 Firefox 扩展 Selenium IDE,并记录了客户用来确保每个步骤都按预期工作的一般步骤。有一个表单按钮在某个时候由于一小段代码的更改而坏了,所以每天运行都检测到了它。它相当容易设置,尽管插件必须手动启动,但是一旦你单击启动,它就会为你完成所有工作。
我们使用 Selenium 进行所有前端测试,我们依赖它每天找到问题。能够自信地说你的应用程序最重要的功能对你的用户来说是可靠的,这非常有用。