1

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?
2
  • 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? Commented Jul 23, 2020 at 20:23
  • @Georgy Thanks! I meant that the strategy should serve ['t1', 't2'] as well as ["t2", "t1"] i.e permutations. Commented Jul 23, 2020 at 21:25

2 Answers 2

4

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):
    ...
Sign up to request clarification or add additional context in comments.

Comments

-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))

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.