关于不断变化的需求和小功能的好处世界中的生活

一年多以来,我们一直在MyStore中创建可帮助用户购买和出售带有标签商品的功能。 关于标签的新闻在哈布雷(Habré)上滑了很多次,所以很简短:自2019年以来,必须对商品进行标记。 并非一次完成所有操作,但是现在您需要给香烟,鞋子,香水和汽车轮胎贴标签。 同时,当政府系统的API不断变化时,我们正在处于不确定的情况下工作。


因此,我们只有两种与政府机构整合的方法:等到一切都安定下来,错过市场领导地位,或者在不断变化的需求中开发系统。


我们选择第二种方法-仅出于灵活方法论的精神。 我认为敏捷确实可以帮助解决应用问题。 在瞬息万变的世界中,生活是您可以扭转的领域。



我叫Maxim Sukharenko,我是MySklad服务平台的团队负责人。 今天,我将告诉您我们如何处理不断变化的需求。


从经典到Scrum


监管机构最初计划的系统开发截止日期为2019年4月,但您了解所有内容。 结果,截止日期移到了十月。 在有新的截止日期的地方,有新的要求和新的格式。 我们迫不及待要修复该API,因此我们没有时间实现集成。 因此,他们决定“犹豫与政党路线”。


我们考虑了为我们提供用于外部系统的适配器的经典方法。 用带有开关的插头来补充它,并时常将插头和适配器的功能上拉到外部系统的当前状态。



逻辑建议为了开发具有不断变化的界面的系统,您需要在某个时间点修正需求。 但是只有什么呢? 直到我们开发了部分功能?


您必须承认,让未完成的功能无法通过测试是令人不快的,并且还要开始将其破坏为新功能。 您可以确定功能开发期间的要求。 但是,对于可以在开发中使用几个月的大型功能该怎么办? 这么长时间都无法确定要求。


因此我们转向了Scrum。 他告诉我们,在sprint结束之前,我们必须提供具有新功能的有效产品。 但是,这如何与固定要求和重要功能抗衡? 关于这个问题有一个很好的笑话:


“医生,当我这样做时,会伤到我。”
“而且你就是不那样做。”


谁不懂, 就不做大功能 。 您可以将需求固定一两个星期,以便与sprint保持一致,并根据需求为sprint设置功能的实现。 并且必须将功能打成这样的碎片,以使它们适合一两个冲刺。 觉得太棘手吗? 然后! 您就是不知道如何减价。 看到了,修拉,看到了,它们是金色的。


当然,这不是那么简单,我们需要有目的地朝着这个方向前进-为了使开发脱离“我们将进行六个月,然后我们将推出新版本进行测试”。


秘诀是在每个sprint的末尾都有一个稳定的版本 。 当然,由于稳定​​分支机构的开销成本的增加,这似乎将增加开发时间,并且该开发将不是最佳的。 但是这里的情况与测试几乎相同,下面让我们讨论一下。


战斗任务


现在是实际情况。 我们的任务是在系统和API之间配置加密,以便用户使用密钥对所有请求进行签名。 我认为你们中的许多人都遇到过CryptoPro,所以我们不得不这样做。


如果使用标准方法,将形成一个孤立的任务-为服务设置密码。 我们会将其挂在一个人身上,一个月后,我们将删除该状态,并怨恨为什么它不会以任何方式结束。 开发人员将逐渐变成来自另一个世界的野生动物,嘴巴和野性的眼睛都带有泡沫。


我们将其分解为小任务,并分散在整个团队中。 我将加密技术与酒精进行了比较:在公司和适量的情况下,它比单独使用要好得多。
由于我们正在开发云服务,因此使用CryptoPro EDS Browser插件更容易(这不是广告,这是绝望的)。 它允许CryptoPro CSP将密钥和加密方法扩展到网页。


首先,用户选择在与服务一起使用时将使用哪个密钥,然后进行身份验证以获得令牌。 然后只有借助加密和令牌API调用。 似乎一切都很简单(否)。


