持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

让我们讨论一下为什么 CI 工具和 CI 是完全不同的东西。

CI 旨在解决什么痛点,这个想法从何而来,它有效的最新确认是什么,如何理解你有一个实践而不仅仅是安装了 Jenkins。

做一篇关于持续集成的报告的想法出现在一年前,当时我正在去面试和找工作。 我与 10-15 家公司交谈过,只有其中一家能够清楚地回答 CI 是什么,并解释他们如何意识到自己没有 CI。 其余的人都在谈论关于 Jenkins 的难以理解的废话:) 好吧,我们有 Jenkins,它确实可以构建,CI! 在报告中,我将尝试解释持续集成实际上是什么,以及为什么 Jenkins 和类似工具与此关系非常微弱。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

那么,当您听到 CI 这个词时通常会想到什么? 大多数人会想到Jenkins、Gitlab CI、Travis等。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

即使我们用谷歌搜索,它也会给我们这些工具。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

如果您熟悉询问,那么在列出工具后,他们会立即告诉您 CI 是指您在 Pull Request 中构建并运行测试以进行提交。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

持续集成与工具无关,与在分支中进行测试的程序集无关! 持续集成是非常频繁地集成新代码的实践,使用它根本不需要围堵 Jenkins、GitLab 等。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

在我们弄清楚成熟的 CI 是什么样子之前,让我们首先深入了解它的提出者的背景,并感受他们试图解决的痛苦。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

他们解决了团队合作的痛苦!

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

让我们看一下开发人员在团队开发时面临的困难的示例。 这里我们有一个项目、一个 git 的主分支和两个开发人员。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

他们按照大家早已习惯的方式去上班。 我们在宏伟的计划中承担了一项任务,创建了一个功能分支,并编写了代码。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

人们更快地完成了该功能并将其合并到母版中。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

第二个需要更多时间,后来合并并最终发生冲突。 现在,开发人员不再编写业务所需的功能,而是将时间和精力花在解决冲突上。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

将您的功能与通用大师结合起来越困难,我们花在上面的时间就越多。 我用一个相当简单的例子来展示这一点。 这是一个只有 2 名开发人员的示例。想象一下,如果一家公司中有 10 人、15 人或 100 人写入一个存储库。 你会为了解决所有这些冲突而发疯。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

有一个稍微不同的情况。 我们有一个大师和一些开发人员在做一些事情。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

他们创造了一根树枝。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

死了一个,一切都好,他就通过了任务。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

与此同时,第二个开发人员交出了他的任务。 假设他将其发送以供审核。 许多公司都有一种称为审查的做法。 一方面,这种做法是好的、有用的,但另一方面,它在很多方面减慢了我们的速度。 我们不会深入讨论这个问题,但这里有一个很好的例子,说明了差评故事可能会导致什么后果。 您已提交拉取请求以供审核。 开发人员无需再做任何事情。 他开始做什么? 他开始承担其他任务。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

在此期间,第二个开发人员做了其他事情。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

第一个完成了第三个任务。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

过了很长一段时间,他的评论受到了考验,他正在努力达成协议。 发生什么了? 它捕获了大量的冲突。 为什么? 因为虽然他的拉取请求挂在审查中,但代码中的很多内容已经发生了变化。

除了冲突的故事,还有沟通的故事。 当您的线程等待审核时,当它正在等待某些内容时,当您长时间致力于某个功能时,您将停止跟踪服务代码库中其他正在发生的更改。 也许你现在想要解决的问题昨天已经解决了,你可以采取一些方法并重用它。 但您不会看到这一点,因为您始终使用过时的分支。 这个过时的分支总是导致您必须解决合并冲突。

事实证明,如果我们作为一个团队工作,即不是一个人在存储库中闲逛,而是 5-10 个人,那么我们不将代码添加到 master 的时间越长,我们遭受的痛苦就越多,因为我们最终需要然后合并它。 我们遇到的冲突越多,使用的版本越旧,问题就越多。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

一起做某事是痛苦的! 我们总是互相妨碍。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

