FsCheck:如何生成依赖于其他测试数据的测试数据?
Posted
技术标签:
【中文标题】FsCheck:如何生成依赖于其他测试数据的测试数据?【英文标题】:FsCheck: How to generate test data that depends on other test data? 【发布时间】:2018-03-31 20:43:33 【问题描述】:FsCheck 有一些简洁的默认Arbitrary
类型来生成测试数据。但是,如果我的某个考试日期取决于另一个考试日期怎么办?
例如,考虑string.Substring()
的属性,即生成的子字符串永远不会比输入字符串长:
[Fact]
public void SubstringIsNeverLongerThanInputString()
Prop.ForAll(
Arb.Default.NonEmptyString(),
Arb.Default.PositiveInt(),
(input, length) => input.Get.Substring(0, length.Get).Length <= input.Get.Length
).QuickCheckThrowOnFailure();
虽然Substring
的实现肯定是正确的,但这个属性失败了,因为最终会生成一个比生成的NonEmptyString
更长的PositiveInt
,从而导致异常。
收缩:NonEmptyString "a" PositiveInt 2 异常:System.ArgumentOutOfRangeException:索引和长度必须引用字符串中的位置。
我可以保护与 if (input.Length < length) return true;
的比较,但这样我最终会进行大量测试运行,甚至没有检查该属性。
如何告诉 FsCheck 只生成不超过输入字符串的PositiveInt
s?我想我必须使用 Gen<T>
类,但它的界面让我很困惑......我尝试了以下但仍然得到 PositiveInt
s 超过字符串:
var inputs = Arb.Default.NonEmptyString();
// I have no idea what I'm doing here...
var lengths = inputs.Generator.Select(s => s.Get.Length).ToArbitrary();
Prop.ForAll(
inputs,
lengths,
(input, length) => input.Get.Substring(0, length).Length <= input.Get.Length
).QuickCheckThrowOnFailure();
【问题讨论】:
fscheck.github.io/FsCheck/TestData.html 我已经多次浏览了这个网站,但仍然无法找到一种方法来做我想做的事。 【参考方案1】:您可以使用SelectMany
创建依赖于从另一个生成的值的生成器。这也允许您使用 LINQ 查询语法,例如
var gen = from s in Arb.Generate<NonEmptyString>()
from i in Gen.Choose(0, s.Get.Length - 1)
select Tuple.Create(s, i);
var p = Prop.ForAll(Arb.From(gen), t =>
var s = t.Item1.Get;
var len = t.Item2;
return s.Substring(0, len).Length <= s.Length;
);
Check.Quick(p);
【讨论】:
这是我可以在official docs 中找到的吗?如果不能,请添加您的参考资料? @GoodNightNerdPride - 我认为我没有看到太多关于 C# 互操作的文档,所以我可能是根据阅读源代码和来自gen
构建器的有根据的猜测发现的。 F# 计算表达式(如 gen ...
)与 C# LINQ 查询语法非常接近,因为它们是从相同的语法模式构建的(尽管 F# 支持更多功能)。
文档中没有太多关于 F# 计算表达式或 LINQ 语法的示例。这是一个例子github.com/fscheck/FsCheck/blob/master/examples/… LINQ 在TestData 页面的第二段中提到,这里有一个小例子:fscheck.github.io/FsCheck/TestData.html#Generators以上是关于FsCheck:如何生成依赖于其他测试数据的测试数据?的主要内容,如果未能解决你的问题,请参考以下文章
Expecto FsCheck在生成字符串时出现堆栈溢出异常
如何使FsCheck生成与MaxLengthAttribute相关的随机字符串?