Boost Your Python Tests with Hypothesis: Property‑Based Testing Made Easy
Learn how to install and use the Hypothesis library for Python to perform property‑based testing, automatically generating diverse inputs, covering edge cases, and enhancing test coverage with examples on arithmetic properties, list sorting, custom strategies, settings, and real‑world scenarios like JSON and URL validation.
Installation
Install the Hypothesis library via pip:
pip install hypothesisWhat is Property‑Based Testing
Unlike traditional "given input – expected output" tests, property‑based testing focuses on general properties of a function. For example, the commutative property of addition states that for any two integers a and b, a + b == b + a. Hypothesis generates many input combinations to try to falsify such properties.
Basic Usage
Example 1: Verify the addition commutative property
from hypothesis import given
import hypothesis.strategies as st
@given(st.integers(), st.integers())
def test_add_commutative(a, b):
assert a + b == b + aRun the test with pytest: pytest test_file.py Hypothesis will automatically generate many integer pairs to validate the assertion.
Example 2: Verify that the smallest element appears first after sorting a list
from hypothesis import given
import hypothesis.strategies as st
@given(st.lists(st.integers(), min_size=1))
def test_sorted_list_first_is_min(lst):
sorted_lst = sorted(lst)
assert sorted_lst[0] == min(lst)Hypothesis creates lists of varying lengths and contents, including negative numbers and duplicates.
Common Strategies
Hypothesis provides many built‑in strategies for data generation. Below is an example of a custom integer range strategy:
@given(st.integers(min_value=1, max_value=100))
def test_number_in_range(n):
assert 1 <= n <= 100Advanced Features
1. Set maximum number of examples
from hypothesis import settings
@settings(max_examples=500)
@given(st.integers())
def test_large_data(n):
...2. Limit execution time (deadline in milliseconds)
@settings(deadline=500) # milliseconds3. Verbose mode to print generated data for debugging
from hypothesis import settings, Verbosity
@settings(verbosity=Verbosity.verbose)
@given(st.integers())
def test_verbose(n):
assert n * 2 % 2 == 0Practical Scenarios
Scenario 1: Validate a JSON encoder/decoder
import json
from hypothesis import given
from hypothesis.strategies import text
@given(text())
def test_json_encode_decode(s):
assert json.loads(json.dumps({"text": s}))["text"] == sScenario 2: Validate URL quoting and unquoting
from urllib.parse import quote, unquote
from hypothesis import given
from hypothesis.strategies import text
@given(text())
def test_url_quote_unquote(s):
encoded = quote(s)
decoded = unquote(encoded)
assert decoded == sPros Summary
Precautions
Not suitable for tests that depend on external services.
May slow down performance‑critical functions.
Can generate unreasonable extreme values; strategies should be constrained appropriately.
Recommended Project Structure
my_project/
├── src/
│ └── my_module.py
└── tests/
├── test_my_module.py
└── __init__.py
# In test_my_module.py, use @given to write property‑based tests.Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
