0

For property-based testing, given a fixed list of values, I need to generate a variable-sized list where order is important and duplicates are allowed. For example, if my fixed list is

texts = ['t1', 't2', 't3', 't4']

I would like to generate different variations, e.g.

['t2']
['t4', 't1'] # Subset and different order
[]
['t3', 't1', 't2'] # Different order
['t4', 't4', 't4', 't1'] # Repetition of t4
['t1', 't2', 't1'] # Repetition but at different location
['t1', 't2']
['t2', 't1'] # different order from the one above and considered different.

What I have managed to use currently is the permutations strategy

from hypothesis import given, strategies as st

@given(st.permutations(texts))
def test_x(some_text):
   ...
   pass

But that does not give me variable size, repetitions

Other requirements:

  • How can I specify a maximum variable list of 20?
Georgy
  • 12,464
  • 7
  • 65
  • 73
RAbraham
  • 5,956
  • 8
  • 45
  • 80
  • 1
    `lists(sampled_from(texts), max_size=20)`? I'm just not sure what you mean by the "order is important" requirement. Could you clarify? – Georgy Jul 23 '20 at 20:23
  • @Georgy Thanks! I meant that the strategy should serve `['t1', 't2']` as well as `["t2", "t1"]` i.e permutations. – RAbraham Jul 23 '20 at 21:25

2 Answers2

3

You are looking for a combination of the lists and the sampled_from strategies:

from hypothesis import strategies as st

texts = ['t1', 't2', 't3', 't4']
lists_from_texts = st.lists(st.sampled_from(texts), max_size=20)

...

@given(lists_from_texts)
def test_x(some_text):
    ...

or if you want to be able to change the source list for different tests:

from typing import List


def lists_from_texts(source: List[str]) -> st.SearchStrategy[List[str]]:
    return st.lists(st.sampled_from(source), max_size=20)

...

@given(lists_from_texts(texts))
def test_x(some_text):
    ...
Georgy
  • 12,464
  • 7
  • 65
  • 73
-1

Since you want at most 20 items, generate a random number from 1 to 20:

import random
size = random.randint(1,20)

Then use that number to make N number of independent choices from your source list:

texts = ['t1', 't2', 't3', 't4']
random_texts = []
for _ in range(size):
    random_texts.append(random.choice(texts))
John Gordon
  • 29,573
  • 7
  • 33
  • 58
  • I wish I could select this answer too. Though I was using this question as a means to learn python-hypothesis, you showed me something I could use in other places as well. Thanks. upvoted. – RAbraham Jul 24 '20 at 17:52