Haskell 有一个很好的特性,即一段代码的类型签名有时会告诉你该代码做了什么。这让我开始思考……你能根据类型签名构建测试吗?
例如,考虑一个模块,例如Data.Map
. 它定义了一个数据类型和几个对该类型进行操作的函数。只看类型签名,应该有可能[原则上]找出所有可能的构造Map
值的方法。我的意思是在算法上是可能的——应该可以编写一些程序来获取模块的接口,并计算出你可以针对它进行的所有可能的函数调用。
现在,有些人认为编写良好的测试套件可以看作是库应该做什么的“规范” 。显然,编写代码的人知道他们想要做什么,而机器不知道。但是,鉴于您提供的类型签名,机器应该能够计算出可能要求的内容。
作为更具体的情况,假设有一些不变量应该适用于所有可能的Map
值。(例如,,null m == (size m == 0)
或者内部健全性检查函数应该始终返回 true。)可以想象编写一个测试框架,将模块交给它,然后说“类型的值Map X Y
应该始终满足这些不变量”,然后让测试框架开始尝试执行您提供的功能的所有可能组合以生成地图并检查它们是否满足所有条件。如果没有,它会告诉您违反了什么条件以及构造此无效值所需的表达式。
我的问题是,这种方法听起来容易处理吗?可取的?有趣的?你会如何解决这样的问题?Djinn 似乎已经知道如何在给定预先存在的函数和常量的情况下构造指定类型的值,因此尝试提出具有给定类型的多个表达式听起来并不难。什么样的启发式方法可以用来尝试获得良好的代码覆盖率?(显然,分析代码而不仅仅是类型要困难得多......赖斯定理潜伏在等待中。)
(请注意,我并不是建议这种机器检查应该取代手写测试代码。这个想法更多是为了增强它;也许在更困难的情况下,机器可以咳出可能的表达,然后问人类什么“正确”的答案应该是。然后可以将其记录为新的测试用例,以便在测试套件运行时运行。)