Python 高手编程系列一千零七十三:选择正确的工具和常见的陷阱

如前所述,没有完美的 CI 工具可以适合每个项目,最重要的是,它使用的每个组织和工作
流程。针对在 GitHub 上托管的开源项目,我可以给一个建议。对于代码平台无关的小型项目,
Travis CI 似乎是最好的选择。它很容易开始,并将给你几乎即时的满足与最小量的工作。
对于封闭源的项目,情况完全不同。有可能你需要在各种设置中评估几个 CI 系统,直
到你能够决定哪一个最适合你。我们只讨论了 4 种流行的工具,但它们应该是一组相当具
有代表性的系统。为了使你更容易地做出决定,我们将讨论与持续集成系统相关的一些常
见问题。在一些可用的 CI 系统中,比在其他系统中更可能犯某些错误。另一方面,一些问
题对于所有应用可能并不重要。我希望通过结合你的需求的知识与这个简短的小结,可以
让你更容易地在一开始就做出正确的选择。
问题 1——过于复杂的构建策略
一些组织喜欢正式化,并且超出合理水平的构建事物。在创建计算机软件的公司中,
这在两个领域尤其如此:项目管理工具和 CI 服务器上的构建策略。
项目管理工具的过度配置通常以 JIRA(或任何其他管理软件)上的问题处理工作流结
束,这样的复杂性使得它们在表示为图形时永远不适合单个项目。如果你的经理热衷于这
样的配置/控制,你可以跟他谈话,或者用另一个经理替换他(阅读:退出你当前的工作)。
不幸的是,这并不能保证在这方面会有任何改进。
但是谈到 CI,我们可以做更多。持续集成工具通常由我们开发人员维护和配置。这些
是我们的工具,应该改善我们的工作。如果有人忍不住想去切换每个开关和转动每个旋钮,
那么他应该远离 CI 系统的配置,特别是如果他的主要工作是谈一整天或者做决定。
实际上没有必要使复杂的策略来决定应该测试哪个提交或分支。不需要限制测试哪个
特定的标签。无需为了执行更大的构建而对提交进行排队。无需通过自定义提交消息禁用构建。你的持续集成过程应该很简单。测试一切!总是测试!就这样!如果没有足够的硬
件资源来测试每个提交,那么添加更多的硬件。记住,程序员的时间比硅芯片要贵。
问题 2——过长的构建时间
漫长的构建时间会扼杀任何开发人员的效率。如果你需要等待几个小时,知道你的工
作是否正确,那么你将没有办法保持高效。当然,当你的特性被测试时,有些工具会有所
帮助。无论如何,作为人类,多任务是非常令人讨厌的。在不同问题之间切换需要时间,
并且最终,将我们的编程效率降低到零。一次处理多个问题时,将很难保持专注。
解决方案非常简单:不惜任何代价,保持快速构建。首先,尝试找到瓶颈并优化它们。
如果构建服务器的性能是问题,那么尝试水平扩展。如果这没有帮助,则将每个构建分成
较小的部分并且进行并行化。
有很多解决方案可以加快缓慢的构建测试,但有时没有办法解决这个问题。例如,如
果你有自动的浏览器测试或者需要对外部服务执行长时间的运行调用,那么很难逾越一些
硬性限制而提高性能。例如,当你的 CI 中的自动验收测试的速度成为问题时,那么你可以
适当放宽测试一切,总是测试的规则。程序员最重要的是单元测试和静态分析。因此,根
据你的工作流程,缓慢的浏览器测试有时可以推迟到发布正在准备的时候。
缓慢构建运行的另一个解决方案是重新思考应用程序的整体架构设计。如果测试应用程序
需要很多时间,通常意味着,它应该分成几个独立的组件,可以单独开发和测试。将软件编写为
巨大的单块是最容易失败的。通常在任何软件工程过程中,软件都会因为没有正确模块化而中断。
问题 3——外部作业定义
一些持续集成系统(尤其是 Jenkins)允许你通过网络页面设置大部分构建配置和测试
过程,而无需接触代码仓库。但是,你应该避免将任何构建步骤/命令的入口点到放到外部
系统。这是 CI 中的一种反模式,只能引起麻烦。
作为引入全局外部构建定义的问题的一个例子,让我们假设我们有一些开源项目。最
初的开发是忙碌的,我们不关心任何风格的规范。我们的项目是成功的,所以开发需要另
一个主要版本。一段时间后,我们从 0.x 版本转移到 1.0,并决定重新格式化所有的代码,
以符合 PEP 8 准则。这是一个很好的方法,静态分析检查可以作为 CI 构建的一部分进行,
所以我们决定将 pep8 工具的执行添加到构建定义。如果我们只有一个全局外部构建配置,
那么如果需要对旧版本的代码进行某些改进,就会出现问题。例如说,有一个关键的安全
问题,需要在应用程序的两个分支:0.x 和 1.y 修复。我们知道 1.0 以下的任何版本都不
符合风格指南,并且新引入的针对 PEP 8 的检查将会将构建标记为失败。
问题的解决方案是保持你的构建过程的定义尽可能接近源。对于某些 CI 系统(TravisCI 和 GitLab CI),默认情况下你将获得该工作流。使用其他解决方案(Jenkins 和 Buildbot),
你需要额外注意,以确保大多数构建过程包含在代码中,而不是某些外部工具配置。幸运
的是,你有很多选择,允许这种自动化。
● Bash 脚本。
● Makefiles。
● Python 代码。
问题 4——缺乏隔离
我们已经多次讨论了隔离在 Python 编程中的重要性。我们知道,在包级别上隔离
Python 执行环境的最佳方法是使用 virtualenv 或者 python -m venv 的虚拟环境。不
幸的是,当测试代码用于持续集成过程的目的时,通常是不够的。测试环境应尽可能接近
生产环境,如果没有额外的系统级虚拟化,这是很难实现的。
当你在构建应用程序时无法确保正确的系统级隔离时,可能遇到的主要问题有:
● 持久化在文件系统或后台服务(缓存,数据库等)的构建之间的状态。
● 多个构建或通过环境,文件系统或后台服务相互交互的测试。
● 由于生产环境的操作系统的特性而无法在构建服务器上捕获的问题。
如果你需要执行同一应用程序的并行构建或甚至并行化单个构建,上述问题特别麻烦。
一些 Python 框架(主要是 Django)为数据库提供一些额外的隔离级别,以确保在运行
测试之前清理存储。还有一个针对 py.test 相当有用的扩展叫作 pytest-dbfixtures
(参考 https://github.com/ClearcodeHQ/pytest-dbfixtures),让你更可靠地实现。无论如何,这
样的解决方案为你的构建添加了更多的复杂性,而不是减少。在每次构建(以 Travis CI 的
作法)中始终清除虚拟机似乎是一个更优雅和更简单的方法。
小结
我们在本章中学习了以下内容。
● 集中式和分布式版本控制系统之间有什么区别。
● 相对于集中式版本控制系统,为什么你更应该选择分布式版本控制系统。
● 在 DVCS 中,为什么 Git 应该是你的第一选择。
● Git 的常见工作流和分支策略是什么。
● 什么是持续集成/交付/部署,以及哪些流行工具允许你实现这些流程。
下一章将解释如何清晰地文档化你的代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值