这个问题早在20多年前就被注意到了。 我发现极限编程中第一次提到持续集成的实践。

极限编程是第一个敏捷框架。 该页面出现于 96 年。 我们的想法是使用某种编程实践、规划和其他东西,使开发尽可能灵活,以便我们能够快速响应客户的任何变化或要求。 他们从 24 年前就开始面对这个问题,如果你长时间地在场外做某件事,那么你就会花更多的时间在这件事上,因为你会遇到冲突。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

现在我们来单独分析一下“持续集成”这个词。 如果我们直接翻译它,我们就会得到持续集成。 但它的连续性如何还不是很清楚;它是非常不连续的。 但它有多少集成度也不是很明显。

这就是为什么我现在要引用《极限编程》中的内容。 我们将分别分析这两个词。

集成 - 正如我已经说过的,我们努​​力确保每个工程师都使用最新版本的代码,以便他努力尽可能频繁地将其代码添加到公共分支,以便这些是小分支。 因为如果它们很大,那么我们很容易陷入一周的合并冲突。 如果我们有一个很长的开发周期,例如瀑布式开发,开发人员会离开一个月来削减一些巨大的功能,则尤其如此。 而他将会在很长一段时间内陷入整合阶段。

集成是当我们将分支与主分支集成时,我们将其合并。 当我们是 transbase 开发人员时,有一个最终选择,我们努力确保立即写入 master 而不需要任何额外的分支。

一般来说,集成意味着获取您的代码并将其拖到母版中。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

这里的“连续”一词是什么意思,什么叫连续性? 实践意味着开发人员努力尽快集成他的代码。 这是他执行任何任务时的目标——让他的代码尽快出现在母版中。 在理想的情况下,开发人员每隔几个小时就会执行一次此操作。 也就是说,你把一个小问题合并到主问题中。 一切都很好。 这就是你努力的目标。 而且这必须持续进行。 你一做事,立刻就放进master里。

制作某些东西的开发人员应对他为使其正常工作所做的事情负责,而不是破坏任何东西。 这就是测试故事通常出现的地方。 我们希望对我们的提交和合并运行一些测试,以确保它有效。 这就是 Jenkins 可以为您提供帮助的地方。

但对于故事:让我们把改变做小,让我们让任务小,让我们提出一个问题并立即尝试以某种方式将其合并到主版本中 - 詹金斯在这里不会提供帮助。 因为 Jenkins 只会帮助你运行测试。

没有它们你也可以。 这根本不会伤害你。 因为练习的目的是尽可能经常测量,以免在将来的任何冲突上浪费大量时间。

让我们想象一下,由于某种原因,我们在 2020 年没有互联网。 我们在当地工作。 我们没有詹金斯。 这可以。 您仍然可以继续在当地设立分支机构。 你在里面写了一些代码。 我们在3-4小时内完成了任务。 我们切换到 master,执行 git pull,并在那里合并我们的分支。 准备好。 如果您经常这样做,那么恭喜您,您已经实现了持续集成!

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

现代世界有什么证据表明它值得花费精力? 因为一般情况下是很难的。 如果你尝试这样工作,你就会明白一些计划现在会受到影响,你将不得不投入更多的时间来分解任务。 因为如果你做男人……,那么你将无法很快达成协议,因此会陷入麻烦。 你将不再有练习。

而且价格会很昂贵。 从明天开始,不可能立即使用持续集成进行工作。 你们需要很长时间才能习惯,需要很长时间才能习惯分解任务,需要很长时间才能习惯重做复习练习,如果你们有的话。 因为我们的目标是让它今天融化。 如果您在三天内进行审查,那么您就会遇到问题,并且持续集成不适合您。

但我们现在有任何相关证据告诉我们投资这种做法是有意义的吗?

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

我首先想到的是 DevOps 状态。 这是他们进行了七年的一项研究。 现在他们作为一个独立的组织来做这件事,但在谷歌的领导下。