首先,我们将MVP与服务隔离开来-配置插件与API的交互。 您知道制造商提供多少有关cryptoPro浏览器插件的文档吗? 一点都不! 只有逆向工程的例子,只有铁杆。 不眠之夜,并试图确定这些或其他参数的影响。


只有这样,我们才能够尝试将其构建到我们的生态系统中。 一个人将原型组件的外观转换为人类形式,第二个人将其与业务逻辑联系起来,第三个人编写用于后代配置的说明。 每个任务都有一个特定的目标,并且与其他任务相对隔离。 人们需要讨论一些东西,并与谁分享痛苦。


因此,局势变得相当稳定。 在小的迭代中,我们添加了新功能,我们会不时更新外部接口,并将更改深入地传播到我们的系统中。 但是问题来了:住到另一个分支直到最后一个分支,还是试图在主数据库中不断保留小功能?


测试功能


我建议弄清楚如何进行测试,以及如何将集成添加到实时项目中。


让我们从测试开始。 首先,我们将确定可以称为测试功能的内容。 我建议命名通过验收测试的功能,包括回归测试。 我们只会同意我们不会诉诸于生活黑客,“没有测试-这意味着一切都已通过测试”。 我们需要在产品中维护我们的代码,测试范围越多越好。 此类测试的自动化百分比越高,功能测试的每次迭代越便宜,并且可以完成的次数就越多。


我们有一组特定的验收和回归测试,其中一些是自动化的,有些是手工完成的。


如果我们正式采取措施,则应在每次代码更改后进行测试。 例如,他们将您的功能分成六张票,在测试过程中发现了十个错误。 并让每个测试花费四个小时:自动不计算在内,而手动仅花费四个小时。 事实证明,通过基本和正式的工作方式,我们将花费64个小时。
现在让我们尝试测试不是在每次代码更改之后,而是在一次代码更改之后。 逻辑建议我们只花32个小时。 并且仅在开发功能并修复所有缺陷之后才进行测试。 但是,前提是所有缺陷彼此隔离,在生命中不会发生。


在生活中,事实证明,在开发功能之后,将进行测试并进行第一波错误检查。 然后修复错误,破坏功能,并通过错误测试它们。 他们进行了第二次全局测试,并且出现了新的漏洞。 这些错误在更正第一波并更改功能时被隐藏并出现。 如此多次。


通常,您需要进行三到五个完整的测试-取决于功能的复杂性和手的方向性。 但是,如果您击败了小功能,则可以进一步加快这一过程。


例如,如果您将一个要在四个小时进行测试的功能分解为两个要在三个半半小时进行测试的功能,那么您将得到五个小时而不是四个小时。 似乎没有利润。 但是它表现为减少了所发布功能的复杂性并减少了相关缺陷链的可能性。 结果,全面测试的迭代次数减少了。



添加到项目


现在,我们将分析在开发人员仍在工作的项目中创建功能时的情况。 假设我们使用相对标准的源代码“每功能分支”(每张票的分支)概念。


显然,维护早午餐的相关性的成本与其寿命成正比。 当前票证中的代码交叉点越少,合并中的问题就越少。 这间接取决于生存时间:经过的时间越长,相关票证出现的机会就越高。 因此,早午餐的时间越短,我们在相关性上花费的精力就越少。


有待了解如何在产品上推出部分功能。 答案很简单:用户不应访问它。 如果您想问为什么要这样做,可以返回上面的几段。


似乎将无效代码保留在向导中不是很好。 是的,但他还没有死。 您可以使用包含此类功能的笔制作一个秘密页面。 或一系列特殊的动作,例如游戏中的复活节彩蛋,将带您进入此功能。 此外,您可以立即对其进行测试。


当然,还有其他方法可以应对需求的变化。 而且这种方法有其局限性和使用条件。 如您所知,仍然没有灵丹妙药。

Source: https://habr.com/ru/post/zh-CN460883/


All Articles