标签: 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其他地方.

haskell unit-testing quickcheck property-based-testing

17
推荐指数
1
解决办法
309
查看次数

难以思考FsCheck的属性

我已经设法让xUnit处理我的小样本组件.现在我想知道我是否也可以参加FsCheck.我的问题是,在为我的函数定义测试属性时,我很难过.

也许我只是没有一套好的样本函数,但是这些函数的测试属性是什么呢?

//transforms [1;2;3;4] into [(1,2);(3,4)]
pairs : 'a list -> ('a * 'a) list      //'

//splits list into list of lists when predicate returns 
//  true for adjacent elements
splitOn : ('a -> 'a -> bool) -> 'a list -> 'a list list

//returns true if snd is bigger
sndBigger : ('a * 'a) -> bool (requires comparison)
Run Code Online (Sandbox Code Playgroud)

f# unit-testing fscheck property-based-testing

13
推荐指数
3
解决办法
844
查看次数

Agitar和Quickcheck基于属性的测试有什么区别?

许多年前,一种名为Agitar的Java测试工具很受欢迎.它似乎做了类似基于财产的测试.

如今 - 基于Haskell Quickcheck的基于属性的测试很受欢迎.Java有许多端口,包括:

我的问题是:Agitar和Quickcheck基于属性的测试有什么区别?

java haskell quickcheck property-based-testing

11
推荐指数
2
解决办法
2751
查看次数

使用假设生成具有自定义值限制的列表列表

故事:

目前,我有一个测试功能,需要一个包含以下规则的整数列表:

  1. 子列表的数量(让我们称之为N)可以是1到50
  2. 子列表中的值的数量对于所有子列表(矩形形式)是相同的,并且应该> = 0且<= 5
  3. 子列表中的值不能大于或等于子列表的总数.换句话说,子列表中的每个值都是> = 0和<的整数N

样本有效输入:

[[0]]
[[2, 1], [2, 0], [3, 1], [1, 0]]
[[1], [0]]
Run Code Online (Sandbox Code Playgroud)

示例无效输入:

[[2]]  # 2 is more than N=1 (total number of sublists)
[[0, 1], [2, 0]]  # 2 is equal to N=2 (total number of sublists)
Run Code Online (Sandbox Code Playgroud)

我试图用接近它基于属性的测试,并产生不同的有效输入hypothesis,并试图绕到我的头lists()integers(),但不能使其工作:

  • 条件#1是容易接近lists()min_sizemax_size参数
  • 条件#2包含在 Chaining strategies together
  • 条件#3是我正在努力的 - 因为,如果我们使用rectangle_lists上面的例子,我们没有引用里面的"父"列表的长度integers() …

python testing unit-testing property-based-testing python-hypothesis

11
推荐指数
3
解决办法
1178
查看次数

基于属性的PHP测试?

在各种更基于功能的语言中,有一些工具(如Quickcheck)允许基于属性的测试.

我如何在PHP中进行基于属性的测试?

我希望能够指定PHP方法的输入和输出属性,并运行覆盖测试.

php testing automated-tests quickcheck property-based-testing

10
推荐指数
2
解决办法
1951
查看次数

7
推荐指数
1
解决办法
978
查看次数

在假设中跳过伪造的例子

故事:

我目前正在使用单元测试函数hypothesis自定义生成策略试图找到一个特定的输入来"打破"我当前的解决方案.以下是我的测试结果:

from solution import answer

# skipping mystrategy definition - not relevant

@given(mystrategy)
def test(l):
    assert answer(l) in {0, 1, 2}
Run Code Online (Sandbox Code Playgroud)

基本上,当answer()函数没有返回0或1或2 时,我正在寻找可能的输入.

以下是我当前工作流程的样子:

  • 运行测试
  • hypothesis找到一个产生以下内容的输入AssertionError:

    $ pytest test.py 
    =========================================== test session starts ============================================
    ...
    ------------------------------------------------ Hypothesis ------------------------------------------------
    Falsifying example: test(l=[[0], [1]])
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用此特定输入调试函数,尝试了解此输入/输出是否合法,并且函数正常工作

问题:

如何跳过这个伪造生成的例子([[0], [1]]在这种情况下)并要求hypothesis生成另一个?