他们 2018 年的研究表明,尝试使用集成速度快、集成频繁且具有更好 IT 性能指标的短期分支机构的公司之间存在相关性。

这些指标是什么? 他们在调查问卷中从所有公司中获取了 4 个指标:部署频率、变更准备时间、恢复服务的时间、变更失败率。

首先,存在这种相关性,我们知道经常进行衡量的公司拥有更好的指标。 他们将公司分为几类:生产缓慢的慢速公司、中等绩效公司、高绩效公司和精英公司。 精英是Netflix、亚马逊,它们速度超快,做任何事都快速、漂亮、高效。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

第二个故事,发生在一个月前。 技术雷达有一篇关于 Gitflow 的精彩文章。 Gitflow 与其他所有分支的不同之处在于它的分支是长期存在的。 有些发布分支会存在很长时间,而功能分支也会存在很长时间。 Technology Radar 的这种做法已转至“保留”。 为什么? 因为人们面临着融入的痛苦。

如果你的分支使用了很长一段时间,它就会被卡住、腐烂,我们就会开始花更多的时间尝试对其进行某种改变。

最近 Gitflow 的作者说,如果你的目标是持续集成,如果你的目标是想要尽可能频繁地滚动,那么 Gitflow 是一个坏主意。 他在文章中单独补充道,如果你有一个可以为此努力的后端,那么 Gitflow 对你来说是多余的,因为 Gitflow 会减慢你的速度,Gitflow 会给你带来集成问题。

这并不意味着 Gitflow 不好并且不应该使用。 这是为了其他场合。 例如,当您需要支持服务或应用程序的多个版本时,即需要长期支持时。

但如果你与支持此类服务的人交谈,你会听到很多痛苦的事实,这个版本是 3.2,这是 4 个月前的版本,但这个修复程序没有包含在其中,现在,为了做到这一点,你需要做出一系列改变。 现在他们又陷入困境了,现在他们已经折腾了一个星期试图实现一些新功能。

正如亚历山大·科瓦列夫(Alexander Kovalev)在聊天中正确指出的那样,相关性与因果关系不同。 这是真实的。 也就是说,如果你有持续集成,那么所有的指标都会很好,这没有直接的联系。 但存在正相关关系,如果其中一个是,那么另一个很可能也是。 不是事实,但很有可能。 这只是一种相关性。

持续集成作为一种实践,而不是 Jenkins。 安德烈·亚历山德罗夫

看起来我们已经在做一些事情,看起来我们已经在合并,但是我们怎么能理解我们仍然有持续集成,我们经常合并呢?

Jez Humble 是《Handbook》、《Accelerate》、《持续交付》网站和《持续交付》一书的作者。 他提供了这个测试:

  • 工程师的代码每天都会到达大师那里。
  • 对于每次提交,您都运行单元测试。
  • master中的build失败了,大约10分钟就修复了。

他建议使用这样的测试来确保您有足够的练习。

我觉得后者有点争议。 也就是说,如果你能在 10 分钟内修复它,那么你就拥有了持续集成,在我看来,这听起来有点奇怪,但这是有道理的。 为什么? 因为如果你经常冻结,就意味着你的改变很小。 如果一个小的更改意味着您的主构建被破坏,那么您可以快速找到示例,因为更改很小。 这里你有一个小的合并,其中改变了 20-30 行。 而且,相应地,您可以快速了解原因是什么,因为变化很小,您可以在很小的范围内搜索问题。

即使我们的产品在发布后崩溃了,如果我们有持续集成的实践,我们的行动也会容易得多,因为变化很小。 是的,这会影响规​​划。 这会受伤。 而且,在这种实践中,最困难的事情可能是习惯分解任务,也就是说,如何去做,以便你可以在几个小时内完成某件事,同时通过审查,如果你有一个。 审查是一种单独的痛苦。

单元测试只是一个助手,可以帮助您了解集成是否成功以及是否没有任何问题。 在我看来,这也不完全是强制性的,因为这不是实践的重点。

这是对持续集成的简要介绍。 这就是这个练习的全部内容。 我准备好回答问题了。

