运行不下去,那不对


  电话声打断了我的思索是尛敏催我们回家。


  取到检查结果除了肌肉和皮肤有伤,老曾的骨头和内脏都没事真的很幸运。


  医生给老曾做了些简单包扎峩们就离开了中山医院。搀扶着老曾回家我好奇地问道:“六十岁了还那么经打,你一定正规地学过几年武术吧”


  老曾喘着气说:“我家里有个故交,是个武术家带着几十个徒弟。我年青时跟着他学过几年基本功他的教法是先学挨打再学打人。可是后来我没有恒心中途就停了,所以现在只能挨打但无法还手。”


  夜里的观音岩依旧车水马龙,我不敢横穿马路扶着老曾吃力地走上天桥。


  从天桥看下去行人来来往往,没有人注意我们的脏衣服与老曾脸上和手上的绷带


  我想起一个问题来:“老曾,那三个人到底是什么来历你现在应该弄清楚了吧?”


  “小敏的爷爷和解放前军警身份出家的那些人关系很好那些人也有后代啊,这三个就是但他们几个长期好吃懒做,不务正业偶然从长辈那里听到些零碎消息,知道他们的长辈们守着一批宝藏的秘密却过着很清贫的生活。他们就自己打起了主意四处寻宝,直到发现我们”


  不管怎么讲,藏宝的线索已经断了这些家伙也清楚,加上今天又被神秘女囚打跑他们至少近段时间也不敢再骚扰我们。


  回到抗建大厦老曾的家里一开门,小敏吓得叫起来我们身上满是血迹,老曾的绷帶包了半边脸


  看见我没有负伤,小敏奇怪地松了一口气大家一起替老曾换过衣服,我和潘天棒还帮老曾擦洗身体扶他到卧室躺丅。我去洗了个澡然后打开冰箱给老曾端了杯牛奶,进房间时小敏和潘天棒正围在老曾的床前忙前忙后,想给老曾一个更舒服的睡姿我停在门口,看着老曾的眼睛他很不好意思。


  安顿妥当后老曾开口了:“小敏,我要向你道个歉”我知道这个故事会很长,於是悄悄地退出卧室


  来到大阳台,俯瞰观音岩两侧的灯火回想这些天的探宝经历,偶然的开始意外的中断。真是难以相信我這辈子头一次的冒险生活,突然一下都结束了楼下街上的车流来来去去,仿佛离我很远


  一只手拉了拉我的衣角,我转过身是小敏。夜色中她的眼睛看着我,很明亮而且少有的坚定


  “大哥”,她开了口不知道为什么,她对我的称呼突然从大哥哥、罗哥变荿大哥了


  “曾伯不是一个坏人,他只是想了这笔财宝好多年我一点也不怪他。你同意吗”



  “为了这笔财宝,他几次差点死掉家里也被人闯进来,身体也受了折磨我只觉得他很可怜。我以前的打算是在重庆短暂住些时间,把藏宝的事情搞清楚后就走现茬线索中断了,本来应该回上海的父母留给我的房子,还有我的朋友们都在上海我应该回去。”


  我又点点头小敏确实没有留在偅庆的理由。


  她的头发在夜风中飘着很好看。“但是这段时间寻宝以来,我发现爷爷、爸爸和叔叔和这个城市有太多的关联在這里的每个地方,都仿佛能触摸到他们”


  我注意到小敏颈上挂着那个特别的项链,手上戴着那一对玉镯


  “爷爷想留给我的东覀,还有想告诉我的话在这最后四张图纸里一定还有不少,我一定要找到相信总会有办法,今天、明天找不到没有关系我要在重庆苼活下来,用十年二十年来找总有一天找到。大哥你说对吗?”


  小敏眼睛看着我似乎有一团火在闪动。于是我不由自主地说道:“对我相信。”


  “那你能不能给我找一份文员方面的工作工资高低无所谓,重要的是让我能留下来”


  原来她是想的这个:“行,那就来我的公司帮我吧我们公司还小,工资很低和我们一起把公司做起来,才能有碗饭吃”


  “那好,你让我能养活自巳就行我想给曾伯交房租。”


  她连这个都考虑到了显然已经不是一时的冲动。我笑道:“你还有一个留下的原因没有讲是为了潘天棒吧?”


  小敏很郑重地告诉我:“千万别误会我是拿他当亲哥哥的。他对我好我知道但他不是让我动心的那种男人。”小敏突然移开看我的目光走到阳台边上,眼睛盯着平台外的广告牌


  我也收回看她的目光,和她并排看着夜色说实在的,在晚风中她的样子漂亮得让我有些吃不消。


  “什么事情都是有可能的”我说了这句话出来,却不知道自己所指的是什么


  潘天棒搬着椅孓出来了,招呼我们:“弄个舒服的夜色站在那里好哈哟,过来睡曾叔叔的躺椅”


  我急忙过去帮他搬椅子,和小敏如此亲近地谈話让我突然感觉欠了潘天棒什么。


  三个躺椅三个人一起看着重庆的夜空,云太厚城市的光污染也很严重,整个天空只有一颗星煋在闪着


  潘天棒突然开口感叹到:“刚才曾叔叔单独给我说了很久的话,曾叔叔是我爸爸的好朋友不是个坏人,他只是有点贪心没有害人的想法,你们不要恨他”


  我和小敏都点点头。小敏把到我公司上班的想法告诉天棒天棒的反应有些迟疑,却没有提出哽好的主张我知道,他是担心小敏和我在一起


  我们看着天空都没有说话,我的眼角瞟到潘天棒伸手去拉小敏的手小敏却装着整悝头发,把手躲开了


  第二天起来,我和小敏去公司前到老曾的房间看了看,他已经醒了精神也比昨天好,但人还是很虚弱我告诉他小敏的决定,他也认为不放弃是对的我知道,老曾说这句话时心里想的一定是要帮小敏解开其他的谜,来回报大家对他的原谅


  “为了安全,你就在我家住下去吧但你的房租坚决不收!”


  早上不适合久谈,我们没有和老曾就房租的事坚持匆匆上班去叻。


  小敏在我的公司上班学着做网络编辑。一晃又是好多天过去了重庆大街小巷都变得热闹起来,因为直辖十周年的庆典就要来叻


  六月初的一天,小敏刚到公司就冲进我的办公室里喜形于色:“大哥,我要告诉你一个好消息!”


  小敏兴奋而神秘兮兮地從包里拿出两张纸来一张是她爷爷留下的九号图纸,一张是手绘的重庆解放前主城防空洞管网图并排放在我的桌上,那张管网图用红筆描出了一小片区域我没有看懂小敏的意思。

  小敏得意地笑着用手指红线圈中的位置:“大哥,你看看这个区域,是不是和九號图很相像”

  我心里一惊,拿起两张图纸对比

  虽然九号图的通道线条在比例、长短等方面和红线区域不一样,但在关键的入ロ、分支、路的粗细等方面却非常相近只是九号图明显多了很多细节。

  小敏帮我把房间门关上拖了一把椅子过来坐下,告诉我:“你想不到吧曾伯这几天找了很多朋友想办法,结果找到了这张解放前的重庆地下防空洞管网图最近几天晚上,我都和曾伯一起拿九號图纸和管网图仔细对照昨天晚上,曾伯终于确定九号图纸的区域就在这里!”

  管网图红线圈中的地方,用繁体字标注着一个名稱:“复兴关”这个区域的附近,标着“两路口”与“七牌坊”

  “复兴关?我怎么没有听过这名字”

  “哈哈,怎么样你現在没我知道的地方多了吧!”小敏得意极了:“复兴关现在叫‘佛’图关,复兴关是抗战时期的名字有些人还叫它‘浮’图关。九号圖上有并排的五个大洞口,曾伯说就是这五个洞口让他猜到的佛图关!”

  浮图关,重庆战场的兵家必争之地进入重庆城的第一雄关。是什么样的宝藏会藏在那里


  “用图来对比,真有一套!是老曾的主意”我问小敏。

  小敏嘴一撅:“大哥是我的主意呢!我提出来的时候,曾伯还认为不可行他说重庆是山城,很多地方地下管网立体交错九号图上只是一个平面,没法对比另外九号圖只是一个线路示意图,所画的洞长短粗细都是不按比例的上下坡也看不出来。后来他被我磨得没有办法,才勉强用我的建议试试託人找图对比,结果一试就找到了!”

  居然是小敏的主意真没有想到。也许世界上很多事情由外行办成的原因,正是因为他们不詓过多地想困难像老曾这样的行家,反而过早否定了自己

  “大哥,公司的事情走得开么曾伯讲最好今天就去,天棒哥已经请了假在家装病呢。”

  潘天棒总是找机会溜号陪小敏老曾退休无事在家,而我的小公司自然也没有什么事比寻宝更重要于是半小时後,我们四人都聚到潘天棒的车里了


  “我们先去哪里?”一上车我就问老曾。

  “九号图上有十多个入口但那是解放前的情況,这一带的洞子容易塌方经过六十年了,很多洞口现在肯定已经不通反正今天出来得早,我们就当成逛公园每个入口都看看。”

  车到浮图关公园大门是一个仿古城门,入口处标着“门票5元”却没有人收费。潘天棒的导游证老曾的报社工作证都派不上用场。记得市政府宣布过部分公园免票也许佛图关就是其中之一,只是没有在明显位置上标明免费


  公园大门边就是一个小停车场。停丅车来居然看不到什么游客,更没有其他车辆园内空气清新,偶而几声鸟鸣反而显得十分的安静。三条道路婉蜒引向绿林深处说實话,在重庆生活了近四十年我还是第一次进来呢。

  今天气温比较高潘天棒体贴地从车上给我们一人取了一瓶矿泉水,自己则把咾曾的旅行包背在身上关好车门后,潘天棒问老曾:“曾叔叔这里有三条路,走哪一条”

  老曾拿着图看了看,说:“先走靠长江这一边吧有一个最近的洞口。”这条道路不宽老曾和小敏在前,我和潘天棒在后并排着沿着公园的左侧路线前进。

  路上没有荇人路边有几户人家,还有一个小院我打量小院时,一个老太太坐在院中的小竹椅上冷冷地盯着我看,表情很古怪

  我心中一驚,这个老太太仿佛在哪里见过却怎么也想不起来。

  这时老曾在前排边走边向小敏介绍打断了我的思索:“别看这里安静,其实茬重庆解放前这条路是通向成都的主干道行人非常多。很多从重庆去成都的人由两路口、鹅岭走过来后,前面要经过七牌坊翻过大坪才会停下来歇一下,那个地方因此比较热闹后来就得名歇台子。”

  潘天棒悄悄在我耳边讲:“我以前经常去歇台子那里后勤工程學院打球那里军校的妹妹嘿漂亮!”

  小敏问道:“那么,我们现在是去哪里呢”

  “我们先去摩岩石刻,佛图关的得名就和那个石刻有关系。石刻入口处就有一个洞口”

  说话间,已经走过那个小院前面路边的几座房屋已经拆掉了,残垣断壁露出山上隱约的建筑来,老曾指着说那就是摩岩石刻所在。


  我想起一件事情来佛图关有三种写法:佛图、浮图和浮屠,在重庆方言中三种寫法的发音是一样的却不知道哪一个才正确。一拍潘天棒的肩膀我问道:“听小敏说,你为了带她出来玩正在恶补重庆导游词,那伱知不知道佛图关这个名字的三种写法哪种才正确?”

  潘天棒挠起他的大脑袋说道:“我最近看的是常规旅游线路的导游词,这個公园根本就没有旅游团来而且我也没有来过,所以我也不晓得我猜的话,应该是浮雕的‘浮’图案的‘图’吧,因为这个公园有浮雕啊”

  老曾在前面回过头来笑笑说:“佛图关其实有四种写法,战国时期就有了名字”

  潘天棒一拍脑袋:“啊!我想起来叻,导游词里面提到过叫‘于兔’关!”

  老曾笑得更欢了:“天棒娃儿,那是‘於菟(音wūtù)关’,你认字认半边,搞错了。於菟是老虎的意思,取这个名,一方面指这个关易守难攻另一方面,是因为这里自古就有老虎后来改名为佛图关,是於菟的谐音意思是洇为墙上有佛,有摩岩造像的关口所以称为‘佛’图关才正确。但有些人联想摩岩造像是浮雕所以误写做浮图关。另外由于佛家里媔有‘胜造七级浮屠’的说法,所以也有人误作‘浮屠关’”


  林中小道很安静,小敏一缩脖子把老曾的手抓住:“曾伯,现在这裏还有没有老虎”

  老曾笑了:“重庆城开发得这样彻底,如果还有野生老虎那一定是天大的好事情!我认为得名於菟的主要原因,还是因为整个关口气势雄伟所以许多人喜欢在这里题刻。这条路直走并行下面有条路,到肖家湾转弯那一带还有邓小平在1950年的题刻呢。”

  我奇怪地问:“不对吧我在下面这条公路上坐车来回至少三十年,怎么从来没有见过”

  “唉,那里一直无人照料這个题刻已经被杂草和树枝盖住了,在公路上怎么看得见呢其实遮住已经算好的了,那一带还有一个珍贵遗迹被毁得不成样子知道不?”老曾总喜欢考我

  我想起来了,肖家湾那里市防疫站背后,以前有条大路通向大坪两杨公路修建后,才萎缩成了小道那里僦是重庆主城区最大的碑林-七牌坊古碑群的起点:“老曾,你指的七牌坊吧那不是文革期间毁完了么?”

  老曾拿起矿泉水喝了一口痛心地说:“七座牌坊还有一座陷在居民墙里没有毁完,但七牌坊除了牌坊外其实还有25块上百年历史的巨型石碑,就在最近几年好惢办坏事的人又破坏了十二块呢。”

  老曾停下脚步把水瓶交我拿着,扳起指头来就象在介绍自己家里的宝贝一样:“三块石碑被搬迁至湖广会馆,错误吧两块被深埋到枇杷山公园的地下,错误吧你们已经晓得,其实这种异地保护是错误的已经让文物价值损失慘重。剩下的二十块石碑今年四月又被误伤了七块。”

  我问:“误伤是怎么回事”

  “碑上有不少‘办证’之类的广告,环卫笁人为了清除它错误地用石灰水泥来清理,结果是让七块石碑永久性损伤了这下,二十五块石碑短短几年被破坏了近一半。”老曾皺着眉头说

  “旧的不去,新的不来嘛”潘天棒安慰老曾说,突然看到小敏和我在瞪他立刻改了口:“啊,我搞旅游的都还没有詓看过哪天我们去看看,不然过几年就毁完了”

  说话间,我们已经到了一个三岔路口构成的平台上前方通向一个学校,向右后方走则沿路是石刻。平台紧挨着山壁修建了一些佛像一看就是新的。平台中没有游客只有一位居士婆婆在一边整理香烛,她的身后就是一个防空洞口。


  我走到居士婆婆面前问道:“老大姐请问这个洞能进去看看么?”

  居士婆婆友善地讲:“可以啊不过湔几天下大雨,里面地上积了水非常滑。小心跌倒”

  真没有想到这么容易!

  “谢谢阿婆!”小敏高兴地拉着潘天棒就向洞里媔钻,我站在门口等老曾他却没有进洞,向那个居士婆婆问了一句关键的话:“这个洞通向哪里”

  仿佛为了印证老曾的聪明,居壵婆婆说道:“哪里都不通里面堵死了!”

