【外评】谷歌测试:复杂难读的布尔表达式
这是我们 “代码健康 “系列的另一篇文章。本文章的一个版本最初作为 “谷歌厕所测试 “插曲出现在全球的谷歌厕所中。您可以下载便于打印的版本,在您的办公室展示。
作者:孙一鸣(Yiming Sun)
您可能在代码库中遇到过一些复杂难读的布尔表达式,希望它们更容易理解。例如,我们想判断比萨饼是否美味:
// Decide whether this pizza is fantastic. if ((!pepperoniService.empty() || sausages.size() > 0) && (useOnionFlag.get() || hasMushroom(ENOKI, PORTOBELLO)) && hasCheese()) { ... }
改进的第一步是将条件提取为一个名称明确的变量:
boolean isPizzaFantastic = (!pepperoniService.empty() || sausages.size() > 0) && (useOnionFlag.get() || hasMushroom(ENOKI, PORTOBELLO)) && hasCheese(); if (isPizzaFantastic) { ... }
然而,布尔表达式仍然过于复杂。根据给定的输入集计算 isPizzaFantastic 的值可能会令人困惑。您可能需要拿起笔和纸,或在本地启动服务器并设置断点。
取而代之的是,尝试将细节归类为提供有意义抽象的中间布尔值。下面的每个布尔值都代表一个定义明确的质量,你不再需要在表达式中混合使用 && 和 || 。在不改变业务逻辑的情况下,您可以更轻松地查看布尔值之间的关系:
boolean hasGoodMeat = !pepperoniService.empty() || sausages.size() > 0; boolean hasGoodVeggies = useOnionFlag.get() || hasMushroom(ENOKI, PORTOBELLO); boolean isPizzaFantastic = hasGoodMeat && hasGoodVeggies && hasCheese();
另一种方法是将逻辑隐藏在单独的方法中。这也提供了使用guard clauses 提前返回的可能性,进一步减少了跟踪中间状态的需要:
boolean isPizzaFantastic() { if (!hasCheese()) { return false; } if (pepperoniService.empty() && sausages.size() == 0) { return false; } return useOnionFlag.get() || hasMushroom(ENOKI, PORTOBELLO); }
本文文字及图片出自 isBooleanTooLongAndComplex
你也许感兴趣的:
- 【程序员搞笑图片】开发人员和测试人员
- 【程序员搞笑图片】设计的付出、开发的付出对比写单元测试和自动化测试脚本的付出
- 【外评】谷歌对测试的分类
- 【译文】谷歌测试技术:如何大规模代码删除
- 【译文】谷歌测试技术:多少测试才算足够?
- Sentry 的前端测试实践:从 Enzyme 迁移到 RTL
- 2021年10大流行软件测试工具
- 谈一谈程序员不愿意写测试的问题
- 程序员文史综合素质测试题,下跪吧
- 为什么说让程序员自己做测试等于白测
你对本文的反应是: