Skip to content

Commit 2310714

Browse files
committed
fix tests warnings
1 parent 4fdf92b commit 2310714

File tree

4 files changed

+41
-19
lines changed

4 files changed

+41
-19
lines changed

src/services/analytics/stat_functions.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
Key features:
99
- Welch's t-test for comparing means with unequal variances.
1010
- Z-test for comparing proportions.
11-
- Ratio metric analysis using the delta method.
11+
- Ratio metric anaysis using the delta method.
1212
- Sample size calculations for various test types.
1313
- Support for both scalar and vectorized operations.
1414
"""
@@ -106,8 +106,7 @@ def ttest_welch(
106106
ci_upper = t_diff + t_se * stat_ppf
107107
ci = ConfidenceInterval(ci_lower, ci_upper)
108108

109-
# Handle division by zero for diff_ratio
110-
diff_ratio = np.where(mean_1 != 0, t_diff / mean_1, np.inf)
109+
diff_ratio = np.divide(t_diff, mean_1, out=np.full_like(t_diff, np.inf, dtype=float), where=mean_1 != 0)
111110

112111
return TestResult(statistic=t_stat, p_value=p_value, ci=ci, diff_abs=t_diff, diff_ratio=diff_ratio)
113112

src/ui/results/elements.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ def render(cls, precomputes: pd.DataFrame | None) -> SettingsColumnLayout | None
409409
p_value_threshold_filter = PValueThresholdFilter.render().threshold
410410
metric_filters = MetricsFilters.render()
411411

412-
observations_cnt = precomputes.groupby("group_name")["observation_cnt"].unique().to_dict()
412+
observations_cnt = precomputes.groupby("group_name")["observation_cnt"].max().astype(int).to_dict()
413413
SampleRatioMismatchCheckExpander.render(observations_cnt)
414414

415415
return cls(

tests/assistant/test_app.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from __future__ import annotations
88

9+
from types import SimpleNamespace
910
from typing import Any
1011
from unittest.mock import AsyncMock, MagicMock, patch
1112

@@ -36,60 +37,63 @@ def user_payload() -> dict[str, Any]:
3637
# ---------------------------------- Happy‑path test ----------------------------------
3738

3839

40+
@patch("assistant.app.logger.instrument_requests", lambda *a, **k: None)
41+
@patch("assistant.app.logger.instrument_sqlalchemy", lambda *a, **k: None)
3942
@patch("assistant.app.init_assistant_service")
4043
@patch("assistant.app.init_engine")
4144
@patch("assistant.app.init_vdb")
4245
def test_invoke_success(mock_vdb, mock_engine, mock_service, user_payload, dummy_usage, patch_configs):
43-
"""/invoke returns AgentResponse and disposes engine on shutdown."""
44-
4546
fake_response = AssistantResponse(output="hi!", usage=dummy_usage, thinking="thinking")
46-
# assistant_service is async, so we need an AsyncMock
47+
48+
# assistant_service — async
4749
mock_service_instance = AsyncMock()
4850
mock_service_instance.process_request.return_value = fake_response
4951
mock_service.return_value = mock_service_instance
5052

51-
# Mock DB engine + vdb
52-
mock_engine_instance = AsyncMock()
53-
mock_engine_instance.dispose = AsyncMock()
54-
mock_engine.return_value = mock_engine_instance
53+
# Engine — объект с async dispose()
54+
engine = MagicMock()
55+
engine.dispose = AsyncMock()
56+
mock_engine.return_value = engine
57+
58+
# vdb — любой sync мок
5559
mock_vdb_instance = MagicMock()
5660
mock_vdb.return_value = mock_vdb_instance
5761

5862
with TestClient(app) as client:
59-
# --- request ---
6063
resp = client.post("/invoke", json=user_payload)
6164
assert resp.status_code == 200
6265
assert resp.json()["output"] == "hi!"
6366

64-
# After exiting TestClient, shutdown event has run
65-
mock_engine_instance.dispose.assert_awaited_once()
67+
engine.dispose.assert_awaited_once()
6668
mock_service_instance.process_request.assert_awaited_once()
6769

6870

6971
# ------------------------ Validation error (missing chat_uid) ------------------------
7072

7173

74+
@patch("assistant.app.logger.instrument_requests", lambda *a, **k: None)
75+
@patch("assistant.app.logger.instrument_sqlalchemy", lambda *a, **k: None)
7276
@patch("assistant.app.init_assistant_service", lambda *a, **kw: AsyncMock())
73-
@patch("assistant.app.init_engine", lambda *a, **kw: AsyncMock())
77+
@patch("assistant.app.init_engine", lambda *a, **kw: SimpleNamespace(dispose=AsyncMock()))
7478
@patch("assistant.app.init_vdb", lambda *a, **kw: MagicMock())
7579
def test_invoke_validation_error(user_payload, patch_configs):
76-
"""Test validation error when chat_uid is missing."""
7780
payload = user_payload.copy()
7881
payload.pop("chat_uid")
7982
with TestClient(app) as client:
8083
resp = client.post("/invoke", json=payload)
81-
assert resp.status_code == 422 # FastAPI validation error
84+
assert resp.status_code == 422
8285

8386

8487
#
8588
# ---------------------------- Error path: assistant raises ----------------------------
8689

8790

91+
@patch("assistant.app.logger.instrument_requests", lambda *a, **k: None)
92+
@patch("assistant.app.logger.instrument_sqlalchemy", lambda *a, **k: None)
8893
@patch("assistant.app.init_assistant_service")
89-
@patch("assistant.app.init_engine", lambda *a, **kw: AsyncMock())
94+
@patch("assistant.app.init_engine", lambda *a, **kw: SimpleNamespace(dispose=AsyncMock()))
9095
@patch("assistant.app.init_vdb", lambda *a, **kw: MagicMock())
9196
def test_invoke_service_error(mock_service, user_payload, patch_configs):
92-
"""Test error handling when assistant service raises exception."""
9397
err = RuntimeError("model crashed")
9498
mock_service_instance = AsyncMock()
9599
mock_service_instance.process_request.side_effect = err

tests/services/analytics/stat_functions/test_ttest_welch.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,22 @@ def test_sample_size_t_test_edge_cases():
171171
alpha=0.05,
172172
beta=0.2,
173173
)
174+
175+
176+
def test_ttest_welch_zero_division_no_warning(recwarn):
177+
"""Tests that no RuntimeWarning is raised for 0/0 division with np.divide."""
178+
mean_1 = np.array([10, 0])
179+
var_1 = np.array([1, 1])
180+
n_1 = np.array([100, 100])
181+
mean_2 = np.array([12, 0])
182+
var_2 = np.array([1, 1])
183+
n_2 = np.array([100, 100])
184+
185+
result = ttest_welch(mean_1, var_1, n_1, mean_2, var_2, n_2)
186+
187+
# Check that no warnings were issued
188+
assert len(recwarn) == 0
189+
190+
# The result for the 0/0 case should be np.inf with the np.divide fix
191+
expected_diff_ratio = np.array([0.2, np.inf])
192+
assert np.allclose(result.diff_ratio, expected_diff_ratio, equal_nan=True)

0 commit comments

Comments
 (0)