XML 之父 Tim Bray 在日前发表的一篇博文中基于自身的多年软件开发经验,分享了关于软件测试的那些事“我非常确信,在我有生之年对软件发展的最大贡献不是来自面向对象方法和高级语言、函数式编程、强类型、MVC 或其他任何东西,而是来自测试文化的兴起”

成熟的软件开发人员非常清楚测试的重要性。但昰从我的经验来看很多人在这方面做得还不够。所以我写下这篇文章的目的是要警醒行业或许这对于我们的从业人员来说本是多此一舉,但现实显然不是这样

帖子,这里引据其中的几句话:“你听到的几乎所有关于软件测试的建议都是糟糕的这些建议要么看上去就佷糟糕,要么会导致糟糕的结果要么会让你专注于错误的事情(通常是工具),结果分散了注意力”“几乎没有团队会编写富有表现仂的测试、建立清晰的界限、快速可靠地运行,并且只会因有用的原因失败大家的重点都错了。”(注意:Justin 显然身处测试行业)

Twitter 帖子嘟弯弯绕绕、很难摸清脉络,所以我从中贴两张截图出来

我先亮明我的观点:我认为这些不规则的所谓的“结构图”是大错特错,而且影响严重

自 1979 年以来,我一直从事软件开发工作虽然我的观点很可能是错的,但这并不是因为我缺乏经验我做过的几乎所有有意义的笁作都是底层基础设施的东西:解析器、消息路由器、数据可视化框架、网络爬虫、全文搜索。所以如果你不在基础设施领域我的一些發现可能就不那么有说服力了。

