Skip to content

Commit 0d9699b

Browse files
vahid-ahmadiclaude
andauthored
Add test suite ensuring key variable reforms produce impacts (#1613)
* Add test suite ensuring key variable reforms produce impacts Tests 6 common parametric reforms (income tax rate, personal allowance, NI rate, child benefit, UC standard allowance, fuel duty) to verify each produces a different result than baseline. Catches silent failures where reforms run without error but have no effect. Fixes #930. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Rename test file to avoid collision and fix formatting Rename test_reform_impacts.py to test_parametric_reform_impacts.py to avoid name collision with existing microsimulation/test_reform_impacts.py. Apply ruff formatting. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent baf820a commit 0d9699b

2 files changed

Lines changed: 151 additions & 0 deletions

File tree

changelog.d/930.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Add test suite verifying that key parametric reforms produce non-zero impacts
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
"""
2+
Tests that key parametric reforms produce non-zero impacts.
3+
4+
These tests catch silent failures where a reform runs without error
5+
but produces the same result as the baseline (e.g., due to a
6+
parameter path being wrong or a formula not picking up the change).
7+
"""
8+
9+
import pytest
10+
from policyengine_uk.model_api import Scenario
11+
from policyengine_uk import Microsimulation
12+
13+
YEAR = 2025
14+
15+
BASE_SITUATION = {
16+
"people": {
17+
"adult": {
18+
"age": {YEAR: 35},
19+
"employment_income": {YEAR: 40_000},
20+
"hours_worked": {YEAR: 40},
21+
},
22+
"child": {
23+
"age": {YEAR: 5},
24+
},
25+
},
26+
"benunits": {
27+
"benunit": {
28+
"members": ["adult", "child"],
29+
},
30+
},
31+
"households": {
32+
"household": {
33+
"members": ["adult", "child"],
34+
"region": {YEAR: "LONDON"},
35+
},
36+
},
37+
}
38+
39+
40+
def _reform_changes_variable(parameter_changes, variable, situation=None):
41+
"""Check that applying a parameter reform changes a variable's value."""
42+
sit = situation or BASE_SITUATION
43+
baseline = Microsimulation(situation=sit)
44+
scenario = Scenario(parameter_changes=parameter_changes)
45+
reformed = Microsimulation(situation=sit, scenario=scenario)
46+
47+
baseline_val = baseline.calculate(variable, YEAR).values[0]
48+
reformed_val = reformed.calculate(variable, YEAR).values[0]
49+
return baseline_val != reformed_val
50+
51+
52+
class TestReformImpacts:
53+
"""Verify that common parametric reforms produce non-zero impacts."""
54+
55+
def test_income_tax_rate_reform(self):
56+
"""Changing the basic rate of income tax should affect income tax."""
57+
assert _reform_changes_variable(
58+
{"gov.hmrc.income_tax.rates.uk[0].rate": {str(YEAR): 0.30}},
59+
"income_tax",
60+
)
61+
62+
def test_personal_allowance_reform(self):
63+
"""Changing the personal allowance should affect income tax."""
64+
assert _reform_changes_variable(
65+
{
66+
"gov.hmrc.income_tax.allowances.personal_allowance.amount": {
67+
str(YEAR): 15_000
68+
}
69+
},
70+
"income_tax",
71+
)
72+
73+
def test_ni_rate_reform(self):
74+
"""Changing the NI employee rate should affect national insurance."""
75+
assert _reform_changes_variable(
76+
{
77+
"gov.hmrc.national_insurance.class_1.rates.employee.main": {
78+
str(YEAR): 0.20
79+
}
80+
},
81+
"national_insurance",
82+
)
83+
84+
def test_child_benefit_reform(self):
85+
"""Changing the eldest child benefit amount should affect child benefit."""
86+
assert _reform_changes_variable(
87+
{"gov.hmrc.child_benefit.amount.eldest": {str(YEAR): 30}},
88+
"child_benefit",
89+
)
90+
91+
def test_uc_standard_allowance_reform(self):
92+
"""Changing UC standard allowance should affect universal credit."""
93+
low_income_situation = {
94+
"people": {
95+
"adult": {
96+
"age": {YEAR: 30},
97+
"employment_income": {YEAR: 5_000},
98+
"hours_worked": {YEAR: 10},
99+
},
100+
},
101+
"benunits": {
102+
"benunit": {
103+
"members": ["adult"],
104+
"would_claim_uc": {YEAR: True},
105+
},
106+
},
107+
"households": {
108+
"household": {
109+
"members": ["adult"],
110+
"region": {YEAR: "LONDON"},
111+
},
112+
},
113+
}
114+
assert _reform_changes_variable(
115+
{
116+
"gov.dwp.universal_credit.standard_allowance.amount.SINGLE_OLD": {
117+
str(YEAR): 500
118+
}
119+
},
120+
"universal_credit",
121+
situation=low_income_situation,
122+
)
123+
124+
def test_fuel_duty_reform(self):
125+
"""Changing fuel duty should affect fuel duty paid."""
126+
driver_situation = {
127+
"people": {
128+
"adult": {
129+
"age": {YEAR: 35},
130+
"employment_income": {YEAR: 30_000},
131+
},
132+
},
133+
"benunits": {
134+
"benunit": {
135+
"members": ["adult"],
136+
},
137+
},
138+
"households": {
139+
"household": {
140+
"members": ["adult"],
141+
"region": {YEAR: "NORTH_EAST"},
142+
"petrol_spending": {YEAR: 2_000},
143+
},
144+
},
145+
}
146+
assert _reform_changes_variable(
147+
{"gov.hmrc.fuel_duty.petrol_and_diesel": {str(YEAR): 1.0}},
148+
"fuel_duty",
149+
situation=driver_situation,
150+
)

0 commit comments

Comments
 (0)