原文译文操作

If you've encountered test-driven development (TDD), you may have encountered programmers who follow it with almost religious fervor. They will tell you that you must always write unit tests before you write code, no exceptions. If you don't, your code will be condemned to everlasting brokenness, tortured by evil edge cases for all eternity.

This is an example of a common problem in programming: good advice by experts that gets turned into a counter-productive religion. Test-driven development is useful and worth doing... some of the time, but not always. And the experts who came up with it in the first place will be the first to tell you that.

如果你遇到过测试驱动的开发(TDD),你可能已经遇到了带有几乎宗教热情的程序员采用这种方法。他们会告诉你在写代码之前必须写单元测试,没有例外。如果你不这么做,你的代码会被永恒的破碎诅咒,永远被邪恶的边界用例折磨。

这是编程中的一个常见的问题:专家的好的建议变成了一个降低生产效率的宗教信仰。基于驱动的开发是很有用的,而且值得采纳... 在有的时候,但不是所有情况下。第一个提出TDD的专家会是第一个告诉你这一点的人。

纠正翻译

Let's see how expert advice turns into zealotry, and how you can prevent it from happening to you.

Expert advice becomes a religion

The problem with experts is that they suffer from Expert Blind Spot. Because experts understand the subject so well, they have trouble breaking it down into concepts and explaining it in ways that make sense to novices.

Thus the expert may say "always write unit tests before you write your code." What they actually meant is this:

  1. Write unit tests before you write your code.
  2. Unless it's code that isn't amenable to unit testing, e.g. because unit tests aren't informative for this particular kind of code.
  3. Or unless it's code that you're going to throw away immediately.
  4. And technically you can write the test after the code, and then break your code and check the test is failing. But this is annoying and a bit more error prone so as an expert I'm not going to mention that at all.

让我们看看专家建议是如何成为宗教的,以及你怎样能避免这件事情发生。

专家建议成为了宗教

专家的问题是,他们有专家盲点。因为专家如此理解一个事情,他们无法将其拆分成概念,并以一种可以理解方式解释给新手。

因此专家可能会说“在写代码前,你一定要写单元测试。”他们实际想说的是:

  1. 在你写代码之前,写单元测试。
  2. 除非这份代码不受单元测试控制,比如由于单元测试对这个特殊种类的代码无法提供丰富的信息。
  3. 或者除非是你打算立刻丢掉的代码。
  4. 从技术上讲你可以在写完代码后写测试,然后再拆分你的代码并逐步测试。但这么做很烦人而且稍微更容易出错,所以作为一个专家我根本不打算提这一点。
纠正翻译

A True Believer in TDD might start arguing with these claims. But consider that even Extreme Programming, where TDD originates, discusses types of coding where unit tests are unnecessary.

In particular a "spike" in Extreme Programming is an architectural prototype, used to figure out the structure of the code you're going to write. Since it's going to be thrown away you don't need to write unit tests when you write a spike. You can see this visually in this overview of Extreme Programming; the Architectural Spike happens before Iterations, and unit tests are written as part of Iterations.

一个TDD的真实信徒可能会开始反对这些说法。但想想甚至TDD起源的极限编程(Extreme Programming),都讨论了有必要进行单元测试的编程类型。

特别地,极限编程中的一个“spike”是一个体系结构原型,用于找出你打算写的代码的结构。由于它最终会被丢掉,你在写spike的时候不需要写单元测试。你可以在这个极限编程概述中可视化地看到这一点;体系结构的Spike总是在循环之前 发生,而单元测试是作为循环的一部分写成的。

纠正翻译

If you're certain all code is amenable to unit testing, consider these two examples: unit tests aren't very helpful in testing a cryptographically secure random number generator. And if the director of a movie has asked you write some code to 3D render a "really awesome-looking explosion" you won't benefit much from unit tests either, unless you can write a unit test to determine awesomeness.

So if experts know unit-testing-before code isn't always the right answer, why do they say "always write unit tests before you write your code"? Expert blind spot: they can't imagine anyone would write unit tests when they shouldn't.