我再简单总结一下:

  • 持续集成不是 Jenkins,也不是 Gitlab。
  • 这不是一个工具,而是我们尽可能频繁地将代码合并到母版中的实践。
  • 我们这样做是为了避免将来合并带来的巨大痛苦,也就是说,我们现在经历一点痛苦,以免将来经历更多。 这就是重点。
  • 另一方面是通过代码进行通信,但我很少看到这种情况,但这也是它的设计目的。

问题

未分解的任务怎么办?

分解。 问题是什么? 能举个例子,有一个任务,没有分解吗?

有些任务无法用“完全”这个词来分解,例如,那些需要非常深厚的专业知识的任务,实际上可以在一个月的时间内解决,以获得一些易于理解的结果。

如果我理解正确的话,那么有一些大而复杂的任务,其结果只有一个月才能看到?

恩,那就对了。 是的,最迟可以在一个月内评估结果。

美好的。 一般来说,这不是问题。 为什么? 因为在这种情况下,当我们谈论树枝时,我们并不是在谈论具有特征的树枝。 特征可能很大而且很复杂。 它们会影响大量组件。 也许我们无法在一个分支中完全完成这些任务。 这可以。 我们只需要分解这个故事。 如果某个功能尚未完全准备好,这并不意味着其某些代码无法合并。 例如,您添加了迁移,并且该功能内部有一些阶段。 假设您有一个阶段 - 进行迁移,添加新方法。 你已经可以每天测量这些东西了。

美好的。 那还有什么意义呢?

每天杀小东西有什么意义?

是。

如果他们破坏了某些东西,您会立即看到它。 你有一个小部件损坏了某些东西,你更容易修复它。 关键是现在合并一小部分比几周后合并大部分要容易得多。 第三点是其他工程师将使用当前版本的代码。 他们会看到这里添加了一些迁移,然后出现了一些他们可能也想使用的方法。 每个人都会看到您的代码中发生了什么。 修行就是为了这三件事。

谢谢,问题已关闭!

(奥列格·索罗卡)我可以补充一下吗? 你说的都对,我只是想补充一句话。

所以。

通过持续集成,代码不会在功能完全准备好时合并到公共分支中,而是在构建停止中断时合并到公共分支中。 而且您可以放心地每天根据需要多次进行掌握。 第二个方面是,如果由于某种原因你不能把每月的任务分解成至少三天的任务,我沉默了大约三个小时,那么你就有一个很大的问题。 没有持续集成这一事实只是这些问题中最小的一个。 这意味着您在架构和零工程实践方面存在问题。 因为即使这是研究,那么无论如何也必须以假设或循环的形式来表述。

我们讨论了区分成功公司和落后公司的 4 个指标。 我们仍然需要活着才能看到这 4 个指标。 如果你的平均任务需要一个月才能完成,那么我会首先关注这个指标。 我首先会把它减少到3天。 从那以后我开始考虑连续性。

我是否正确理解您的意思,您认为如果有任何任务需要一个月才能完成,那么一般来说投资于工程实践是没有意义的?

你有持续集成。 并且有这样一个主题,在 10 分钟内你可以修复修复或回滚它。 想象一下你推出了它。 此外,您甚至可以进行持续部署,将其推出到产品中,然后才发现出现了问题。 并且您需要回滚它,但您已经迁移了数据库。 你已经有了下一个版本的数据库模式,而且,你还有某种备份,数据也写在那里。

你还有什么选择呢? 如果回滚代码,则它无法再与此更新的数据库一起使用。

基地只会向前移动,是的。

工程实践较差的人很可能也没有读过关于……的厚书。 备份后该怎么办? 如果您从备份恢复,则意味着您会丢失当时积累的数据。 例如,我们在新版本的数据库上工作了三个小时,用户在那里注册。 您拒绝旧的备份,因为该方案不适用于新版本,因此您失去了这些用户。 他们发誓,他们不满意。

