在测试方法名中使用不间断空格
摘要
本文讨论了在PHP测试方法名中使用不间断空格,以提升代码的可读性和清晰度。
<p><a href="https://lobste.rs/s/bvsaiy/using_non_breakable_spaces_test_method">评论</a></p>
查看缓存全文
缓存时间: 2026/09/20 10:11
# 在测试方法名中使用不间断空格
来源:https://mnapoli.fr/using-non-breakable-spaces-in-test-method-names
**是的,本文将介绍如何使用不间断空格来命名测试方法。这个技巧非常棒,强烈推荐你也试试看。**
```
public function test a user can add a product to a wishlist()
{
}
```
上述代码是完全有效的PHP代码(https://3v4l.org/MrqVL)并能正常运行。不间断空格(https://en.wikipedia.org/wiki/Non-breaking_space)在编辑器中看起来与普通空格相同,但PHP会将其视为普通字符进行解析。
---
这是常见的测试命名方式:
```
public function testAddProductToWishlist()
{
}
```
这也是几年前我们在Wizaplace (http://www.wizaplace.com/) 项目中惯用的命名风格。
当时我们深受几个关于代码风格演讲的影响(https://mnapoli.fr/approaching-coding-style-rationally/)。使用 `snake_case` 代替 `camelCase` 在测试方法中逐渐变得合理,因为它能更清晰地表达测试意图:
```
public function test_a_user_can_add_a_product_to_a_wishlist()
{
}
```
(☝️ 这不符合PSR-2规范,起初我们对此持怀疑态度,但最终还是接受了)
团队内部开始讨论这种命名方式。恰逢当时我们正在开玩笑要开发PHP 6框架(https://github.com/wizaplace/thephp6framework),并尝试用表情符号作为类名或方法名(这在PHP中完全可行 https://github.com/fideloper/laravel)。
有人突然开玩笑提议:
> 既然为了可读性可以不遵循PSR-2的测试方法命名规范,不如直接用不间断空格,这样可读性会更强...
这本是个玩笑,但仔细想想确实有道理。由于逻辑思维与人类认知有时难以协调,我们决定进行一次小规模可控实验(http://verraes.net/2014/03/small-controlled-experiments/),在实践中检验效果。
```
public function test a user can add a product to a wishlist()
{
}
```
结果令人惊喜。这种方法如此出色,以至于一年后的今天我们依然对它完全满意。
测试方法变得清晰且富有表达力,以下是来自我们某个实际代码变更的差异示例:
```
- public function testProjectMultiVendorProductWithOneDetached()
+ public function test product and multivendor product projections are both updated when they are detached()
{
```
由于测试方法像完整句子一样,我们会自然地将其视为语句来思考,这让所有测试都变得更加清晰。再看几个例子:
```
public function test very long slugs are truncated()
{
}
public function test there are no projects by default()
{
self::assertEmpty($this->projectService->getProjects());
}
```
## 常见问题解答
### 如何实际输入不间断空格?
这非常简单且容易掌握:
- MacOS系统:`Alt`+`空格`
- Ubuntu系统:`Alt Gr`+`空格`(`Alt Gr`是右侧的`Alt`键)
### 是否与所有开发工具兼容?
根据我们的经验,完全兼容。我们使用的所有工具都运行良好:
- git
- PhpStorm —— 更新说明:此快捷键会触发"快速定义"辅助功能,需要禁用(或重新映射)该快捷键;默认情况下也可以通过 `Cmd+Y` 或 `Ctrl+Y` 访问"快速定义",因此移除该快捷键即可
- Sublime Text
- GitHub(及原Gitlab)
- PHPUnit在PhpStorm中的集成(右键点击"运行"功能仍然有效)
- Phpstorm的代码分析和重构工具:
我们在Atom和Visual Studio Code中遇到过小问题(语法高亮异常),这些问题已由Florent(https://twitter.com/florent_viel)通过以下提交修复:atom/language-php#196(https://github.com/atom/language-php/pull/196)和Microsoft/vscode#26992(https://github.com/Microsoft/vscode/pull/26992)。
### 所有人类开发者都能接受吗?
这可能是最具挑战的部分:让其他团队成员接受这种方式。每个新加入团队的同事首次阅读代码时都会产生"WTF"的困惑瞬间。这违背了最小意外原则(https://en.wikipedia.org/wiki/Principle_of_least_astonishment),但我们对使用不间断空格如此自豪和满意,以至于每次向新人解释都成为有趣的时刻 :)
根据我们的经验,无论是初级还是资深开发者,同事们都能很快适应。不过我们的团队规模还较小,在拥有多团队的大型组织中推广可能会更困难。
### 如果误输入普通空格怎么办?
不必担心,你会立即发现问题:
同样根据我们的经验,这从未成为真正的问题。
### 能否用于开源项目?
这是目前我唯一的保留意见。在团队能够自主掌控代码和决策的闭源项目中使用不间断空格很简单:如果效果好,就继续使用;否则停止即可。
在开源项目中情况更复杂,因为大多数贡献者在无法得到你亲自解释的情况下都会经历"WTF"时刻。这可能会让人困惑甚至反感。
我目前的个人立场是:
- 在不太可能获得贡献者的小型项目中使用这种方法
- 尽可能推广这种实践(本文的目的正是如此)
- 希望这种做法能逐渐普及,以便我们能在更多场景中应用
相似文章
为何你应该检查你的gem的代码行数
文章讨论了使用代码行数作为评估Ruby gems的度量指标,指出这有助于理解实现复杂性,并鼓励一种通过“轻松阅读”来注重清晰度和可维护性的设计理念。
思考测试:断言与匹配器
本文探讨了软件开发中测试断言与匹配器的设计,强调了它们在编写可读且高效的测试代码中的作用,特别是在 Ruby 中。
我不再在 JavaScript 里把所有东西链在一起
开发者 Matt Smith 解释,为了调试更轻松、性能更好,他现在在 JavaScript 中更偏爱一步步写代码,而不是冗长的方法链。
单元测试:更多是圈地,而非除虫
文章指出,与硬件测试实践相比,软件开发中的单元测试主要用于圈地和维持协作环境中的代码稳定性,而非有效发现缺陷。
非尾部分隔符并不令人愉悦
本文认为,在编程语言和数据格式中禁止尾部分隔符(如逗号)会使代码编辑更容易出错且不一致,并主张语言设计应允许尾部分隔符以提供更好的开发者体验。