什么用于属性测试

cou*_*ech 17 haskell unit-testing quickcheck property-based-testing

我想知道什么是物业测试目标,它的甜点是什么,应该在哪里使用.让'有一个我想测试的示例函数:

f :: [Integer] -> [Integer]
Run Code Online (Sandbox Code Playgroud)

这个函数f采用一个数字列表,并将奇数数字平方并滤除偶数.我可以陈述一些关于函数的属性,比如

  1. 给出偶数列表,返回空列表.
  2. 给定奇数列表,结果列表将具有与输入相同的大小.
  3. 鉴于我有偶数列表和奇数列表,当我加入它们时,随机传递并传递给函数,结果的长度将是奇数列表的长度.
  4. 鉴于我提供了一个正奇数列表,那么同一索引的结果列表中的每个元素都将大于原始列表中的元素
  5. 鉴于我提供奇数和偶数的列表,加入并随机播放它们,然后我将得到一个列表,其中每个数字都是奇数
  6. 等等

没有属性测试,该函数适用于最简单的情况,例如我可以做一个简单的情况,如果我实现f错误将传递这些属性:

f = fmap (+2) . filter odd
Run Code Online (Sandbox Code Playgroud)

所以,如果我想介绍一些简单的情况,看起来我需要在属性规范中重复算法的基本部分,或者我需要使用基于值的测试.重复算法的第一个选项可能是有用的,如果我打算改进算法,如果我计划改变它的实现,例如速度.通过这种方式,我有一个参考实现,我可以用来再次测试.

如果我想检查一下,算法不会因某些微不足道的情况而失败,我不想在规范中重复算法,看起来我需要一些单元测试.我会写例如这些检查:

f ([2,5]) == [25]
f (-8,-3,11,1) == [9,121,1]
Run Code Online (Sandbox Code Playgroud)

现在我对算法有了更多的信心.

我的问题是,基于属性的测试是否意味着要取代单元测试,还是它是互补的?是否有一些一般性的想法,如何编写属性,所以它们是有用的还是完全取决于对函数逻辑的理解?我的意思是,可以说,以某种方式写出属性特别有益吗?

此外,是否应该努力使属性测试算法的每个部分?我可以把算法放在一边,然后在其他地方进行测试,让属性只测试过滤部分,它看起来很好,它可以很好地覆盖它.

f :: (Integer -> Integer) -> [Integer] -> [Integer]
f g = fmap g . filter odd
Run Code Online (Sandbox Code Playgroud)

然后我可以通过单独Prelude.id测试来测试g其他地方.

Ing*_*ngo 4

下面的属性怎么样:

  1. 对于源列表中的所有奇数,其平方是结果列表的元素。
  2. 对于结果列表中的所有数字,源列表中都有一个数字与其平方。

顺便odd说一句,比\x -> x % 2 == 1