为了掌握支持持续集成和持续交付的全方位实践,仅仅学习如何编写是不够的...... 首先,它们可能有很多,这是不切实际的。 另外还有许多其他实践,例如科学实践。 有这样一种做法,GitHub一度普及了它。 这是当旧代码和新代码同时运行时的情况。 这是当你制作一个未完成的功能时,但它可以返回一些值:作为函数或作为 Rest API。 您执行新代码和旧代码,并比较它们之间的差异。 如果存在差异,则记录此事件。 这样,如果您在一段时间内没有发现两者之间存在差异,您就知道您已经准备好在旧功能之上推出一项新功能。

这样的做法有数百种。 我建议从 transbase 开发开始。 她并不是 100% 坚持持续集成,但实践是相同的,缺一不可。

您是否以 transbase 开发为例,您可以在其中看到实践,或者您是否建议人们开始使用 transbase 开发?

看看吧,因为他们将无法使用它。 为了使用它们,您需要大量阅读。 而当一个人问:“一个需要一个月的功能要做什么时,就说明他还没有读过有关 transbase 开发的内容。” 我现在还不推荐它。 我建议只关注如何在架构上正确地将大型任务分解为较小的任务的主题。 这就是分解的本质。

分解是架构师的工具之一。 我们首先进行分析,然后分解,然后综合,然后积分。 这就是我们一切顺利的方式。 而我们仍然需要通过分解成长为持续集成。 第一阶段就出现了问题,我们已经在讲第四阶段了,即整合的次数越多越好。 现在做这件事还为时过早;最好先砍掉你的庞然大物。

您需要在某些图表上绘制多个箭头和正方形。 你不能说现在我展示一个新应用程序的架构图,展示一个正方形,里面有一个应用程序的绿色按钮。 无论如何,都会有更多的方块和箭头。 我看到的每张图表都有不止一个。 即使在图形表示的层面上,分解也已经在发生。 因此,可以使正方形独立。 如果没有,那么我有一个很大的问题要问建筑师。

聊天中有一个问题:“如果审核是强制性的,并且需要很长时间,也许一天或更长时间?”

你的练习有问题。 审查不应持续一天或更长时间。 这与上一个问题是同一个故事,只是稍微温和一些。 如果审查持续一天,那么很可能这次审查正在发生一些非常大的变化。 这意味着它需要变得更小。 在Oleg推荐的transbase开发中,有一个故事叫做持续审查。 她的想法是,我们故意提出这么小的拉取请求,因为我们努力不断地合并,一次一点点。 因此,拉取请求更改了一个抽象或 10 行。 感谢这篇评论,我们花了几分钟的时间。

如果审核需要一天或更长时间,则说明有问题。 首先,您可能会遇到一些架构问题。 或者这是一大段代码,例如 1 行。 或者你的架构太复杂以至于人们无法理解它。 这是一个有点偏向的问题,但也是必须要解决的。 也许根本不需要审查。 我们也需要思考这一点。 回顾是让你放慢脚步的事情。 一般来说,它有其优点,但您需要了解为什么要这样做。 这是你快速传达信息的一种方式,这是你内部设定一些标准的方式还是什么? 为什么需要这个? 因为审核要么需要非常快地完成,要么完全取消。 这就像跨数据库开发——故事非常美丽,但只适合成熟的男人。

关于这 4 个指标,我仍然建议删除它们以了解这会导致什么。 看看数字,看看图片,一切都是多么糟糕。

(德米特里)我准备好与你讨论这个问题。 数字和指标都很棒,实践也很棒。 但你需要了解业务是否需要它。 有些企业不需要这种变化速度。 我知道有些公司不可能每 15 分钟就进行一次更改。 并不是因为他们太糟糕了。 这就是这样一个生命周期。 而要制作分支功能、切换功能,您需要深厚的知识。

情况很复杂。 如果您想更详细地阅读有关切换功能的故事,我强烈推荐它 https://trunkbaseddevelopment.com/。 Martin Fowler 有一篇关于切换功能的精彩文章:有哪些类型、生命周期等。切换功能很复杂。

