How to Use Hypothesis Strategies for Lists of Text in Python
Generate random lists of non-empty strings with Hypothesis and verify that joining them with a comma-and-space separator meets expected length and containment invariants.
pip install hypothesis
Python code
33 linesfrom hypothesis import given, strategies as st
from hypothesis import example
@given(st.lists(st.text(min_size=1, max_size=10), min_size=1, max_size=5))
def test_joined_string_length(items):
"""Each text is non-empty; a joined string should be at least as long
as the number of items (separator adds characters)."""
joined = ", ".join(items)
assert len(joined) > len(items) - 1
assert all(item in joined for item in items)
if __name__ == "__main__":
# Run the test with 100 examples to demonstrate
import sys
# Use hypothesis's own runner to produce output
from hypothesis import settings
# Wrap the test to capture results
results = []
@settings(max_examples=100)
def run():
test_joined_string_length()
try:
run()
print("Hypothesis test passed: all generated lists of text satisfied assertions.")
except Exception as e:
print(f"Hypothesis test failed: {e}", file=sys.stderr)
sys.exit(1)
Output
Hypothesis test passed: all generated lists of text satisfied assertions.
How it works
The @given decorator defines a strategy st.lists(st.text(min_size=1, max_size=10), min_size=1, max_size=5) that generates test data — each list contains 1 to 5 strings, each string 1 to 10 characters. The assertions verify that joining the list with ', ' produces a string longer than the number of items minus one, and every original item appears in the joined result. Hypothesis runs the test with many examples (default 100) to explore edge cases. The @example decorator (imported but unused here) can also force specific inputs for regression testing.
Common mistakes
- Forgetting to specify `min_size` for text, which allows empty strings that break assumptions.
- Importing `example` but never using it when you intend to include a fixed test case.
- Running the test without `hypothesis` installed, causing an ImportError.
Variations
- Use `st.lists(st.text(), max_size=10)` to allow empty strings and adjust assertions accordingly.
- Use `@example(["a", "b"])` to inject a specific list for a regression test.
Real-world use cases
- Property-based testing of string formatting logic, such as CSV or message assemblers that join user-provided fields.
- Verifying that search or indexing code correctly handles lists of varied text lengths and content.
- Validating that API serialization or filtering functions preserve all input elements after transformation.
Sponsored
More from Testing & modern typing
- Capture stdout and stderr with pytest capsys easy
- Characterization Test for Legacy Python Code medium
- Dataclass with Type Hints Fields in Python easy
- Dependency Injection in Python for Testability easy
- Design Data Helpers with Python TypedDict and Literal easy
- Fix and Test a Regression Bug in Python with Unit Tests easy
Keep learning
Related tutorials and quizzes for this topic.