Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >测试代码的坏味道

测试代码的坏味道

作者头像
Phodal
发布于 2020-01-16 03:19:25
发布于 2020-01-16 03:19:25
1.6K00
代码可运行
举报
文章被收录于专栏:phodalphodal
运行总次数:0
代码可运行

测试代码才能真正体现开发人员的水平。

追求技术卓越是采用敏捷的第一成功要素。—— Jeff Sutherland 敏捷宣言创始人之一

  • Phodal: “你为什么写测试?”
  • 开发人员 A:“为了测试覆盖率”。
  • Phodal:“咦,这个测试没有断言”
  • 开发人员 A 笑了笑。

某次代码重构中,我发现代码的测试覆盖率很高,过程中出了一些错误,重构手法不正确是一个问题。但是在重构的过程中,发现有些测试都是没有意义的,所以我变转向开始研究测试坏味道,顺便在 Coca 中写了个识别代码测试坏味道的工具。

测试反应开发人员的水平

与编写业务代码相比,测试代码才能真正体现开发人员的水平。你可以用测试来判断开发人员的水平:

  • 有没有为自己的代码编写测试?
  • 测试中有没有断言?
  • 测试中有没有包含有效的断言?
  • 测试的长度是否正常?
  • 测试中的断言是否合理?

没有断言的测试意味着原本的代码写得又臭又长;测试中只包含无效断言表明开发人员在划水;测试方法的长度过长,表明原有的方法可以进一步抽象……

顺便一提,我们推荐的 TDD(测试驱动开发),它并非是银弹。但是,当你来面对一个复杂的场景时,它可以驱动出可测试的代码,辅助以重构,能帮助你写出短小的函数。借此整体上降低整一部分代码的开发 + 维护成本。

我知道你想说有人的很聪明,可以写出的代码足够的健壮。但是呢,这样的人存在吗?即使存在的话,需求是善变的,下一次接手代码的人能保证原有的功能是好的吗?

正视测试同正视 bug 一样

软件测试(英语:Software Testing),描述一种用来促进鉴定软件的正确性、完整性、安全性和质量的过程。换句话说,软件测试是一种实际输出与预期输出间的审核或者比较过程。

项目代码是日常接触最多的部门,我们会直面代码中的问题,也因此会重视它们。对于测试嘛,就呵呵了。但是,你们就这么忽略了测试的重要性。

我们编写测试是为了提升软件开发质量,一旦代码改出了问题,那么测试就会帮我们找出破坏了的原有功能。而不是在长长的软件测试反馈链之后,才发现:原来我们改出了 bug。

不过呢,当你的业务进度压力大的时候,没有时间编写测试,反而 bug 就更多了。

测试代码坏味道

代码坏味道是对应于系统中的更深层问题的表面指示。

我们一般谈论代码坏味道的时候,主体是项目代码,而测试代码坏味道则往往被人忽略了。测试代码能直观地反应出代码的设计问题,它们是 API 的使用方,它们是 API 的第一等使用方。

测试代码坏味道,是指单元测试代码中的不良编程实践(例如,测试用例的组织方式,实现方式以及彼此之间的交互方式),它们表明测试源代码中潜在的设计问题。

如 Robert C. Martin 在《代码整洁之道》所说的那样,好的测试应该是:

  • 快速(Fast),测试应该够快。
  • 独立(Indendent),测试应该相互独立。
  • 可重复(Repeatable),测试应当可在任何环境中通过。
  • 自足验证(Self-Validating),测试应该有布尔值输出。
  • 及时(Timely),测试应该及时编写。

要我说的话,它应该还有:

  • 同一人编写,测试应该由开发业务代码的编写。这样他/他们才知道自己代码写得烂。
  • 边界,测试直接不影响业务代码。这里指的主要是 private -> public 的行为,又或者是业务代码中包含测试代码,而非因为测试对原有代码重构。
  • 有效命名。测试信息应该体现在方法名上,表达某一个特定的需求。

测试代码应该遵循生产代码的质量标准。

命名在测试中也是一大难题,我们如可以采用 Roy Osherove(《单元测试的艺术》作者) 推荐的 UnitOfWork_StateUnderTest_ExpectedBehavior 命名法则。几个示例如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Public void Sum_NegativeNumberAs1stParam_ExceptionThrown()
Public void Sum_NegativeNumberAs2ndParam_ExceptionThrown ()
Public void Sum_simpleValues_Calculated ()

测试代码坏味道示例

先让我们来看看有哪些常见的测试坏味道:

  • 空的测试。测试是生成的,但是没有内容。
  • 忽略的测试。即测试被 Ignore
  • 没有断言的测试。为了测试覆盖率而出现的测试
  • 多余的 Println。调试时留下的讯息。
  • 多重断言。每个测试函数只应该测试一个概念。
  • ……。

