使用C#和FsCheck生成随机字符串

7

作为第一步,我希望逐渐将FsCheck集成到我的C#测试代码中。

我想随机生成部分输入数据。

以下是我生成随机字符串的方法:


static string RandomString() {
  var kgen = Gen.Constant(Gen.Sized(g => Gen.OneOf(Arb.Generate())));
  var sgen = Gen.Sample(1, 10, kgen).First();
  var str = Gen.Eval(10, Random.StdGen.NewStdGen(0, 1000), sgen);
  return str;
}

如果我多次调用它,我每次都会得到相同的字符串。
我该如何每次获得不同的字符串和/或正确编写此代码?
1个回答

9

您应该使用属性替换测试,而不是试图手动生成随机字符串并在测试中使用它们。FsCheck并不适合作为随机生成器,尽管可以将其强制转换为该功能。比如:

var maxLength = 10
return Arb.Generate<string>().Sample(maxLength, 1).Single()

该函数应该生成一个长度最多为10的新随机字符串,"大多数情况下"是这样的,即如果我没记错的话,随机种子是基于时间的。所以如果在同一时间间隔内调用它两次,它将返回相同的字符串。

使用这种方法不会让您利用缩小和Prop中的API来观察和分类生成的数据,例如限制它:https://fscheck.github.io/FsCheck/Properties.html


+1 这回答了我的问题,@Kurt Schelfthout。我理解通过属性进行测试的概念,但由于我已经有了一个完整的测试项目。我想在测试中添加随机数据,就像这样。你认为这是一条不好的路吗?你认为添加一个新的F#项目到解决方案中,并根据属性思考新的测试(例如:以旧标准测试为“规范”)是否更好? - gsscoder
1
我明白 - 我自己还没有尝试过,但是我的建议是保留现有的测试(这可以确保您不会失去任何测试覆盖率),并逐渐用“真实”属性增强现有的测试。然后,随着您对基于属性的测试的信心增强,您可以考虑删除一些多余的现有测试。 - Kurt Schelfthout
2
顺便提一下,您应该能够在同一个项目中混合使用两种方法。我经常这样做。例如,对于特定的错误重现,如果我单独添加了具有失败示例的特定测试,即使该反例最初是通过基于属性的测试发现的,我也会感觉更加安全。 - Kurt Schelfthout
感谢您的建议。如果我必须与新的基于属性的测试并行进行,我更喜欢在F#中编写一个新的测试库,这对于FsCheck来说更自然(我猜)。 :) - gsscoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接