import numpy as np
import pytest
import scirs2
class TestPairedTTestBasics:
def test_paired_significant_difference(self):
before = np.array([10.0, 12.0, 15.0, 11.0, 14.0, 13.0])
after = np.array([15.0, 16.0, 18.0, 14.0, 17.0, 16.0])
result = scirs2.ttest_rel_py(before, after)
assert "statistic" in result
assert "pvalue" in result
assert "df" in result
assert result["df"] == 5.0 assert result["pvalue"] < 0.2
def test_paired_no_difference(self):
np.random.seed(42)
before = np.array([10.0, 12.0, 15.0, 11.0, 14.0, 13.0])
after = before + np.random.normal(0, 0.1, 6)
result = scirs2.ttest_rel_py(before, after)
assert result["pvalue"] > 0.05
def test_paired_identical_arrays(self):
a = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
b = a.copy()
result = scirs2.ttest_rel_py(a, b)
assert "statistic" in result
assert "pvalue" in result
def test_paired_negative_difference(self):
before = np.array([20.0, 22.0, 25.0, 21.0, 24.0, 23.0])
after = np.array([15.0, 17.0, 20.0, 16.0, 19.0, 18.0])
result = scirs2.ttest_rel_py(before, after)
assert result["pvalue"] < 0.01
assert result["statistic"] > 0
def test_paired_small_sample(self):
before = np.array([10.0, 15.0, 12.0])
after = np.array([12.0, 17.0, 14.0])
result = scirs2.ttest_rel_py(before, after)
assert result["df"] == 2.0 assert "statistic" in result
assert "pvalue" in result
def test_paired_large_sample(self):
np.random.seed(42)
n = 100
before = np.random.normal(10, 2, n)
after = before + np.random.normal(0.5, 0.5, n)
result = scirs2.ttest_rel_py(before, after)
assert result["df"] == 99.0 assert "statistic" in result
assert "pvalue" in result
class TestPairedTTestAlternatives:
def test_alternative_two_sided(self):
before = np.array([10.0, 12.0, 15.0, 11.0, 14.0])
after = np.array([15.0, 17.0, 20.0, 16.0, 19.0])
result1 = scirs2.ttest_rel_py(before, after)
result2 = scirs2.ttest_rel_py(before, after, alternative="two-sided")
result3 = scirs2.ttest_rel_py(before, after, alternative="two_sided")
assert result1["pvalue"] == result2["pvalue"]
assert result1["pvalue"] == result3["pvalue"]
assert result1["statistic"] == result2["statistic"]
def test_alternative_less(self):
before = np.array([10.0, 12.0, 15.0, 11.0, 14.0])
after = np.array([15.0, 17.0, 20.0, 16.0, 19.0])
result = scirs2.ttest_rel_py(before, after, alternative="less")
assert "pvalue" in result
assert "statistic" in result
def test_alternative_greater(self):
before = np.array([20.0, 22.0, 25.0, 21.0, 24.0])
after = np.array([15.0, 17.0, 20.0, 16.0, 19.0])
result = scirs2.ttest_rel_py(before, after, alternative="greater")
assert "pvalue" in result
assert "statistic" in result
def test_invalid_alternative(self):
a = np.array([1.0, 2.0, 3.0])
b = np.array([2.0, 3.0, 4.0])
with pytest.raises(RuntimeError, match="Invalid alternative"):
scirs2.ttest_rel_py(a, b, alternative="invalid")
class TestPairedTTestEdgeCases:
def test_different_lengths(self):
a = np.array([1.0, 2.0, 3.0])
b = np.array([1.0, 2.0, 3.0, 4.0])
with pytest.raises(RuntimeError):
scirs2.ttest_rel_py(a, b)
def test_empty_arrays(self):
a = np.array([])
b = np.array([])
with pytest.raises(RuntimeError):
scirs2.ttest_rel_py(a, b)
def test_single_element(self):
a = np.array([1.0])
b = np.array([2.0])
with pytest.raises(RuntimeError):
scirs2.ttest_rel_py(a, b)
def test_two_elements(self):
a = np.array([1.0, 2.0])
b = np.array([3.0, 4.0])
result = scirs2.ttest_rel_py(a, b)
assert result["df"] == 1.0 assert "statistic" in result
assert "pvalue" in result
def test_constant_differences(self):
a = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
b = np.array([2.0, 3.0, 4.0, 5.0, 6.0])
result = scirs2.ttest_rel_py(a, b)
assert "statistic" in result
assert "pvalue" in result
def test_with_nan(self):
a = np.array([1.0, 2.0, np.nan, 4.0, 5.0])
b = np.array([2.0, 3.0, 4.0, 5.0, 6.0])
try:
result = scirs2.ttest_rel_py(a, b)
assert (np.isnan(result["statistic"]) or np.isinf(result["statistic"]) or
np.isnan(result["pvalue"]) or result["pvalue"] == 0.0)
except RuntimeError:
pass
def test_with_inf(self):
a = np.array([1.0, 2.0, np.inf, 4.0, 5.0])
b = np.array([2.0, 3.0, 4.0, 5.0, 6.0])
try:
result = scirs2.ttest_rel_py(a, b)
assert (np.isinf(result["statistic"]) or np.isnan(result["statistic"]) or
np.isinf(result["pvalue"]) or np.isnan(result["pvalue"]))
except RuntimeError:
pass
class TestPairedTTestNumericalAccuracy:
def test_large_values(self):
before = np.array([1e10, 1.1e10, 1.2e10, 1.3e10, 1.4e10])
after = np.array([1.1e10, 1.2e10, 1.3e10, 1.4e10, 1.5e10])
result = scirs2.ttest_rel_py(before, after)
assert "statistic" in result
assert 0 <= result["pvalue"] <= 1
def test_small_values(self):
before = np.array([1e-10, 1.1e-10, 1.2e-10, 1.3e-10, 1.4e-10])
after = np.array([1.1e-10, 1.2e-10, 1.3e-10, 1.4e-10, 1.5e-10])
result = scirs2.ttest_rel_py(before, after)
assert np.isfinite(result["statistic"])
assert 0 <= result["pvalue"] <= 1
def test_very_small_differences(self):
before = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
after = before + 1e-10
result = scirs2.ttest_rel_py(before, after)
assert "pvalue" in result
class TestPairedTTestStatisticalProperties:
def test_symmetry(self):
np.random.seed(42)
a = np.array([10.0, 12.0, 15.0, 11.0, 14.0]) + np.random.normal(0, 0.1, 5)
b = np.array([15.0, 17.0, 20.0, 16.0, 19.0]) + np.random.normal(0, 0.1, 5)
result_ab = scirs2.ttest_rel_py(a, b, alternative="two-sided")
result_ba = scirs2.ttest_rel_py(b, a, alternative="two-sided")
if np.isfinite(result_ab["statistic"]) and np.isfinite(result_ba["statistic"]):
assert abs(result_ab["statistic"] + result_ba["statistic"]) < 1e-6
assert abs(result_ab["pvalue"] - result_ba["pvalue"]) < 1e-10
def test_degrees_of_freedom(self):
for n in [3, 5, 10, 20, 50]:
np.random.seed(42)
a = np.random.normal(0, 1, n)
b = np.random.normal(0.5, 1, n)
result = scirs2.ttest_rel_py(a, b)
assert result["df"] == float(n - 1)
def test_statistic_magnitude(self):
np.random.seed(42)
before = np.random.normal(10, 2, 50)
after_small = before + np.random.normal(0.1, 0.5, 50)
result_small = scirs2.ttest_rel_py(before, after_small)
after_large = before + np.random.normal(5.0, 0.5, 50)
result_large = scirs2.ttest_rel_py(before, after_large)
if np.isfinite(result_large["statistic"]) and np.isfinite(result_small["statistic"]):
assert abs(result_large["statistic"]) > abs(result_small["statistic"])
assert result_large["pvalue"] < result_small["pvalue"]
def test_sample_size_effect(self):
np.random.seed(42)
before_small = np.random.normal(10, 2, 10)
after_small = before_small + np.random.normal(0.5, 0.3, 10)
result_small = scirs2.ttest_rel_py(before_small, after_small)
before_large = np.random.normal(10, 2, 100)
after_large = before_large + np.random.normal(0.5, 0.3, 100)
result_large = scirs2.ttest_rel_py(before_large, after_large)
if result_large["pvalue"] > 0 and result_small["pvalue"] > 0:
assert result_large["pvalue"] <= result_small["pvalue"]
class TestPairedTTestRealWorldScenarios:
def test_before_after_treatment(self):
before_bp = np.array([140, 145, 138, 142, 147, 139, 144, 141, 143, 146], dtype=np.float64)
after_bp = np.array([125, 130, 122, 128, 132, 124, 129, 126, 127, 131], dtype=np.float64)
result = scirs2.ttest_rel_py(before_bp, after_bp)
assert result["pvalue"] < 0.05
assert result["statistic"] > 0
def test_test_retest_reliability(self):
np.random.seed(42)
test1 = np.array([85, 90, 78, 92, 88, 86, 91, 89, 87, 93], dtype=np.float64)
test2 = test1 + np.random.normal(0, 2, 10)
result = scirs2.ttest_rel_py(test1, test2)
assert result["pvalue"] > 0.05
def test_matched_pairs_design(self):
twin1_scores = np.array([75, 82, 79, 85, 88, 76, 84, 80, 83, 87], dtype=np.float64)
twin2_scores = np.array([78, 85, 82, 89, 92, 79, 88, 83, 87, 91], dtype=np.float64)
result = scirs2.ttest_rel_py(twin1_scores, twin2_scores)
assert "pvalue" in result
assert 0 <= result["pvalue"] <= 1
def test_repeated_measures(self):
baseline_weight = np.array([85.2, 92.1, 78.5, 88.3, 95.7, 82.4, 90.6, 86.8])
three_month_weight = np.array([82.1, 89.5, 76.2, 85.1, 92.3, 80.1, 87.8, 84.2])
result = scirs2.ttest_rel_py(baseline_weight, three_month_weight)
assert result["pvalue"] < 0.1
assert result["statistic"] > 0
def test_crossover_design(self):
response_a = np.array([45, 52, 48, 55, 50, 47, 53, 49, 51, 54], dtype=np.float64)
response_b = np.array([48, 55, 51, 58, 53, 50, 56, 52, 54, 57], dtype=np.float64)
result = scirs2.ttest_rel_py(response_a, response_b)
assert "pvalue" in result
assert result["pvalue"] < 0.1
assert result["statistic"] < 0
if __name__ == "__main__":
pytest.main([__file__, "-v"])