然后,再来个 Examples。

这是 Arduino 代码中的 I18NTest.java 文件,先看看文件,再看看问题:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
 public void testAllLocales() {
 for (Language language : Languages.languages) {
 if (!language.getIsoCode().equals("")) {
 Locale locale = toLocale(language);
 ResourceBundle bundle = ResourceBundle.getBundle("processing.app.i18n.Resources", locale);
 if (locale.equals(bundle.getLocale())) {
 Collections.list(bundle.getKeys()).stream().map(bundle::getString).filter(key -> !key.contains("<html")).forEach(key -> {
 try {
 I18n.format(key);
 } catch (IllegalArgumentException e) {
 System.out.println(language);
 System.out.println(key);
 throw e;
 }
 });
 } else {
 System.out.println("Missing locale: " + locale);
 }
 }
 }
 }

问题有很多:

  • 没有断言
  • 多余的 print 函数
  • try...catch...
  • 糟糕的测试命名

这个测试的正确作法之一应该是:使用容器 collection 来过滤出正确的语言,最后对比长度是否正确。

再举个例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void testXmlSanitizer() {
 boolean valid = XmlSanitizer.isValid("Fritzbox");
 assertEquals("Fritzbox is valid", true, valid);
 System.out.println("Pure ASCII test - passed");

 valid = XmlSanitizer.isValid("Fritz Box");
 assertEquals("Spaces are valid", true, valid);
 System.out.println("Spaces test - passed");

 ...
}

这个测试用例违反了每个测试一个用例的原则。

坏味道检测工具

欢迎成为 Coca 的忠实用户,只需要运行 coca tbs,就可以识别出你的 Java 代码中的测试味道。如下是 Arduino 源码中的测试坏味道:

Coca 开源,不要钱,不要钱。对 Coca Pro 有兴趣的,可以和我们联系,哈哈哈哈。

结论

回到开头:《敏捷宣言》上的原文是,『坚持不懈地追求技术卓越和良好设计,敏捷能力由此增强』。只是对于工具、手法和模式的理解,何时去使用各种各样的技术,以及考虑产品、需求的意图,大抵就是技术卓越的体现。

相关资料:https://testsmells.github.io/index.html ,我从这个网站上获得了 Coca 项目所需要的大量用例代码。