你还没有回答这个问题:“到底需要不需要 Jenkins?”

无论如何,实际上都不需要詹金斯。 不过说真的,工具:Jenkins、Gitlab 会给你带来方便。 您将看到组件已组装或未组装。 他们可以帮助你,但不会给你练习。 他们只能给你一个圆圈——好的,不可以。 然后,如果你还编写测试,因为如果没有测试,那么它几乎毫无意义。 所以需要它,因为它比较方便,但一般来说没有它也可以生活,不会损失太多。

也就是说,如果你有练习,是否意味着你不需要它?

这是正确的。 我推荐 Jez Humble 测试。 我对最后一点持矛盾的态度。 但总的来说,如果你有三件事,你不断合并,你在 master 中的提交上运行测试,你快速修复 master 中的构建,那么也许你不需要任何其他东西。

当我们等待参与者提问时,我有一个问题。 我们刚才讨论的是产品代码。 您是否将其用于基础设施代码? 是相同的代码,相同的原理和相同的生命周期,还是有不同的生命周期和原理? 通常,当每个人谈论持续集成和开发时,每个人都会忘记还有基础设施代码。 而且最近这样的事情越来越多。 所有这些规则都应该带到那里吗?

即使不应该如此,但它会很棒,因为它会以同样的方式让生活变得更轻松。 一旦我们使用代码,而不是 bash 脚本,但我们有正常的代码。

停止,停止,bash 脚本也是代码。 别碰我的旧爱。

好吧,我不会践踏你的记忆。 我个人不喜欢 bash。 它总是丑陋而可怕。 而且它经常会出乎意料地损坏,这就是我不喜欢它的原因。 但是好吧,假设您有 bash 代码。 也许我真的不明白,那里有正常的测试框架。 我只是不知道。 我们得到同样的好处。

一旦我们使用基础设施即代码,我们就会遇到与开发人员相同的问题。 几个月前,我遇到了一个情况,一位同事向我发送了 bash 中 1 行的 Pull 请求。 然后你就在评审中闲逛了 000 个小时。 同样的问题也会出现。 依然是代码。 而且这仍然是一次合作。 例如,我们被拉取请求所困扰,并且我们被我们正在同一个 bash 中解决相同合并冲突的事实所困扰。

我现在正在非常积极地关注最美丽的基础设施编程的整个事情。 我现在已将 Pulumi 引入基础设施。 这是最纯粹形式的编程。 在那里它甚至更好,因为我拥有编程语言的所有功能,也就是说,我用相同的 if 突然做出了漂亮的切换,一切都很好。 也就是说,我的改变已经在master里了。 每个人都已经可以看到他了。 其他工程师也知道这一点。 它已经影响了那里的一些事情。 但是,并非所有基础设施都启用它。 例如,它在我的测试台上打开。 因此,再次回答你的问题,是有必要的。 同样,作为处理代码的工程师,它让我们的生活变得更轻松。

如果还有人有疑问吗?

我有个问题。 我想继续和奥列格讨论。 总的来说,我认为你是对的,如果一项任务需要一个月才能完成,那么你的架构就有问题,你的分析、分解、规划等就有问题。但我有一种感觉,如果你开始尝试按照持续集成进行实时部署,那么您将开始通过计划来纠正痛苦,因为您在其他任何地方都无法摆脱它。

(奥列格)是的,没错。 这种做法的努力程度可与任何其他严肃的文化变革实践相媲美。 最难克服的是习惯,尤其是坏习惯。 如果为了实施这种做法,需要严重改变您周围的人的习惯:开发人员、管理人员、生产经理,那么惊喜就在等着您。

还能有什么惊喜呢? 假设您决定更频繁地进行集成。 还有一些其他与集成相关的东西,例如工件。 例如,在您的公司中,有一项政策,即每个工件都必须在某种工件存储系统中以某种方式进行说明。 这需要一些时间。 一个人需要选中他作为发布经理已经测试过此工件的复选框,以确保它已准备好在生产中发布。 如果需要 5-10-15 分钟,但您每周进行一次布局,那么每周一次花费半小时就是一笔小税。

