Test Precisely and Concretely

Kevlin Henney

IT IS IMPORTANT TO TEST for the desired, essential behavior of a unit of code, rather than 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 illus- trative example. Implementing a sorting algorithm is not necessarily an every- day 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 something like, “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 result- ing sequence should be the same length as the original. Although correct, this is still not enough. For example, given the following sequence:

31415 9

The following sequence satisfies a postcondition of being sorted in non- descending order and having the same length as the original sequence:

33333 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 (fortu- nately 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 permuta- tion of the original values. This appropriately constrains the required behavior.

162 97 Things Every Programmer Should Know



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 com- plicated that there are no obvious deficiencies.

Using concrete examples eliminates this accidental complexity and opportu- nity for accident. For example, given the following sequence:

31415 9

The result of sorting is the following:

11345 9

No other answer will do. Accept no substitutes.

Concrete examples help 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’s also 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.

Test Precisely and Concretely的更多相关文章

  1. RFC3261--sip

    本文转载自 http://www.ietf.org/rfc/rfc3261.txt 中文翻译可参考 http://wenku.baidu.com/view/3e59517b1711cc7931b716 ...

  2. react programming

    So you're curious in learning this new thing called Reactive Programming, particularly its variant c ...

  3. Learning to Promote Saliency Detectors

    Learning to Promote Saliency Detectors 原本放在了思否上, 但是公式支持不好, csdn广告太多, 在博客园/掘金上发一下 https://github.com/ ...

  4. 深度学习Deep learning

    In the last chapter we learned that deep neural networks are often much harder to train than shallow ...

  5. IDL build

    For Developers‎ > ‎Design Documents‎ > ‎ IDL build 目录 1 Steps 2 GYP 3 Performance 3.1 Details ...

  6. [C2P1] Andrew Ng - Machine Learning

    About this Course Machine learning is the science of getting computers to act without being explicit ...

  7. [C2P3] Andrew Ng - Machine Learning

    ##Advice for Applying Machine Learning Applying machine learning in practice is not always straightf ...

  8. 2017年计算语义相似度最新论文,击败了siamese lstm,非监督学习

    Page 1Published as a conference paper at ICLR 2017AS IMPLE BUT T OUGH - TO -B EAT B ASELINE FOR S EN ...

  9. ASP.NET Core project.json imports 是什么意思?

    示例代码: "frameworks": { "netcoreapp1.0.0": { "imports" : "portable- ...

随机推荐

  1. Android error--No implementation found for native Lcomd

    在利用NDK编译Cpp执行时,出现了No implementation found for native Lcom等错误,调试好久,才发现 XXX.h和XXX.cpp.在XXX.cpp里#includ ...

  2. 一个简单的推断抢购时间是否到达的js函数

    原型函数,功能非常easy,找到时钟的id,计算数值.到达抢购时间时运行任务. function nwt() {var str=$('#deal_expiry_timer_e3cdcd2a').tex ...

  3. Android自己定义控件皮肤

    Android自己定义控件皮肤 对于Android的自带控件,其外观仅仅能说中规中矩,而我们平时所示Android应用中,一个简单的button都做得十分美观.甚至于很多button在按下时的外观都有 ...

  4. Spring In Action读书笔记

    第一章 1.Spring採用4种策略减少Java开发复杂度 基于POJO的轻量级和最小侵入性编程 依赖注入和面向接口实现松耦合 基于切面和惯例进行声明式编程 通过切面和模板降低样板式代码 PS:POJ ...

  5. 【Python】python网络协议

    套接字是常见的低级别的网络通讯协议,在此基础上,还有很多其他的网络通讯协议.用于实现client-server的网络互联,以下对这些协议做一个简单的介绍. 1.文件传输 FTP:文件传输协议.能够上传 ...

  6. #定位系统性能瓶颈# perf

    perf是一个基于Linux 2.6+的调优工具,在liunx性能測量抽象出一套适应于各种不同CPU硬件的通用測量方法,其数据来源于比較新的linux内核提供的 perf_event 接口 系统事件: ...

  7. 痛苦的人生——JRuby on Rails的开发与部署小记

    最近单位领导部署了一项开发用户自助服务系统的任务,该任务有且仅有我一人独立完成——哈哈,十分美妙的工作呢. 恰巧楼主最近被Ruby的美妙特性所迷惑,于是义无反顾地投入到Ruby on Rails的怀抱 ...

  8. iOS9中,swift判断相机,相册权限,选取图片为头像

    在iOS7以后要打开手机摄像头或者相册的话都需要权限,在iOS9中更是更新了相册相关api的调用 首先新建一个swift工程,在SB中放上一个按钮,并在viewController中拖出点击事件 ok ...

  9. hdoj--3594--Cactus(tarjan)

    Cactus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  10. Java基础——选择排序、冒泡排序

    1.选择排序 原理是直接从待排序数组里选择一个最小(或最大)的数字,每次都拿一个最小数字出来, 顺序放入新数组,直到全部拿完 代码演示: public class Test3 { public sta ...