Coca:https://github.com/phodal/coca

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 phodal 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
使用监控宝自动签到免费获取一年优酷会员
最近优酷与中国新歌声节目合作,在移动端展开了签到送会员的活动,只需连续签到90天即可免费领取优酷会员年卡。不过如果每天手动签到的话,非常容易发生漏签的情况,下面就告诉大家如何利用网站监控平台进行全自动签到,从而免费领取优酷会员。
reizhi
2022/09/26
8720
使用监控宝自动签到免费获取一年优酷会员
天翼云盘超级会员上线,云存储彻底告别免费时代?
近日天翼云盘超级会员服务上线,用户每月支付19元可享受5TB容量、上传下载加速等特权服务。几乎同一时间,腾讯微云宣布,从明年1月16日起,普通用户的免费存储容量缩小为10G,会员存储容量不变。这两家市
罗超频道
2018/04/27
7K0
天翼云盘超级会员上线,云存储彻底告别免费时代?
QQ又砍掉一个功能,你用过吗?
此前10月13日,QQ群“元老级”功能——“恢复QQ群”因业务调整被下线。这是腾讯公司提供的一项找回QQ联系人、QQ群的服务,向所有QQ用户免费开放。所有用户都可以申请恢复28天内解散、转让的群,该功能还可以帮助群主或管理员恢复28天内删除的群成员。
一行Java
2023/11/15
2510
QQ又砍掉一个功能,你用过吗?
“十元店”的大生意 ——QQ会员业务转型及深度运营
说起QQ秀当年的火爆,大多数80后都见识过。在10年前,互联网上可玩的东西不多,像QQ秀这样酷炫的东西自然吸引了大量用户,这算是“可视化的自我标识”带来的经济效益吧。想想吧,只要设计出虚拟的服饰、发型、配饰就可以持续地卖钱,几乎没有竞争对手,这样的生意可不好找。但就是这么好的生意也渐渐萎靡了,业务营收突然大幅下滑,在尝试加强运营推广之后,仍收效甚微,我们意识到这或许是转型的时刻了! 转型不简单,首先得把核心问题找出来。 显然,原有的卖“物品”付费模式令用户倾向于购买更加“靠谱”和人气物品。于是,购买最多的物
腾讯大讲堂
2018/02/11
1.4K0
“十元店”的大生意 ——QQ会员业务转型及深度运营
代码实现:会员制度,分普通会员和超级会员
产品经理:我们增加了活动送的一个月体验会员,与普通会员享受同等九折待遇,但是只能享受最高20的优惠金额。
艳艳代码杂货店
2021/09/26
1.9K0
Linux京东签到教程,京东POP店铺签到有礼操作指南「建议收藏」
抽奖,B端商家可设置不同级别奖品,不同中奖率;C端用户参与抽奖活动,增强双方互动性,提升转化率。
全栈程序员站长
2022/10/02
1.2K0
Linux京东签到教程,京东POP店铺签到有礼操作指南「建议收藏」
今晚!QQ与宝马再牵手,互联网企业玩转会员的正确姿势是什么?
今天,腾讯QQ与宝马在广州太古仓召开跨界合作发布会。一个是社交巨头、一个是汽车老牌,看上去毫不沾边的两个品牌却走到了一起,合作形式是宝马定制车型接入QQ超级会员、QQ音乐、全民K歌等QQ下属的产品或服务,合作产品是100辆定制版宝马BMW1系运动轿车。事实上,这已经不是QQ第一次和宝马联手“搞事情”了,在此之前,QQ与宝马已成功牵手两次。 QQ成了开宝马的老司机 2015年,QQ第一次与宝马牵手是从产品层面出发。QQ为宝马定制了车载IM即宝马QQ,用户可在车载屏幕上聊QQ,接收或者发送位置并直接导航。
罗超频道
2018/04/25
1K0
今晚!QQ与宝马再牵手,互联网企业玩转会员的正确姿势是什么?
现有1亿个用户10天的签到情况,你能统计出这10天连续签到的用户总数吗?
在 Web 和移动应用的业务场景中,我们经常需要保存这样一种信息:统计用户在手机 App 上的签到打卡信息。
杨同学technotes
2022/12/01
7060
产品经理必会知识:万字长文 | 史上最全的付费会员体系分析
老生常谈的AARRR模型中,会员体系在活跃、留存、收入端是最常见的运营手段,它有两种类型:
全栈程序员站长
2022/07/04
3.3K0
产品经理必会知识:万字长文 | 史上最全的付费会员体系分析
技术改变生活——QQ等级计算工具
  最近老有人问我升到皇冠需要多少时间,我就回“你查下皇冠的活跃天数,减去你当前天数不就行了”,但是后来我发现,除了大家熟知的QQ会员能加速外,还有超级QQ、QQ拼音、QQ电脑管家和腾讯微博,都能进行加速,而且根据不同规则,加速天数也各不相同。本想网上找找看有没有现成的相关软件,结果只发现1个,而且版本特别老,是08年的产物,功能上完全不能达到现在的需求,于是,我就自己做了个。