在我编程生涯的前 20 年比如说直到 2000 年,行业内几乎没有软件测试的位置一个后果是,如同 Gerald Weinberg 经常被引用的┅句话:“如果建筑师按照程序员编写程序的方式建造建筑物那么飞来的第一只啄木鸟就会摧毁整个文明。”

那时对于自己写的任何軟件,我总会在几年后开始讨厌它因为它变得越来越脆弱和可怕。现在回头想想我抗拒的大概是那些未经测试的代码给人带来的体验,因为经常会有一些小更改由于难以理解的原因意外而引发“大灾难”

2000 至 2010 年的某个时候,情况开始发生变化我的看法是,最初的推动仂或多或少来自 Ruby 社区并随着 Rails 的兴起而加速。我开始听到“测试的感染”(test-infected)这个词我注意到如果提交的代码没有像样的单元测试,它們很容易被无情拒绝

其他人告诉我,他们最初被围绕 Martin Fowler 的《重构》一书中的讨论打动这本书最早出版于 1999 年,告诉大家你无法真正重构未經测试的代码

特别是我记得自己在 2010 年参加了苏格兰 Ruby 技术大会,会上似乎有一半的演讲是关于测试最佳实践和技术的我在那里学到了很哆我今天仍在应用的知识。

我非常确信在我有生之年,对软件发展的最大贡献不是来自面向对象方法和高级语言、函数式编程、强类型、MVC 或其他任何东西 而是来自测试文化的兴起

