-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path17_hypothesis_bridge.py
More file actions
159 lines (110 loc) · 4.68 KB
/
Copy path17_hypothesis_bridge.py
File metadata and controls
159 lines (110 loc) · 4.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
"""Hypothesis Strategy Bridge — Property-Based Testing with DataForge.
Real-world scenario: You use Hypothesis for property-based testing and want
to use DataForge's realistic data as test inputs. The hypothesis bridge
creates Hypothesis strategies from DataForge fields, allowing you to combine
realistic fake data with Hypothesis's shrinking and test-case generation.
This example demonstrates:
- strategy(): single-field Hypothesis strategies
- forge_strategy(): multi-field dict strategies
- Writing property-based tests with @given
- Combining DataForge strategies with other Hypothesis strategies
NOTE: This example requires the ``hypothesis`` package.
Install with: pip install hypothesis
"""
try:
import hypothesis # noqa: F401
except ModuleNotFoundError:
print("This example requires 'hypothesis'. Install with: pip install hypothesis")
print("Skipping example.")
raise SystemExit(0)
from hypothesis import given, settings
from hypothesis import find # noqa: E402
from dataforge.compat.hypothesis import forge_strategy, strategy # noqa: E402
# --- Example 1: Single-field strategies -----------------------------------
print("=== Single-Field Strategies ===\n")
# Create strategies from DataForge field names
email_st = strategy("email")
name_st = strategy("first_name")
city_st = strategy("city")
# Find an example that satisfies a trivial condition
example_email = find(email_st, lambda x: "@" in x)
example_name = find(name_st, lambda x: len(x) > 0)
print(f" Example email: {example_email}")
print(f" Example name: {example_name}")
print()
# --- Example 2: Property-based test — email validation --------------------
print("=== Property: All Emails Contain '@' ===\n")
@given(email=strategy("email"))
@settings(max_examples=50)
def test_email_has_at_sign(email: str) -> None:
assert "@" in str(email), f"Email missing '@': {email}"
test_email_has_at_sign()
print(" PASS: 50 generated emails all contain '@'")
print()
# --- Example 3: Property-based test — name is non-empty -------------------
print("=== Property: Names Are Non-Empty ===\n")
@given(name=strategy("full_name"))
@settings(max_examples=50)
def test_name_not_empty(name: str) -> None:
assert len(str(name).strip()) > 0, "Name should not be empty"
test_name_not_empty()
print(" PASS: 50 generated names are all non-empty")
print()
# --- Example 4: Multi-field strategies (dict output) ----------------------
print("=== Multi-Field Strategy (Dict Output) ===\n")
# Using a list of field names
user_st = forge_strategy(["first_name", "email", "city"])
example_user = find(user_st, lambda d: "first_name" in d)
print(f" Example user dict: {example_user}")
print()
# Using a column→field mapping
contact_st = forge_strategy(
{
"name": "full_name",
"mail": "email",
"phone": "phone_number",
}
)
example_contact = find(contact_st, lambda d: "name" in d)
print(f" Example contact dict: {example_contact}")
print()
# --- Example 5: Property test with multi-field strategy -------------------
print("=== Property: User Records Have Required Keys ===\n")
@given(data=forge_strategy(["first_name", "last_name", "email", "city"]))
@settings(max_examples=30)
def test_user_has_required_keys(data: dict) -> None:
assert "first_name" in data
assert "last_name" in data
assert "email" in data
assert "city" in data
assert all(v is not None for v in data.values()), "No values should be None"
test_user_has_required_keys()
print(" PASS: 30 generated user records all have required keys")
print()
# --- Example 6: Locale-specific strategies --------------------------------
print("=== Locale-Specific Strategies ===\n")
jp_name_st = strategy("full_name", locale="ja_JP")
de_name_st = strategy("full_name", locale="de_DE")
jp_name = find(jp_name_st, lambda x: len(str(x)) > 0)
de_name = find(de_name_st, lambda x: len(str(x)) > 0)
print(f" Japanese name: {jp_name}")
print(f" German name: {de_name}")
print()
# --- Example 7: Combining with standard Hypothesis strategies -------------
print("=== Combining with Standard Hypothesis Strategies ===\n")
from hypothesis import strategies as st # noqa: E402
@given(
name=strategy("full_name"),
age=st.integers(min_value=18, max_value=99),
score=st.floats(min_value=0.0, max_value=100.0, allow_nan=False),
)
@settings(max_examples=30)
def test_mixed_strategies(name: str, age: int, score: float) -> None:
assert len(str(name)) > 0
assert 18 <= age <= 99
assert 0.0 <= score <= 100.0
test_mixed_strategies()
print(" PASS: 30 examples with mixed DataForge + Hypothesis strategies")
print()
print("Hypothesis + DataForge enables powerful property-based testing")
print("with realistic, locale-aware fake data.")