胡尐睿丶
2022/03/23
2.3K0
技术改变生活——QQ等级计算工具
一个小小的签到功能,到底用 MySQL 还是 Redis ? ?
redis实现方案,使用bitmap来实现,bitmap是redis 2.2版本开始支持的功能,一般用于标识状态,
芋道源码
2020/10/09
1.1K0
一个小小的签到功能,到底用 MySQL 还是 Redis ? ?
一个小小的签到功能,到底用MySQL还是Redis?
redis实现方案,使用bitmap来实现,bitmap是redis 2.2版本开始支持的功能,一般用于标识状态,
良月柒
2020/09/23
7080
一个小小的签到功能,到底用MySQL还是Redis?
签到功能,用 MySQL 还是 Redis ?
redis实现方案,使用bitmap来实现,bitmap是redis 2.2版本开始支持的功能,一般用于标识状态,
java进阶架构师
2020/10/23
1.9K0
签到功能,用 MySQL 还是 Redis ?
让你设计实现一个签到功能,到底用MySQL还是Redis?
redis实现方案,使用bitmap来实现,bitmap是redis 2.2版本开始支持的功能,一般用于标识状态,
业余草
2020/09/21
2.3K0
腾讯电脑管家携手QQ倡导“腾出空,趣探索”
【天极网IT新闻频道】随着“腾出空,去生活”系列品牌活动的落地,“如何平衡工作与生活”的话题引起了职场白领的热烈讨论。近日,腾讯电脑管家基于对职场人士的深刻洞察,联合腾讯QQ面向广大用户发起“腾出空,趣探索”的号召,呼吁用户通过高效的工作、学习方式,释放更多个人时间去探索新鲜事物,发现更好玩的世界。 此次腾讯电脑管家携手腾讯QQ,打造“探索未来的自己”为主题活动,进一步丰富“腾出空,去生活”的现实意义。同时深度结合腾讯电脑管家12.10版“最近文档”功能和QQPC 9.0版新增的“腾讯视频”追剧功能、“
企鹅号小编
2018/03/01
1.1K0
腾讯电脑管家携手QQ倡导“腾出空,趣探索”
破局升级 | QQ VIP官网再设计
腾讯ISUX isux.tencent.com 社交用户体验设计 有破有立,再造升级。官网作为会员体系中最主要的营销渠道,突破原有的资源壁垒,将QQ三大会员体系官网进行再造升级,对商业目标的达成起到至关重要的作用,同时也能给QQ用户提供更为全面的会员服务。我们将从确定目标价值、构建官网架构、设计语言升级、打造通用组件这几个方面一一道来QQ VIP官网的再设计之路。 项目背景 QQ原有的两大会员体系QQ会员和QQ空间黄钻,原本互相独立,产品运营和用户体验上存在很多差异。但QQ空间本身是基于QQ
腾讯ISUX
2020/01/03
1.2K0
破局升级 | QQ VIP官网再设计
大福利 | QQ会员 x QQJOY装置设定
QQJOY嘉年华2020于11月20日在上海国家会展中心举办,作为正值20周年的QQ会员,“理所当燃”如期而至。QQ会员携20周年特别版公仔“燃鹅”在魔都与小伙伴们连嗨三天,为小伙伴们带来一系列围绕着“燃”的产品展示、体验活动、互动游戏和免费礼品。 20岁是一个热血的年纪,QQ会员围绕着“燃”的主题对品牌形象进行了全面升级,本篇文章将给大家分享我们如何在线下打造一个“燃”的互动体验空间。 PART 01 整体设计思路 QQ会员品牌形象全新升级,品牌符号由头发变成了火焰,更能代表年轻人的风貌和态度。同时
腾讯ISUX
2020/12/22
5950
QQ大会员品牌运营策划与设计
2019年6月,我们的增值团队推出了全新增值业务QQ大会员,其定位是基于QQ超级会员和豪华黄钻所有特权,同时提供更多增值服务。作为设计团队,得知这个消息的我们是兴奋的,我们可以全流程参与从0到1打造和运营一个全新的会员品牌。 同时我们也在思考,什么样的一个品牌形象可以囊括QQ超级会员和豪华黄钻的所有特性,甚至看起来要更厉害,更尊贵呢?这让我们意识到,需要将我们会员系统的品牌设计推向突破点了。本文分为两部分,从树立QQ大会员品牌形象到一年后的现在,我们如何根据产品不同阶段特性和产品策略对QQ大会员进行品
腾讯ISUX
2021/02/25
8430
博文视点读书节第五日丨IT大咖私房书单继续放送,超级会员返场来袭!
博文视点程序员读书节 第五日 ● 精彩继续 持续关注每日推送 > 更多精彩活动享不停 < 行业大咖私房书单 领域专家精彩联播 十日荐书计划 百份大厂联名福袋 学院课程全场超值秒杀 学院超级会员1元抢 …… 限定活动不间断进行  整整十天高密度福利轰炸  给你安排上了! ▼  博文视点程序员读书节  10月15日-10月24日 十日好书&惊喜不间断 一波带走十重满足!我可以! 第 一 弹 十日荐书计划 第五日 荐书官:李智慧 阿里巴巴&Intel前架构师 《大型网站技术架构:核心原理与案例分析》作者
博文视点Broadview
2023/05/19
1680
博文视点读书节第五日丨IT大咖私房书单继续放送,超级会员返场来袭!
读书节第三日丨产品大咖荐读&直播齐上阵,学院超级会员限时开抢!
博文视点程序员读书节 第三日 ● 直播活动上线 持续关注每日推送 > 更多精彩活动享不停 < 行业大咖私房书单 领域专家精彩联播 十日荐书计划 百份大厂联名福袋 学院课程全场超值秒杀 学院超级会员1元抢 …… 限定活动不间断进行  整整十天高密度福利轰炸  给你安排上了! ▼  博文视点程序员读书节  10月15日-10月24日 十日好书&惊喜不间断 一波带走十重满足!我可以! 第 一 弹 十日荐书计划 第三日 荐书官:范冰 独立咨询顾问 科技专栏作家 Growth Hacking国内早期布道与推动
博文视点Broadview
2023/05/19
2120
读书节第三日丨产品大咖荐读&直播齐上阵,学院超级会员限时开抢!
推荐阅读
相关推荐
使用监控宝自动签到免费获取一年优酷会员
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验