驯服野兽:遗留代码,测试和您

旧版代码是“旧”代码,其年龄可以是2个月和10年。通常,开发人员曾对此进行过撰写,而公司对此却记忆犹新。也许它们根本不存在,并且遗留代码是在“大爆炸”期间与宇宙一起诞生的。从那时起,它的要求发生了许多次变化,以“昨天是必须的”模式对代码进行了更正,没有人像测试那样编写文档。旧版代码令人困惑且脆弱,它既不显示开头也不显示结尾。如何接近他?


以下是“瑞克和莫蒂”系列的镜头。贾斯汀·罗兰(Justin Royland)和丹·哈蒙(Dan Harmon)。

您需要接受测试,但要为痛苦做准备。从您决定进行此类项目的那一刻起,问题便已经开始。您需要了解为什么要执行它,说服管理层批准对遗留代码的测试,并为您的同事提供帮助。之后,出现问题,从哪里开始研究,首先进行哪些测试,以及如何不破坏所有内容?但是最主要的是,当您意识到工作无止境时,如何不陷入绝望。

Kirill Borisov在行业中工作了12年,多年来,他在拐杖,破坏代码和破坏旧系统方面已经走了很长一段路:从整体会计系统到授权微服务。这次旅程给了他丰富的经验和故事,他将以有价值的建议的形式分享。


我有一个梦想-有一天要从事一个新项目。从一开始,一切都会好起来,就像第一场雪一样新鲜:测试,架构和含义。但这只是一个梦想,因为十年来我一直在出售自己的才华以赚钱,并从一个遗留项目转移到另一个遗留项目。

在这段时间里,我别无所求,但我可以通过分享与旧版互动的经验来拯救您。我将告诉您如何驯服野兽(旧版代码):与代码和人员一起工作,实施测试,是否需要完成测试以及开发人员如何与此相关。

什么不会在这里:

  • 编写测试的技巧。许多书籍,文章和各种视频都涵盖了这个问题。
  • 讨论方法论。BDD,TDD,ATDD-全部由您决定。
  • 所有可能违反NDA的行为。人们的记忆力很长,律师的武器很长。

什么是遗留代码


有很多定义。我相信这是2个月到10年的“ 相当古老 ”的代码。遗留代码混乱而脆弱,但就像一条巨蛇吞噬了它的尾巴。

这是不允许您从容进行测试的原因。所有开发人员,从初学者到经验丰富的开发人员,在来到一个旧项目时,都要抓住一连串的测试,然后急于杀死这个怪物。长矛断裂,随之而来的人。结果,仍然有一个没有生命迹象的开发人员,他已经在一个旧项目上工作了数十年。

有可能克服这种野兽吗?是的,但是需要准备。

训练


与野兽搏斗并不像准备阶段那么重要。它从三个问题开始。



“我为什么要这样做?” 说真的,为什么?毕竟,只有两个选择。

  • , , , .
  • , .

您想为别人的舒适或自己的荣耀而工作吗?如果对于后者,那么随着第一个成功的兴趣消失,您将消失,一切都会消失。您将切换到其他位置,并且工作的烂点将在很长一段时间内阻塞该项目。

“我知道我在做什么吗?” 如果您编写测试,就会知道。如果不是这样,那么在您着手研究怪物之前,请掌握以下基本知识:编写3-4个测试,覆盖一小部分代码,充实您的手并感受到力量。

“我有时间吗?” 很好地干预并改进代码,为将来而努力,这是很棒的。但是,当现在燃烧时,也许没有时间这样做了。如果是这样,那么该项目需要您,而不是未来的光明前景。

当您回答所有问题时,请继续执行下一步。

侦察


检查项目的结构您对项目的结构,组件和工作原理有想法吗?当然可以,但也许与现实不符。在开始工作之前,了解您必须面对的问题非常重要。花一些时间来完成该项目并进行深入研究。

制作一个依赖图没有一个项目可以生存。数据库,外部服务,库-所有这些都可以在项目中使用。

对你做了什么?您可能不是第一个与野兽战斗的人。检查被烧毁并离开该项目的“祖先”的做法。

侦察之后,我们继续进行敌对行动。

与组织斗争


第一轮是与您的组织的斗争。最主要的是您的经理,直接上司。

经理。他并不像看起来那样可怕。这是一个有普通需求的普通人:准时交付项目而没有不必要的问题,为此获得金钱和奖金,然后继续生活。

领导者并不反对你的事业。他反对您大声疾呼前往该项目:“测试!测试!测试!”如果您这样做,他会将您视为花费时间并放慢其余时间的人。

展示收益。经理讲善,省,时的语言。理解它们是由按时关闭项目并以更少的资源获得更多结果的愿望所驱动。

不应这样提交测试:

-哦,太棒了!

我们的想法应按如下方式推广:

