测试(4): 测试与类型

程序语言里的一个重要概念就是类型约束,既然类型是一种约束,它和软件测试之间的关系是什么?

我们可以从软件的构成来看下:

软件=程序+软件工程

单看程序,按下软件工程不表。下面的公式对么?

程序=算法+数据结构

这要看抽象的角度。狭义地说,算法和数据结构是非常核心的部分,一般只是占一个程序的基础部分。而一个基础部分,充其量只是一个程序的一个模块,即使是很核心的模块。假设一个程序只用一种语言开发,一个语言包括运行时+基础类库。一个稍微有点规模的程序需要在语言运行时+语言基础类库的基础上,引入3rd(第三方)库,引入所需要的框架或者自己发明的轮子,开发各种辅助支持库,并构建所要解决问题的领域模型,然后组织上层业务逻辑。

从这个角度看,一个项目的基本单元可以看成是一个模块,从而程序可以看作是

程序=语言运行时+基础类库+3rd库+框架+领域模型+业务模块。

而一个模块,在大部分语言下,由函数构成。在一个类的角度来看,可以考察的是类与类之间间结构类内部的成员变量和函数结构。类间结构表现出来可能是设计模式;类内结构,可能才是数据结构+算法的领地。那么,拆分到类,类的粒度之下的基本行为单元是函数。所以,如果我们保证所有函数的行为正确,就能很大程度保证一个类的行为正确,从而保证一个模块的行为正确,而所有模块的正确最后就保证了一个程序的正确性。

怎样保证函数的正确性?一个函数在运行时,依赖于该函数的假设条件是否满足,一个函数执行应该是怎样的状态,执行后应该是怎样的状态,一个健壮的函数代码可能需要写很多前置条件检查和后置状态检查。

一个良好的编程语言会提供内置的机制支持对假设条件的检查,其中最核心的就是类型约束。按照语言里对类型约束的强弱,我们知道语言分强类型语言和弱类型语言;另一种角度是根据类型约束起作用的时机,分静态类型语言和动态类型语言。

然而类型检查所能作的约束非常有限,即使是检查一个函数所有可能的输入应该有所有可能的预期输出这个目标,靠类型约束都不能做到。而这,需要做的就是单元测试。从这个角度来说单元测试是类型安全的延伸,类型是一种对语义的限制,由于运行时语义的组合爆炸,导致不能通过语言内置的类型规则检查所有的语义限制,所以只好用单元测试来做补丁。

但是,类型做的约束是“是什么”,类型本身不约束行为,也就是“怎么做”。具体差别如下:

  1. 一个行为良好的语言,可能使用一个较少类型约束的语言。
  2. 一个行为糟糕的语言,可能使用一个类型约束很强的语言。

因此,类型约束和测试的约束的是不同的事情,测试约束的是函数、模块、程序的行为。

posted @ 2017-01-15 22:52  ffl  阅读(303)  评论(0编辑  收藏  举报