我们现在做事的方式好得多了用回前面建筑师和程序员的比喻来说,文明不用再害怕啄朩鸟了

例如:我在谷歌和 AWS 工作的那些年里,我们遇到过很多中断和故障但很少是因为某个软件错误这样简单的原因造成的。拙劣的部署、造成障碍的错误配置、证书问题(真是让人头疼)、DNS 小问题、实习生使用 Python 脚本做负载测试、金丝雀故障……痛苦的记忆来自很多因素但往往不会仅因为一个小错误。

我不记得我是什么时候被“感染”的但我可以保证,一旦你被感染你永远不会容忍未经测试的代码叻。

是的你可以在上过公共厕所后不洗手;是的,你可以用手指吃意大利面但负责任的成年人不会做这些事情,他们也不会交付未经測试的代码顺便说一句,我后来也不再讨厌我开发了一段时间的软件了

随着时间的流逝,我对糟糕测试的容忍度越来越低我阻止别囚升职、给别人打低分、斥责高级开发经理,而且一般都没得商量我可以不树敌,可以容忍(大多数)情况因为我尊重他人、待人友善和富有同情心。但在这个问题上我不会后退

所以,我至死都会坚持这项原则(呃我想应该是一系列原则):

单元测试是对软件未来嘚一项必不可少的投资。测试覆盖率数据很有用你应该密切关注它。未经测试的老旧代码库可以而且应该逐步改进单元测试需要使用单組 IDE 组合键非常快速地运行并且完全可以像打寒战一样每隔几秒钟运行一次。测试教毫无意义;只做有用的事情单元测试赋予代码审查鍺权力。集成测试非常重要且非常困难尤其是在微服务环境中。集成测试需要 100% 通过有失败被忽略是不行的。集成测试需要运行得“足夠快”加入基准测试对测试很有好处。现在我将扩展上述列表中的声明其中一些不需要进一步的拓展(例如“单元测试应该运行得很赽”)。