-在最后一个季度,我们有50起崩溃可以在产品开发阶段修复。您可以使用测试来修复它。如果我们不期望,他们将确认所做的更改没有更改功能。我们将节省解决这些问题所花费的时间,并减少因系统故障而造成的罚款。

说“优化,节省金钱,节省时间”,您就是在说经理的语言。当他听到这些话时,就被这个主意深深吸引。他认为您不是下一个对新鲜技术充满热情的疯狂程序员,而是一个对改进产品感兴趣的人。他不会一次批准您的所有想法,但是他很可能会提出概念证明。

概念验证增加了机会。为经理提供单独的隔离代码段,该子系统包含测试,启动和运行。如果您以某个频率弹出一个严重的漏洞,并尝试通过测试捕获并修复它,就可以做到这一点。 PoC将确认您的意图,表明您有计划并且您的工作会带来结果。

不要承诺太多。对于管理者而言,数字很重要:结果是什么,时间安排是由什么决定的?但是管理者是一个贪图结果的生物。从一开始就不要承诺太多。如果您承诺立即解决所有问题,经理将与此相关。当局会说:“太好了!”,但是它将减少资金投入并缩短期限,希望我们能更早地移交该系统。

当我们与经理达成协议时,我们求助于每天与之共事的人。

同事


他们不喜欢改变。一个典型的遗留项目的典型同事是一个对生活和未来失去信心的人。他不愿改变,而对命运屈服:“我永远在这里,没有办法摆脱沼泽。”问题是您开始在沼泽中搅动水。您要求他编写并运行一些测试,但是他想完成工作,完成任务并回家。



让您的同事受益—解释为什么他们会感觉更好。例如,他们不断花费时间和精力,下班后剩下的时间用来修复一些错误。按下它:“如果您没有为生产部署已损坏的代码,则无需花费时间来修复它。我们将编写测试,我们将捕获这样的代码,它的中断时间会更少。”

表现出耐心和同情心。您与人沟通-问为什么他们担心您的想法?建议找到一个相互理解的共同点。这是与人打交道的主要策略:不要吵架,不要撞到额头,要友善。

在下一次团队站立会议的同事开会之前,可能会阻止您提出想法。 “小组思考”的机制在团队中起作用:没有人愿意做出决定,每个人都互相看,没有人热情洋溢。

解决这个问题有一个卑鄙的把戏。不幸的是,我一生中不止一次使用它。

分而治之。在午餐或拐角处去找一位同事说:“整个团队已经签约了,您是唯一拖慢进度的人。也许我们可以找到一种通用语言?”

依次进行所有操作后,您就对所有人签名。每个人都会以为自己以为其他人都已经注册了,感到羞愧。这是不光彩和可怕的,但是有效。负责任地使用此技术,并且是不得已的方法。记住-您仍然必须与这些人一起工作。

当我们和同事一起整理时,我们正在等待另一只贪婪的野兽。

与车打架


这就是称为产品的代码的窍门。让我们从基础开始。

拆除垃圾。有必要进行测试,以使对系统的影响最小,从而获得可验证的结果。但是任何遗留系统都充满了数据:自启动以来已经添加了许多年,并且会影响系统的行为。因此,有必要“从头开始”进行测试。

准备一个“真空中的球形系统”:清空数据源,进行系统启动时的最低配置,禁用所有可能的“ hacks”和“ features”。使系统启动。如果启动,则您具有运行所需的最小数据集。这已经是一个很好的起点-“干净的板岩”。

使用一些可测量的效果,例如,按下某个按钮,您将获得可测量的工作结果。这样,您可以继续下一步。

解开数据。任何遗留项目均基于“必须在昨天交付”的原则进行工作。您上大学或读过的书在这里都不起作用。当您开始测试时,您将遇到,例如,循环依赖关系,该循环依赖关系无法在程序中重新创建,但对于运行而言是必需的。

从“主要对象”开始。要处理依赖林,请尝试考虑哪个对象是主要对象。例如,对于仓库会计系统,主要对象是“盒子”。 “货架”对象与之关联,“行”对象与“货架”关联。

重新创建所需的最小值。如果查看对象之间的链接并更深入地研究依赖关系树,则可以确定依赖对象的必要最小数据量。您需要重新创建它,以便系统正常运行并可以测试您的功能。

不要害怕更改链接。您可能需要袖手旁观,深入探究这一混乱局面:删除和更改链接,更改数据库的结构。您是来改进系统的,所以不要害怕进行更改。

我们通过测试。对于混淆的旧产品,好的方法是进行烟雾测试。

烟雾测试


“烟雾测试”的概念来自电子世界。一位工程师用一堆灯泡和电线组装了一个巨型电路。但是在开始测试之前,我只是将电路插入电源插座。如果开始冒烟,则出了点问题。

在信息系统中,烟雾测试的概念非常简单。想象一个Web服务,它有一个端点。让我们尝试向他发送不带参数的GET请求。如果由于某种原因产品突然破裂(错误500),则出问题了。

