2016-04-06 4 views
1

Я использую Triq (erlang quickcheck), и у меня возникают проблемы с созданием набора nice правил для моей программы.Создание случайного правила для теста на основе свойств

То, что я хочу, чтобы создать вещи, которые выглядят следующим образом:

A -> B 

, где я хотел бы предоставить A и размер B, с последними не имея какое-либо dupicates.

Например, если я говорю, создайте мне правила с 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]} 

Примечание, я не хочу любые dupicates в B (это часть у меня возникают проблемы с). Кроме того, на самом деле не имеет значения, что B составлено из - оно может быть чем угодно, если оно отличается и без дубликатов.

Мои спецификации слишком запутаны, чтобы показать здесь, поэтому я бы предпочел.

ответ

1

Я не знаком с Triq, но в Prophe и Quviq's Qickcheck вы можете использовать ?SUCHTHAT условия, которые фильтруют «плохие» экземпляры.

Если сгенерированный экземпляр не удовлетворяет ограничению SUCHTHAT, он отбрасывается и не считается действительным тестом. Вы можете использовать этот механизм для создания списков указанного размера (то есть, что PropEr вызывает «векторы»), а затем отбрасывать те, у которых есть дубликаты, но я думаю, что слишком много экземпляров будут затем отброшены (см. Также ссылку).

Обычно более эффективно возиться с генератором, так что все экземпляры действительны в вашем случае, например, генерирование (3) X-times столько элементов, удаляя дубликаты и сохраняя столько, сколько вам нужно. Это может все еще потерпеть неудачу, и это провалится, поэтому вам нужно защититься от него.

Вот генератор для вашего случая, в исправном, вместе с манекеном свойством:

-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])]. 
+0

Спасибо, только один вопрос: почему мы формируем в 3 раза больше? Является ли номер три особенным, или вы имеете в виду, что нам просто нужно генерировать больше, чем нужно? – drozzy

+0

Нет, это не так, просто «гарантирует», что после удаления дубликатов останется достаточно четких элементов. – aronisstav

+0

Будете ли это _lould_ генерировать что-то? – drozzy