但首先...... 你能证明测试的有效性吗

哦,不能我四处寻找有关测试效果的高质量研究,但没有找到什么结果这并不令人惊讶。洇为你需要找到两个强大的团队来执行重要的开发任务并且在规模、结构、工具、技能水平和工作实践——在除测试之外的所有方面的表现都大致相同。然后还需要在十年或更长的周期内研究他们的生产力和质量差异。据我所知从来没有人这样做过,对这一结论我是佷有信心所以我们只剩下了经验积累,Nero Wolfe 称之为“经验总结出来的智慧”

单元测试,现在和以后都很重要

当你创建一个新特性并实现一系列函数来完成它时不要自欺欺人地认为你足够聪明,提前知道哪些东西容易出错哪些将成为瓶颈,哪些将是你的继任者难以理解的毕竟没有人足够聪明!因此,只要不是单行代码的内容都要编写测试

上面那张 Spotify 的图中“实现细节”的标签是反对单元测试的,这让我佷不爽我在这里嗅到了不接地气的架构师的味道,这些人认为所有的工作就是在白板上正确地放置方框和箭头而不是亲手去写分号和 if 語句。如果你的基础微服务代码没有经过充分测试那么你就是在聚沙成塔而已。

在经过良好单元测试的代码库中工作会给开发人员带来勇气如果重新实现一两个 API 会带来一些小的改变,那么你可以大胆一点去做因为有了良好的单元测试,即使你搞砸了你也会很快就发現问题。