烟雾测试是一个好的开始。这是一项测试,测试某些功能并清楚表明系统正在运行或损坏。即使是对最简单端点的简单请求,也已经影响了超过1%的代码。通过如此小的测试,我们正在准备进一步测试的跳板。

烟雾测试发现许多问题。在整个服务运行期间,可能没有人会猜测要发送没有参数的请求。

使用此策略可以涵盖程序中的几个主要入口点:登录/密码输入表单,基本的Web服务,按钮。您已经可以向经理和同事展示此内容。

功能测试


这些不是对单个类或方法的测试,而是对功能的某些部分进行的最高测试。

想象一下“在服务中生成报告”的功能。我们无需检查各个部分,而是测试请求的情况以创建具有某些参数的报告并获取数据文件。不必知道生成报告的机制,但是,如果服务将某些输出数据与某些输入数据一起提供,则此黑盒具有一定的概率就可以正常工作。

此类测试涵盖了主要功能,可让您快速启动并立即覆盖大范围。您将确保该代码至少能够像您想象的那样正常工作,获得更大的信心,充满手腕并发现更多问题。
功能测试是一种手段,而不是目的。
很容易迷上功能测试针:“我正在测试真正的功能!这就是用户所面对的。”

功能测试涉及可以与大量数据交互的大量代码。因此,3-4项功能测试是好的,而10项则更糟,而数千项耗时9小时的测试则太多了。不幸的是,这也会发生。

功能测试后,进行单元测试。但我不会谈论它们-您已经了解所有信息。

我们介绍了机器测试的基础知识,并返回了主要主题。在与遗产的斗争中,同事和经理并不是最大的敌人。最大的敌人是你自己。

与自己战斗


为道路似乎永无止境做好准备。在您的计划中,一周的工作将花费六个月,而没有完成项目的希望。



抵抗是不可避免的。所有盟友最终都会开始怀疑,试图脱离轨道,说服他们退出测试并继续发展。为此做好准备。提醒每个人为什么要参与所有这些工作,花费了多少精力和时间。论点薄弱,但可能有效。

没有人能保证成功。即使您表现出英勇的努力,将自己全都投入工作,您的项目仍然可能会枯竭,而进行测试的十字军将一无所获。

这很正常,这不是生命和职业的终结。这甚至不能证明您是一个糟糕的专业人士。唯一的结论是,这个特定项目失败了。

但是,那么您就有经验和知识。下次,当您手里拿着一头新长矛,而马又加速到另一台风车时,您也准备好将这头长矛折断,但是以后,可以采用另一种方法,并且损失较小。

现在令人反感,痛苦和永恒。

分词


不要害怕反馈。我不得不走进这个陷阱,看看其他人是如何陷入陷阱的。我做了一些事情,并引起了同事的夸奖:“我做到了!”但是突然发现我的便利机制对同事来说很不方便,我没有问。

编写测试,尝试实现。通常引入新的测试框架会很有趣,但是您不必自己编写测试。然后可能发生的情况是,一旦编写它们,您将了解您无法使用测试。也许同事也看到了这一点,但保持沉默,或者干脆不编写测试。

帮助有问题的同事即使他们不要求帮助并不意味着全力以赴,它可以减轻同事的负担,减轻他们的责任,“公共汽车”的数目下降到统一,然后您就可以成为测试人员:有些东西破了,CI红色,测试指南。在合理的框架内提供帮助。

“公共汽车”号码不是一个玩笑。您不能总是将项目拖到自己身上。每个人都可能会精疲力尽,休假或辞职。因此,将您的知识和责任传递给您的同事,这对于没有您的情况是必要的。当您在海滩上放松时,这将有助于避免不愉快的通话,并且CI再次变为红色。

完善测试机制可以避免许多问题,因为缓慢的测试突然变得很快。以前,他们占用20行代码,但现在只占用一行。您没有注意到这一点,因为一旦您写了一些东西就忘记了:“它有效-请勿触摸!” 但是此规则并不总是适用。

您不是宇宙的中心。我再次重申,“公共汽车”号码不是一个玩笑。我不止一次遇到一个人开始测试,然后重新接受该项目的提议的情况:他留下了一切,逃走了,但没有留下评论和文档。一切工作到新提交为止,但无法修复-没有人知道一切如何工作。

我不想你成为这个人。不要成为限制因素。

  • 编写文档。
  • 进行培训。
  • 分享您的经验。

当所有同事都与您处于同一水平(正负)时,过程将由一个人的比赛变为通过标志的团队接力比赛。只有在您同事的支持下,您才能成功。如果您一个人在项目上,请认为您之后的其他人也会一个人受苦。以文档的形式给您的跟随者一个朋友,不要让自己死亡。

27 Moscow Python Conf++ Python 2 Python 3 — 2020 .

, (fb, vk, twitter) telegram- . !

All Articles