我可以找到许多为发生器设置最大尺寸的示例,但是如何在最小和最大长度之间生成列表?
我正在尝试用基于属性的测试 (PBT) 替换一些旧的单元测试,具体地用scala和scalatest - scalacheck但我认为这个问题更普遍。简化的情况是,如果我有要测试的方法:
def upcaseReverse(s:String) = s.toUpperCase.reverse
Run Code Online (Sandbox Code Playgroud)
通常,我会编写单元测试,例如:
assertEquals("GNIRTS", upcaseReverse("string"))
assertEquals("", upcaseReverse(""))
// ... corner cases I could think of
Run Code Online (Sandbox Code Playgroud)
所以,对于每个测试,我写出我期望的输出,没问题。现在,使用 PBT,它会像:
property("strings are reversed and upper-cased") {
forAll { (s: String) =>
assert ( upcaseReverse(s) == ???) //this is the problem right here!
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编写一个对所有String输入都适用的测试时,我发现自己不得不在测试中再次编写方法的逻辑。在这种情况下,测试将如下所示:
assert ( upcaseReverse(s) == s.toUpperCase.reverse)
Run Code Online (Sandbox Code Playgroud)
也就是说,我必须在测试中编写实现以确保输出正确。有没有办法解决这个问题?我是否误解了 PBT,我是否应该测试其他属性,例如:
这也是合理的,但听起来很做作,不太清楚。任何在 PBT 方面有更多经验的人都可以在这里解释一下吗?
编辑:按照@Eric 的消息来源,我找到了这篇文章,并且有一个我的意思的示例(在再次应用类别时):测试times( F#) 中的方法 …
我想写一个如下属性:
(prop/for-all [x (gen/nat)
y (gen/nat)]
(= (g x y) (f x y)))
Run Code Online (Sandbox Code Playgroud)
但是,该物业仅在何时持有x > y.表达此属性的前提条件的正确方法是什么?(更好的是,我怎么能写出这个属性,这个属性y生成的自然数小于x?)
其他语言有基于属性的测试库,如Haskell QuickCheck.如何Clojure的规格从这样的库有什么不同?或者它只是Clojure的基于属性的测试框架?
我正在使用Scalatest 3.1.0-SNAP13,但无法找到如何从此PR中指定 init 种子选项。我正在使用 SBT 来运行测试,因此如果有一种方法可以指定此选项build.sbt将是理想的。
我用几个自定义生成器定义了一个类型,以使 FsCheck 生成几个类型的自定义实例。但是对于其中一种复杂类型,我想先使用默认的 FsCheck 生成,然后再调整结果。这是一个(简化的)代码:
type CustomGenerators =
static member FirstCustomType() = /* function that returns FirstCustomType */
static member SecondCustomType() =
Arb.generate<SecondCustomType>
|> Gen.map (fun x -> /* adjust some data in the generated instance */)
|> Arb.fromGen
Run Code Online (Sandbox Code Playgroud)
问题是当 SecondCustomType() 静态方法调用 Arb.generate 时,它会立即调用 SecondCustomType() 导致无限递归。我知道 Arb.generate 必须尊重自定义生成器,所以这就是它调用静态 SecondCustomType() 的原因,但我需要调用 SecondCustomType 的默认(非自定义)Arb.generate 实现。我无法从不同类型调用实现,因为我的自定义生成器使用 FirstCustomType 的自定义生成器,因此默认 SecondCustomType 实现必须知道 CustomGenerators 类型中定义的所有自定义生成器。这是一个糟糕的圈子,我还没有找到一个干净的解决方案(只有解决方法)。
我在golang中运行一些测试,我想避免运行慢速,例如这个使用bcrypt所以它很慢:
// +build slow
package services
import (
"testing"
"testing/quick"
)
// using bcrypt takes too much time, reduce the number of iterations.
var config = &quick.Config{MaxCount: 20}
func TestSignaturesAreSame(t *testing.T) {
same := func(simple string) bool {
result, err := Encrypt(simple)
success := err == nil && ComparePassWithHash(simple, result)
return success
}
if err := quick.Check(same, config); err != nil {
t.Error(err)
}
}
Run Code Online (Sandbox Code Playgroud)
为了避免在每次迭代中运行它,我都设置了// +build slow标志.这应该只在执行时运行,go test -tags slow但不幸的是它每次都在运行(-v标志显示它正在运行).
知道什么是错的吗?
我正在尝试使用 FsCheck 进行基于属性的测试,但我似乎无法弄清楚如何让 FsCheck 使用我已注册的基因。下面是为域生成类型的代码:
module Flips.Gens
open Flips.Domain
open FsCheck
type Silly = {
Name : string
}
let SillyGen () =
gen {
let! NonEmptyString name = Arb.generate<NonEmptyString>
return { Name = name}
}
type Domain () =
static member ArbSillyGen () = Arb.fromGen (SillyGen ())
Run Code Online (Sandbox Code Playgroud)
这是示例测试
module Flips.Tests
open Xunit
open FsCheck
open FsCheck.Xunit
open Flips.Gens
do Arb.register<Domain> () |> ignore
module Tests =
[<Property>]
let ``Silly Name is NonEmptyString`` (silly:Silly) =
let isNullOrEmpty = System.String.IsNullOrEmpty silly.Name …Run Code Online (Sandbox Code Playgroud) scalatest ×3
clojure ×2
f# ×2
fscheck ×2
scalacheck ×2
testing ×2
unit-testing ×2
clojure.spec ×1
go ×1
quickcheck ×1
scala ×1
xunit ×1