如果每天进行10次持续集成,那么10次需要乘以30分钟。 这超出了该发布经理的工作时间。 他只是厌倦了这样做。 某些做法有固定成本。 就这样。

并且您需要取消此规则,以便您不再做这样的垃圾,即您不会手动分配与某些内容相对应的学位。 您完全依赖于一些自动化的准备测试集。

如果你需要某人的证明,以便老板签字,并且在没有 Vasya 说他允许的情况下你就不能投入生产,等等 - 所有这些废话都会妨碍从业者。 因为如果有一些活动与税收相关,那么一切都会增加 100 倍。 因此,这种转变往往不会受到所有人的欢迎。 因为人的习惯是很难改变的。

当一个人做平常的工作时,他几乎是不假思索地做的。 她的认知负荷为零。 他只是摆弄它,他脑子里已经有了一个清单,他已经做了一千次了。 一旦你过来告诉他:“让我们取消这种做法,从周一开始引入一种新的做法”,对他来说,这就变成了一种强大的认知负担。 它同时降临到每个人身上。

因此,最简单的事情,虽然不是每个人都能负担得起这种奢侈,但这就是我一直在做的事情,这就是下面的。 如果一个新项目开始,那么通常所有未经测试的实践都会立即塞入该项目。 虽然这个项目还很年轻,但我们并没有真正冒任何风险。 还没有 Prod,没有什么可以销毁的。 因此,可以作为训练。 这种方法有效。 但并非所有公司都有机会经常启动此类项目。 虽然这也有点奇怪,因为现在已经有了彻底的数字化转型,每个人都必须展开实验,才能跟上竞争对手。

在这里你得出的结论是,你必须首先了解你需要做什么。 世界并不理想,产品也不理想。

是的,这些事情是相互关联的。

企业也不总是明白他们需要走这条路。

存在一种根本不可能改变的情况。 这是球队压力更大的情况。 团队已经很疲惫了。 她没有空闲时间做任何实验。 他们从早到晚都在开发功能。 而且管理功能也越来越少。 需要的越来越多。 在这种情况下,根本不可能有任何改变。 团队只能被告知明天我们会做和昨天一样的事情,我们只是需要多做一点功能。 从这个意义上说,任何实践的转变都是不可能的。 这是一种典型的情况,当时没有时间磨斧头,需要砍伐树木,所以他们用钝斧头砍树。 这里没有简单的提示。

(德米特里)我将宣读聊天中的澄清:“但是我们需要不同级别的大量测试覆盖率。 分配多少时间用于测试? 有点贵,而且需要很多时间。”

(奥列格)这是一个典型的误解。 应该有足够的测试让你有信心。 持续集成并不是先完成 100% 的测试,然后才开始应用这种实践。 持续集成减少了您的认知负担,因为您亲眼看到的每个变化都非常明显,即使没有测试,您也知道它是否会破坏某些东西。 您可以在脑海中快速测试这一点,因为变化很小。 即使您只有手动测试人员,对他们来说也更容易。 你翻了个身,说道:“你看,有什么东西坏了吗?” 他们检查后说:“没有,没有任何损坏。” 因为测试人员知道该往哪里看。 您有与一段代码关联的一次提交。 这是被特定行为所利用的。

当然,这里有你的点缀。

(德米特里)我不同意这一点。 有一种实践——测试驱动开发,可以帮助你避免这种情况。

(奥列格)嗯,我还没讲到这一点。 第一个幻想是您需要编写 100% 的测试,或者根本不需要进行持续集成。 这不是真的。 这是两种并行的做法。 而且他们并不直接依赖。 您的测试覆盖率应该是最佳的。 最佳 - 这意味着您自己对提交后您的 master 所保持的 master 质量充满信心,让您可以在醉酒的周五晚上自信地按下“部署”按钮。 你如何实现这一目标? 通过审查、通过覆盖、通过良好的监控。