如果你认定单元测试适用于所有代码,想想两个例子:单元测试在检测一个密码安全随机数字生成器中没什么用处。而且如果一个电影的导演让你写一段代码来3D渲染一个“看起来非常给力的爆炸”,你同样无法从单元测试中收益太多,除非你写一个单元测试来定义“给力程度”。

所以如果专家知道在写代码前写单元测试不总是对的,他们为什么说“总是 在写代码之前写单元测试”呢?专家盲点:他们无法想象任何人在不该写单元测试的时候写单元测试。

纠正翻译

To the expert, a prototype and code requiring tests are obviously very different things with different goals. But that isn't so obvious to the novice listener.

The novice listener takes the expert at their literal word, and comes to believe that they must always write unit tests before writing code. The novice is now a True Believer. They tell everyone they know "always wrote tests before you write code," and they try to do so under all circumstances.

Thus good advice turns into a counter-productive religion, with unit tests often being written when they needn't or shouldn't be.

对于专家来说,一个原型系统和需要测试的代码,对于不同目标来说,很明显是非常不同的事情。但对于新手听众来说没那么明显。

新手听众会从字面意义上去理解专家的建议,并且相信他们必须在写代码前总是 写单元测试。新手现在变成了一个真正信徒。他们告诉认识的所有人“总是在写代码前写测试”,并且他们试图在所有情况下都这么做。

这样,好的建议转变成了降低生产力的宗教,因为单元测试总在不需要或者不应该出现的时候出现。

纠正翻译

Avoiding the trap

How can you keep this from happening to you?

If you're an expert, make sure you explain the qualifications to your statements. Don't say "always do X." Instead say "you should do X, because Y, under circumstance A but not circumstance B."

If you're not an expert things get a bit harder. Consider that both the expert and the True Believer are making the same statement: "always write tests before you write code." How can you tell whether the person telling you this is an expert or a True Believer?

You need to take every piece of advice and figure out when and where it does not apply. An expert's assumptions will often be implicit in the topic they're writing about, so that may give you some hints.

避免陷阱

你该怎么做来避免这种事情发生在你身上呢?

如果你是个专家,确保解释你的陈述的应用场景。不要说“总是要做X”。而是要说“因为Y,你需要做X,在A的情况下但不是B的情况下。”

如果你不是专家,事情就有点麻烦了。想想要是专家和真正信徒都在做同样的陈述“总是在写代码前写测试”。你怎么能分辨出告诉你这一点的是专家还是真正信徒呢?

你需要听取每一份意见,并弄清楚在什么场景下它不适用。对于一个专家写作的话题,他的假设经常是隐式的,所以这可能给你一些提示。

纠正翻译

If you're having a two-way conversation try to get them to qualify their statement: ask them to come up with the boundary cases, where this advice is no longer applicable. Bring up the cases you've found where their advice seemingly won't work and see what they say.

An expert, given enough prodding, will be able to come up with cases where their advice isn't applicable, and explain the reason why. But a True Believer won't back down, won't agree to any compromise: they know the The Truth, and it is absolute and unchanging.

Programming is a broad field, and what makes good software depends on your circumstances, goals and tools. There is almost never one answer that applies everywhere. Learn from the experts, but never become a True Believer.

如果你能够与专家双向交流,试图让专家描述他们的陈述的适用范围:让他们提出这个建议不再适用的边界场景。提出你找到的他们的建议似乎无法工作的例子,看看他们说什么。

一个专家如果受到了足够的刺激,能够提出他们的建议不适用的例子,并解释为什么。但一个真正信徒不会退缩,不会接受任何妥协:他们知道真相,而且是绝对的和不可改变的真相。

编程是一个广阔的领域,什么能造就一个好软件取决于你的场景、目标和工具。几乎从没有任何一个答案处处适用。从专家身上学习,但绝不要从真正信徒身上学习。

纠正翻译