为基于 属性 的测试生成随机规则
Generating a random rule for property based test
我正在使用 Triq(erlang quickcheck),但我无法为我的程序生成一组 nice 规则。
我想要生成的东西看起来像这样:
A -> B
我想提供 A
和 B
的大小,后者没有任何重复项。
例如,如果我说用 L.H.S 生成我的规则。 [a]
和 R.H.S。尺寸 4(即 A = [a]
和 size(B) = 4
)我想要这样的东西:
{rule, [a], [1,2,4,5]}
{rule, [a], [a,d,c,e]}
{rule, [a], [q,d,3,4]}
请注意,我不想在 B 中出现 任何 重复(这是我遇到问题的部分)。此外,B 由什么组成并不重要 - 它可以是任何东西,只要它是不同的并且没有重复即可。
我的规范太乱了,不能在这里展示,所以我不想展示。
我不熟悉 Triq,但在 PropEr 和 Quviq 的 Qickcheck 中,您可以使用 ?SUCHTHAT
条件过滤 'bad' 个实例。
如果生成的实例不满足 ?SUCHTHAT 约束,它将被丢弃并且不计为有效测试。您可以使用此机制生成指定大小的列表(即 PropEr 调用的列表 'vectors'),然后丢弃那些具有重复项的列表,但我认为随后会丢弃太多实例(另请参阅 link).
修改生成器通常更有效,这样 所有 个实例都是有效的,在您的情况下,例如生成 (3) X 倍的元素,删除重复项并根据需要保留尽可能多的元素。这个还是会失败,会失败,所以要防着。
这是适合您的案例的生成器,在 PropEr 中,还有一个虚拟机 属性:
-module(dummy).
-export([rule_prop/0]).
-include_lib("proper/include/proper.hrl").
-define(X, 5).
rule_prop() ->
?FORALL(_, rule_gen(integer(), 4, integer()), true).
rule_gen(A, SizeB, TypeB) ->
?LET(
EnoughB,
?SUCHTHAT(
NoDupB,
?LET(
ManyB,
vector(?X * SizeB, TypeB),
no_dups(ManyB)
),
length(NoDupB) >= SizeB
),
begin
B = lists:sublist(EnoughB, SizeB),
{rule, A, B}
end).
no_dups([]) ->
[];
no_dups([A|B]) ->
[A | no_dups([X || X <- B, X =/= A])].
我正在使用 Triq(erlang quickcheck),但我无法为我的程序生成一组 nice 规则。
我想要生成的东西看起来像这样:
A -> B
我想提供 A
和 B
的大小,后者没有任何重复项。
例如,如果我说用 L.H.S 生成我的规则。 [a]
和 R.H.S。尺寸 4(即 A = [a]
和 size(B) = 4
)我想要这样的东西:
{rule, [a], [1,2,4,5]}
{rule, [a], [a,d,c,e]}
{rule, [a], [q,d,3,4]}
请注意,我不想在 B 中出现 任何 重复(这是我遇到问题的部分)。此外,B 由什么组成并不重要 - 它可以是任何东西,只要它是不同的并且没有重复即可。
我的规范太乱了,不能在这里展示,所以我不想展示。
我不熟悉 Triq,但在 PropEr 和 Quviq 的 Qickcheck 中,您可以使用 ?SUCHTHAT
条件过滤 'bad' 个实例。
如果生成的实例不满足 ?SUCHTHAT 约束,它将被丢弃并且不计为有效测试。您可以使用此机制生成指定大小的列表(即 PropEr 调用的列表 'vectors'),然后丢弃那些具有重复项的列表,但我认为随后会丢弃太多实例(另请参阅 link).
修改生成器通常更有效,这样 所有 个实例都是有效的,在您的情况下,例如生成 (3) X 倍的元素,删除重复项并根据需要保留尽可能多的元素。这个还是会失败,会失败,所以要防着。
这是适合您的案例的生成器,在 PropEr 中,还有一个虚拟机 属性:
-module(dummy).
-export([rule_prop/0]).
-include_lib("proper/include/proper.hrl").
-define(X, 5).
rule_prop() ->
?FORALL(_, rule_gen(integer(), 4, integer()), true).
rule_gen(A, SizeB, TypeB) ->
?LET(
EnoughB,
?SUCHTHAT(
NoDupB,
?LET(
ManyB,
vector(?X * SizeB, TypeB),
no_dups(ManyB)
),
length(NoDupB) >= SizeB
),
begin
B = lists:sublist(EnoughB, SizeB),
{rule, A, B}
end).
no_dups([]) ->
[];
no_dups([A|B]) ->
[A | no_dups([X || X <- B, X =/= A])].