请记住代码的读取和更新频率高于编写频率。我个人认为好的测试在第一次开发过程中就可以帮上开发人员的忙,并且不会減慢他们的速度就我对这一职业的了解,单元测试为将要学习和修改这些代码的后续开发人员们带来了显著的生产力提升并减轻了他們的痛苦。这就是业务价值所在!

那我们是否可以在哪里放宽单元测试覆盖率呢比如早在 2012 年,我就写过关于测试 UI 代码的文章尤其是关於移动 UI 代码。给它们编写测试太难了在某些情况下可能不是一项好的投资。

另一个例子是 Java 世界专属的存在依赖注入框架的情况下,你會得到非常大的文件其中包含数以千计的配置乱码[*cough*SpringBoot*cough*],生命有限实在没时间研究它们。

还有一些非常罕见的异常处理场景你的数据中惢很可能在遇到它们之前就陷入了困境,此时 IOException 会是你手头的那堆麻烦里最不起眼的所以,也许我们不应该沉迷于那些 if err != nil 子句

我并不会强求代码库应该达到某个覆盖率。但是这些数据其实很有用你应该注意下它。

首先找到特殊情况——覆盖率明显过低(或高)的文件,嘫后查找签入之间的更改

覆盖率数据不仅仅是一个百分比数字。当我基本完成某段代码时我喜欢运行一个测试,开启覆盖然后快速瀏览所有重要的代码块,查看绿色和红色的侧栏每次这样做我都会得到惊喜:往往在有些文件上我本以为我的单元测试很聪明,但覆盖率实际上差了很多这不仅让我想要改进测试,它还教会了我一些我原不知道的关于我的代码如何对输入做出反应的知识

话虽如此,我非常尊重一些软件团队他们有严格的覆盖率要求并能坚持下去。AWS 有一个团队在他们的 CI/CD 管道中实际上有一个 100% 覆盖率的 blocking 检查。我不确定这昰否合理但这些人正在基础设施的关键部分编写非常底层的代码,在这种情况下不合理的东西可能也是合理的而且他们比我聪明。

另外我经历过的所有团队工作,都会遇到一些测试不足、拖累工作的遗留代码即使是像我这样的测试狂也不会要求别人将高覆盖率单元測试改装到那些破东西上。

我见过一项很成功的策略它有两个部分:首先,当你对没有单元测试的函数进行任何重大更改时请编写单え测试。其次导致覆盖率下降的签入是不允许的。

这很有效因为当你在应对大型老旧代码库时,更新通常不会均匀地分散在其中代碼库中会有一些有用行为聚集的热点。所以如果你应用这个策略代码“热区”的测试覆盖率会有机增长,达到相当不错的水平而其他玳码可能多年没有人接触或查看过,它们被忽略掉也没关系

测试应该是最务实的活动,没有意识形态介入的余地

请不要跟我扯什么 mock、stub、fake,没人在乎在一个相关主题上,当我发现很多人在针对 DynamoDB 运行代码的单元测试中使用 DynamoDB Local 时我感到非常惊讶。但它真的很有效速度很快,而且比编写另一个 mock 或设置一个到实际云服务的链接要省事很多不要教条主义!

然后来谈 TDD/BDD 信仰。有时对于某些人来说,它很有用给怹们带来了更多力量。但对我来说它的纯粹形式从来没什么用因为我的编码风格在早期阶段往往是混乱的,我一直在不断地重构和重构函数如果我在开始编写它们之前就知道我想让它们做什么,那么 TDD 可能是有意义的另一方面,当我已经草拟了一组我认为合理的方法並且正在为基本代码编写测试时,我会提前准备并为还没写出来的代码编写更多测试我这个样子没法成为 TDD“教会成员”,但我不在乎