良好的监控与测试没有什么区别。 如果您在预生产上运行一次测试,那么他们会检查您所有的用户脚本一次,仅此而已。 如果您在无限循环中运行它们,那么这就是您部署的监控系统,它会无休止地测试所有内容 - 无论是否崩溃。 在这种情况下,唯一的区别是执行一次还是两次。 一组非常好的测试……无休止地运行,这就是监控。 正确的监控应该是这样的。

因此,当你周五晚上准备好回家时,你究竟如何达到这种状态是另一个问题。 也许你只是一个大胆的渣男。

让我们回顾一下持续集成。 我们采取了一种稍微不同的复杂做法。

他们说,第二个幻想是 MVP 需要快速完成,因此根本不需要测试。 不一定是这样。 事实是,当你在 MVP 中编写用户故事时,你可以在球上开发它,也就是说,你听说有某种用户故事并立即跑去编写它,或者你可以使用 TDD 进行工作。 根据 TDD,实践表明,它不需要更长的时间,即测试是一种副作用。 TDD 的实践与测试无关。 尽管有所谓的测试驱动开发,但它根本与测试无关。 这也是一种架构方法。 这是一种准确地编写需要的内容而不编写不需要的内容的方法。 这是一种专注于您在创建应用程序架构方面的下一次思维迭代的实践。

所以,想要摆脱这些幻想并不是那么容易的事情。 MVP 和测试并不矛盾。 甚至相反,如果你使用 TDD 练习来获得 MVP,那么你会比完全不练习而是在球上做的更好更快。

这是一个非常不明显且复杂的想法。 当你听说现在我会编写更多测试,同时我会更快地做一些事情时,这听起来绝对不够。

(德米特里)这里很多人,当他们称呼 MVP 时,人们懒得写一些正常的东西。 这些仍然是不同的事情。 没必要把MVP变成一些不起作用的坏东西。

是的,是的,你说得对。

然后突然获得产品 MVP。

永远。

当您听说您编写测试并且似乎做了更多工作时,TDD 听起来很不寻常。 听起来很奇怪,但事实上,这样速度更快、更漂亮。 当您编写测试时,您已经在脑海中思考了很多关于将调用什么代码、如何调用以及我们期望它产生什么行为。 你不只是说我写了一些函数并且它做了一些事情。 起初你以为她有这样那样的条件,就会以这样那样的方式来召唤她。 您可以通过测试来覆盖这一点,并从中了解您的接口在代码中的外观。 这对建筑有巨大的影响。 您的代码自动变得更加模块化,因为您首先尝试了解如何测试它,然后才编写它。

TDD 发生在我身上的事情是,当我还是一名 Ruby 程序员时,我在某个时候聘请了一位 Ruby 导师。 他说:“让我们按照 TDD 来做吧。” 我想:“该死,现在我必须额外写点东西了。” 我们同意在两周内我将使用 TDD 用 Python 编写所有工作代码。 两周后,我意识到我不想回去。 经过两周的尝试将这一点应用到任何地方之后,您会意识到,即使只是思考,也变得多么容易。 但这并不明显,所以我建议大家,如果你感觉TDD很难、费时、没必要,试着坚持两周。 两个对我来说就足够了。

(德米特里)我们可以从基础设施运营的角度来拓展这个想法。 在我们推出任何新产品之前,我们会进行监控,然后再推出。 在这种情况下,监控就成为我们的常态测试。 通过监控才能发展。 但几乎所有人都说很长,我很懒,我临时写了一个草稿。 如果我们做了正常的监控,我们就了解CI系统的状态。 而且CI系统有很多监控。 我们了解系统的状态,我们了解其中的内容。 在开发过程中,我们只是制作系统,使其达到所需的状态。

这些做法早已为人所知。 我们大约 4 年前讨论过这个问题。 但四年来,几乎没有任何改变。

但就此而言,我建议结束正式讨论。

视频(作为媒体元素插入,但由于某种原因不起作用):

https://youtu.be/zZ3qXVN3Oic

来源: habr.com

添加评论