问题也可以解释为:hypothesis如果找到伪造的例子并且生成更多伪造的例子,我可以要求不终止吗?

python testing unit-testing property-based-testing python-hypothesis

7
推荐指数
1
解决办法
555
查看次数

使用Hedgehog(或任何其他基于属性的测试框架)生成随机GADT的最安全方法

我有像这样的GADT:

data TType a where
    TInt  :: TType Int
    TBool :: TType Bool
Run Code Online (Sandbox Code Playgroud)

我想要一个像这样的功能:

genTType :: Gen (TType a)
Run Code Online (Sandbox Code Playgroud)

哪个可以生成TType类型的随机构造函数.我可以通过创建存在的合格数据类型来实现这一点

data AnyType = forall a . MkAnyType (TType a)
Run Code Online (Sandbox Code Playgroud)

然后生成随机数01(包括)并AnyType根据整数值创建.像这样:

intToAnyType :: Int -> AnyType
intToAnyType 0 = MkAnyType TInt
intToAnyType 1 = MkAnyType TBool
intToAnyType _ = error "Impossible happened"
Run Code Online (Sandbox Code Playgroud)

但这种方法对我来说有几个缺点:

  1. 没有外部类型安全.如果我向TType数据类型添加另一个构造函数,我可能忘记修复测试,编译器不会警告我这一点.
  2. 编译器无法阻止我写作intToAnyType 1 = MkAnyType TInt.
  3. 我不喜欢这个error.Int类型太宽泛了我.让这种模式匹配详尽无遗是件好事.

我可以在Haskell中做些什么来消除尽可能多的缺点?最好使用此模块的发电机:

haskell type-safety gadt property-based-testing haskell-hedgehog

7
推荐指数
1
解决办法
216
查看次数

在Hedgehog中通过'Gen'或'forAll'生成随机输入之间的区别

假设,我想在Haskell Sumhedgehog库的帮助下测试以下的associativity属性:

a <> (b <> c) ? (a <> b) <> c
Run Code Online (Sandbox Code Playgroud)

我实际上有两种方法来生成随机输入.

1.生成全部Gen(使用Gen'Applicative和Monad实例)

genTriple :: Get (Int, Int, Int)
genTriple = liftA3 (,,) Gen.enumBounded Gen.enumBounded Gen.enumBounded

prop_assoc :: Property
prop_assoc = property $ do
  (a, b, c) <- forAll genTriple
  (Sum a <> Sum b) <> Sum c === Sum a <> (Sum b <> Sum c)
Run Code Online (Sandbox Code Playgroud)

2.生成每个字段 forAll

prop_assoc :: Property
prop_assoc = property $ do
  a <- forAll Gen.enumBounded …
Run Code Online (Sandbox Code Playgroud)

testing automated-tests haskell property-based-testing haskell-hedgehog

7
推荐指数
1
解决办法
184
查看次数

一套快速检查测试与实现相匹配是好还是坏?

我正在尝试使用Haskell的QuickCheck,虽然我熟悉测试方法背后的概念,但这是我第一次尝试将它用于一个超出测试类似的项目的那个项目reverse . reverse == id.事情.我想知道将它应用于业务逻辑是否有用(我认为非常可能).

因此,我想测试的几个现有业务逻辑类型函数如下所示:

shouldDiscountProduct :: User -> Product -> Bool
shouldDiscountProduct user product =
  if M.isNothing (userDiscountCode user)
     then False
     else if (productDiscount product) then True
                                       else False
Run Code Online (Sandbox Code Playgroud)

对于此功能,我可以编写如下的QuickCheck规范:

data ShouldDiscountProductParams
  = ShouldDiscountProductParams User Product

instance Show ShouldDiscountProductParams where
  show (ShouldDiscountProductParams u p) =
    "ShouldDiscountProductParams:\n\n" <>
    "- " <> show u <> "\n\n" <>
    "- " <> show p

instance Arbitrary ShouldDiscountProductParams where
  arbitrary = ShouldDiscountProductParams <$> arbitrary <*> arbitrary

shouldDiscountProduct :: Spec
shouldDiscountProduct = …
Run Code Online (Sandbox Code Playgroud)

haskell functional-programming business-logic quickcheck property-based-testing

7
推荐指数
1
解决办法
171
查看次数