《97 Things Every Programmer Should Know》章节翻译,请指正一下最后两段。

译《97 Things Every Programmer Should Know》中部分章节,如下文,最后两段总感觉别扭,请各位帮助指正一下,多谢。

 

精准、细致的测试


测试应当找准要点、明确目的,而不要在一些次要、无效的细节上花费过多精力。但这里要求的放弃次要、无效细节并不是说测试就可以不细致,它更不应该成为我们对测试敷衍了事的借口。测试绝对应该做到精准、细致。

这里举一个数组排序的例子,也许对于一个开发人员来说,对数组进行排序不会每天都遇到,但排序算法相信大多数人都耳熟能详。当提出一个问题:“你会怎样测试一个数组排序函数的正确性?”,我想大部分人的回答是:“验证函数输出结果是否将元素按一定顺序排列”。这样的回答当然没错,但显然还不够精确。
 
如果我再提示是否还包含其它验证条件?一些人也许会想想然后再补充:“排序后的数组长度应该与原始数组长度相同”。我只能再次说没错,但仍然不够精确,且看下面给出的原始数组:

 3 1 4 1 5 9

再看排序后的结果:

 3 3 3 3 3 3

这个结果满足之前回答的两个条件:有一定顺序(非降序),且与原始数组长度相同。但明显结果并不正确,其实这个例子是我从一个实际开发项目中原封不动拿来的(幸运的是在产品发布前),它产生的原因是一个开发人员的一时大意在排序时重复把第一个值赋给了所有元素。但如果按前面的两个假设条件作为我们的测试用例,这将是一个可怕的后果。

所以找准测试要点非常重要,总结一下这个测试排序函数的精确条件:“只允许将数组中的元素置换位置以使其按顺序排列”。OK,这样我们的测试方案就精准了。同时可以发现对数组元素换位是不会影响到它的长度的,所以“输出长度与原始数组长度必需一至”这个条件已不再需要。

我们找出了对数组排序函数的测试要点,但找出要点不等于就能做出一个好的测试方案,因为一个好的测试方案应该是易读、易懂并且容易实现的。这里虽然正确的描述了精确的测试条件,但仔细想想如果要根据这个条件进行测试就必需编写单独的代码,而编写的代码可能比排序本身更复杂。正如托尼.霍尔(见注1曾经说的:

“进行软件设计有两种方式:一种是让它尽量简单,让人看不出明显的不足。另一种是尽量复杂,让它没有明显的缺陷。”

通过构思一个具体的实例往往能帮助我们降低问题的复杂性,少走弯路。如下原始数组:

3 1 4 1 5 9

排序后的结果:

1 1 3 4 5 9

当面对这样的具体实例,要把原始数组排序为预期结果过程中我们就会考虑到诸多细节:比如如何遍历原始数组并将元素值顺序填充到一个新数组中,填充过程中如何保证每个元素的唯一性,多个元素的大小排列算法,等等。

找准每个要测试对象的特征,精准、细致是测试的两大要素。

 

注1:Tony Hoare,1934年出生于英国,1959年博士毕业于俄罗斯莫斯科国立大学,获得语言机器翻译专业学士学位。1960年发布了使他闻名于世的快速排序算法(Quick Sort),这个算法也是当前世界上使用最广泛的算法之一。1980年被美国计算机协会授予“图灵奖”,2000年因为其在计算机科学与教育上做出的贡献被封为爵士。

 
 
 
 
原文:
 
Test Precisely and Concretely

It is important to test for the desired, essential behavior of a unit of code, rather than test for the incidental behavior of its particular implementation. But this should not be taken or mistaken as an excuse for vague tests. Tests need to be both accurate and precise.
Something of a tried, tested, and testing classic, sorting routines offer an illustrative example. Implementing a sorting algorithm is not necessarily an everyday task for a programmer, but sorting is such a familiar idea that most people believe they know what to expect from it. This casual familiarity, however, can make it harder to see past certain assumptions.
When programmers are asked "What would you test for?" by far and away the most common response is "The result of sorting is a sorted sequence of elements." While this is true, it is not the whole truth. When prompted for a more precise condition, many programmers add that the resulting sequence should be the same length as the original. Although correct, this is still not enough. For example, given the following sequence:
    3 1 4 1 5 9
The following sequence satisfies a postcondition of being sorted in non-descending order and having the same length as the original sequence:
    3 3 3 3 3 3
Although it satisfies the spec, it is also most certainly not what was meant! This example is based on an error taken from real production code (fortunately caught before it was released), where a simple slip of a keystroke or a momentary lapse of reason led to an elaborate mechanism for populating the whole result with the first element of the given array.
The full postcondition is that the result is sorted and that it holds a permutation of the original values. This appropriately constrains the required behavior. That the result length is the same as the input length comes out in the wash and doesn't need restating.
Even stating the postcondition in the way described is not enough to give you a good test. A good test should be readable. It should be comprehensible and simple enough that you can see readily that it is correct (or not). Unless you already have code lying around for checking that a sequence is sorted and that one sequence contains a permutation of values in another, it is quite likely that the test code will be more complex than the code under test. As Tony Hoare observed:
    There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other is to make it so complicated that there are no obvious deficiencies.
Using concrete examples eliminates this accidental complexity and opportunity for accident. For example, given the following sequence:
    3 1 4 1 5 9
The result of sorting is the following:
    1 1 3 4 5 9
No other answer will do. Accept no substitutes.
Concrete examples helps to illustrate general behavior in an accessible and unambiguous way. The result of adding an item to an empty collection is not simply that it is not empty: It is that the collection now has a single item. And that the single item held is the item added. Two or more items would qualify as not empty. And would also be wrong. A single item of a different value would also be wrong. The result of adding a row to a table is not simply that the table is one row bigger. It also entails that the row's key can be used to recover the row added. And so on.
In specifying behavior, tests should not simply be accurate: They must also be precise.
By Kevlin Henney

posted on 2010-06-02 09:22  吴剑  阅读(1794)  评论(1编辑  收藏  举报

导航