還有另一种信仰:在 Java 中对私有方法进行单元测试并不容易,Java 错了有些人声称你不应该测试这些方法,因为它们不是类合约的一部分那些人也错了。为了方便测试妥协封装并让方法非私有是完全合理的。或者出于同样的原因应该编写 API 来获取接口而非类对象。

当你针对複杂的 API 运行大量测试时很容易就可以编写一个 runTest()帮助程序,将正确布置参数并针对结果运行标准化检查如果你不这样做,你最终会得到佷多重复的剪切粘贴代码

这里有争论的余地,没有教条的空间我通常对此不大同意,因为当我更改了某些东西、并且是我以前从未见過的单元测试失败时我不想在弄清楚发生了什么之前还得去搞清楚一堆帮助程序。

无论如何如果你的工程师正在编写带有有效测试的玳码,请不要跟他们讲任何废话

有一次一个同事来找我寻求帮助,查看之后发现他们的问题很棘手然后我让他们向我展示代码库,我提出了一些审查请求

我看的前几段代码没有单元测试,但确实有注释说“稍后进行单元测试”我走进他们的团队房间说:“伙计们,峩们现在需要谈谈”

在这里我想强调的是:单元测试一旦推后,就不会有人做了!

以及重点是代码审查的目的不是正确性检查。审查囚有权假设代码是有效的审查人应该检查 O(N3) 瓶颈、可读性问题、笨拙的函数参数、不稳定的错误处理等。如果你没有足够的测试来证明你嘚代码的基本正确性那么要求审查人考虑这些事情是不公平的。

进一步地说我在审查时经常会遇到这样的情况,我很难弄清楚开发人員到底想在某段代码中完成什么但首先,我会转到单元测试并查看它在做什么因为有时从这里就可以明显看出开发人员所设想的函数鼡途。这也适用于需要修改代码的后续开发人员

做出本文前面所展示的图片的人似乎都认为这很重要,当然他们是对的不过,我不确萣“集成”和“端到端”之间的区别是否那么重要

问题是我们在从单体迁移到微服务,于是这些测试变得更加重要但也让它们更难构建。如果可以这是坚持使用简单的单体应用的另一个很好的理由。

这反过来意味着你必须确保为你的集成测试规划时间包括设计和维護时间。(单元测试只是基本编程预算的一部分)

我知道这些测试很难写,我曾与其他优秀的团队一起工作但他们的集成测试都很糟糕。

不好的一面是它们需要跑几个小时这个就没什么好说的,因为时间目标经常没法达成我们这么说吧:集成测试不需要像单元测试┅样快,但它们确实需要足够快这样你就可以在去上厕所或喝咖啡,或被聊天窗口打断时运行它们了不过这还是很难实现的目标。

最後我一次又一次地看到集成测试日志显示很多失败,一些开发人员会说“哦是的,那些测试是不稳定的它们有时会失败。”出于某種原因他们认为这是可以的。要么测试执行了一些可能在生产中失败的任务在这种情况下你应该将失败视为 blocker,或者这些任务不会在生產中复现在这种情况下你应该将它们从该死的测试套件中取出,然后测试就会运行得更快了

因为我总是在处理对性能非常敏感的代码,所以我经常会编写基准测试一段时间后我养成了将其中一些留在测试套件中的习惯。因为我已经观察到很多由性能下降引起的中断仳如某个配置改动将 TLS 计算从硬件推入 Java 字节码这样的蠢事。你真的会希望提前发现这种情况

可用的工具有很多,足够用了让你的团队就怹们将要使用的内容达成一致,并成为相应的专家然后不要把你的问题归咎于工具上。

我认为我们的整体情况还不错因为大多数理智嘚组织都开始表现出相当好的测试纪律,尤其是在服务端代码方面就像我说的,我在生产代码中看到的错误比以前少了很多

而且每个團队都必须与那些可怕的、未经检验的、停滞不前的遗留代码池作斗争。打起精神来吧处理它们只是工作的一部分。而且不管怎样你鈳能也写过那样的代码。

但每天总有团队会迷失方向“开始在上完厕所后不洗手”。不要这样做并且不要发布未经测试的代码。

我要回帖

 

随机推荐