style(tests): ruff 全量清理 — 49 项修复,backend 与 tests 全绿

- ruff --fix 自动修正 44 项:移除未用 import(pytest 等)、import 块排序归一(I001)
- 手工修复剩余 5 项:test_cascade.py 两处未用赋值(F841);test_s2_rules_and_logic.py 中部 import 移至文件顶部(E402 ×3)
- 无行为变更:全量 492 项测试通过
This commit is contained in:
sinohqb 2026-08-03 15:13:24 +08:00
parent 14b09e1ac6
commit 5ecb30876e
22 changed files with 188 additions and 93 deletions

View File

@ -1,18 +1,21 @@
"""Integration tests for the login gate: /api/auth/* and require_auth."""
import pytest
from fastapi.testclient import TestClient
from sqlmodel import Session, SQLModel, create_engine
from agenteval.config.settings import Settings
from agenteval.web.app import app
from agenteval.web.deps import get_db
from fastapi.testclient import TestClient
from sqlmodel import Session, SQLModel, create_engine
@pytest.fixture()
def client_with_db(tmp_path):
from agenteval.storage.db import ( # noqa: F401
EvalResultDB, EvalRunDB, EvalTargetDB, ScenarioDB, TurnDB,
EvalResultDB,
EvalRunDB,
EvalTargetDB,
ScenarioDB,
TurnDB,
)
engine = create_engine(
f"sqlite:///{tmp_path / 'auth_api.db'}",

View File

@ -1,17 +1,22 @@
"""Integration tests for /api/campaigns/{id}/analysis (v0.7 ticket 03)."""
import pytest
from httpx import ASGITransport, AsyncClient
from sqlmodel import select
from agenteval.models import (
CampaignStatus, Case, CaseType, ChannelType, EvalTarget, PlatformType,
Scenario, TargetStatus,
CampaignStatus,
Case,
CaseType,
ChannelType,
EvalTarget,
PlatformType,
Scenario,
TargetStatus,
)
from agenteval.storage.db import CampaignAnalysisDB, ModelConfigDB
from agenteval.storage.model_config_repository import ModelConfigRepository
from agenteval.storage.repository import CampaignRepository, ScenarioRepository, TargetRepository
from agenteval.web.app import app
from httpx import ASGITransport, AsyncClient
from sqlmodel import select
@pytest.fixture()

View File

@ -8,13 +8,22 @@ No real timer is used — the clock is injected, mirroring how the durable loop
"""
import pytest
from agenteval.evaluation.campaign_runner import advance_campaign
from agenteval.models import (
Campaign, CampaignPlanEntry, Case, CaseType, ChannelType, EvalTarget,
PlatformType, RunStatus, RunTrigger, Scenario, TargetStatus,
Campaign,
CampaignPlanEntry,
Case,
CaseType,
ChannelType,
EvalTarget,
PlatformType,
RunStatus,
RunTrigger,
Scenario,
TargetStatus,
)
from agenteval.storage.repository import CampaignRepository, RunRepository, ScenarioRepository, TargetRepository
from tests.unit.mock_channel import MockChannel

View File

@ -9,15 +9,24 @@ and cancellation (no further spawning).
from datetime import timedelta
import pytest
from agenteval.evaluation import campaign_runner
from agenteval.evaluation.campaign_runner import request_cancel, start_campaign
from agenteval.models import (
Campaign, CampaignPlanEntry, CampaignStatus, Case, CaseType, ChannelType,
EvalTarget, PlatformType, RunStatus, Scenario, TargetStatus,
Campaign,
CampaignPlanEntry,
CampaignStatus,
Case,
CaseType,
ChannelType,
EvalTarget,
PlatformType,
RunStatus,
Scenario,
TargetStatus,
)
from agenteval.storage.db import utc_now
from agenteval.storage.repository import CampaignRepository, RunRepository, ScenarioRepository, TargetRepository
from tests.unit.mock_channel import MockChannel
TICK = 0.01

View File

@ -7,14 +7,19 @@ nullable ``campaign_id`` column does not disturb existing Run behavior.
"""
import pytest
from httpx import ASGITransport, AsyncClient
from agenteval.models import (
Case, CaseType, ChannelType, EvalRun, EvalTarget, PlatformType,
Scenario, TargetStatus,
Case,
CaseType,
ChannelType,
EvalRun,
EvalTarget,
PlatformType,
Scenario,
TargetStatus,
)
from agenteval.storage.repository import RunRepository, ScenarioRepository, TargetRepository
from agenteval.web.app import app
from httpx import ASGITransport, AsyncClient
@pytest.fixture()

View File

@ -1,23 +1,38 @@
"""Integration tests for the reports API: /api/reports/{id}, /markdown, /compare."""
import json
import pytest
from fastapi.testclient import TestClient
from sqlmodel import Session, SQLModel, create_engine
import pytest
from agenteval.models import (
Case, CaseType, EvalResult, EvalRun, EvalTarget, RunStatus, Scenario,
PlatformType, ChannelType, TargetStatus, Turn,
Case,
CaseType,
ChannelType,
EvalResult,
EvalRun,
EvalTarget,
PlatformType,
RunStatus,
Scenario,
TargetStatus,
Turn,
)
from agenteval.storage.repository import ResultRepository, RunRepository, ScenarioRepository, TargetRepository
from agenteval.web.app import app
from agenteval.web.deps import get_db
from fastapi.testclient import TestClient
from sqlmodel import Session, SQLModel, create_engine
@pytest.fixture()
def client_with_db(tmp_path):
from agenteval.storage.db import ( # noqa: F401
EvalResultDB, EvalRunDB, EvalTargetDB, FileCategoryDB, FileRecordDB, ScenarioDB, TurnDB,
EvalResultDB,
EvalRunDB,
EvalTargetDB,
FileCategoryDB,
FileRecordDB,
ScenarioDB,
TurnDB,
)
engine = create_engine(
f"sqlite:///{tmp_path / 'reports_api.db'}",

View File

@ -6,18 +6,21 @@ no network calls are made.
"""
import asyncio
from typing import Any
import pytest
from agenteval.models import (
Case,
CaseType,
ChannelType,
EvalTarget,
PlatformType,
Scenario,
TargetStatus,
)
from agenteval.storage.repository import ScenarioRepository, TargetRepository
from agenteval.web.app import app
from httpx import ASGITransport, AsyncClient
from agenteval.channels.base import SendResult
from agenteval.models import (
Case, CaseType, ChannelType, EvalTarget, PlatformType,
Scenario, TargetStatus,
)
from agenteval.storage.repository import RunRepository, ScenarioRepository, TargetRepository
from agenteval.web.app import app
from tests.unit.mock_channel import MockChannel
@ -37,10 +40,9 @@ def seeded_db(db_session, monkeypatch):
def _test_get_session():
return db_session
from agenteval.storage import db as db_module
from agenteval.web.routers import runs as runs_module
from agenteval.storage import repository as repo_module
from agenteval.evaluation import engine as engine_module
from agenteval.storage import repository as repo_module
from agenteval.web.routers import runs as runs_module
monkeypatch.setattr(db_module, "get_session", _test_get_session)
monkeypatch.setattr(runs_module, "get_session", _test_get_session)

View File

@ -5,11 +5,10 @@ llm_config变更时递增元数据编辑不升版API 不接受外部指
"""
import pytest
from cryptography.fernet import Fernet
from httpx import ASGITransport, AsyncClient
from agenteval.services.model_configs import ModelConfigService, SecretCipher
from agenteval.web.app import app
from cryptography.fernet import Fernet
from httpx import ASGITransport, AsyncClient
pytestmark = pytest.mark.anyio

View File

@ -1,22 +1,34 @@
"""Integration tests for /api/stats/dashboard aggregation."""
import pytest
from fastapi.testclient import TestClient
from sqlmodel import Session, SQLModel, create_engine
from agenteval.models import (
Case, CaseType, ChannelType, EvalRun, EvalTarget, PlatformType,
RunStatus, RunTrigger, Scenario, TargetStatus,
Case,
CaseType,
ChannelType,
EvalRun,
EvalTarget,
PlatformType,
RunStatus,
RunTrigger,
Scenario,
TargetStatus,
)
from agenteval.storage.repository import RunRepository, ScenarioRepository, TargetRepository
from agenteval.web.app import app
from agenteval.web.deps import get_db
from fastapi.testclient import TestClient
from sqlmodel import Session, SQLModel, create_engine
@pytest.fixture()
def client_with_db(tmp_path):
from agenteval.storage.db import ( # noqa: F401
EvalResultDB, EvalRunDB, EvalTargetDB, ModelConfigDB, ScenarioDB, TurnDB,
EvalResultDB,
EvalRunDB,
EvalTargetDB,
ModelConfigDB,
ScenarioDB,
TurnDB,
)
engine = create_engine(
f"sqlite:///{tmp_path / 'stats_api.db'}",

View File

@ -3,8 +3,6 @@
import json
import pytest
from sqlmodel import select
from agenteval.evaluation.analysis import (
AnalysisError,
analyze_campaign,
@ -16,6 +14,7 @@ from agenteval.models import Campaign, CampaignPlanEntry, EvalRun, RunStatus
from agenteval.storage.db import CampaignAnalysisDB, EvalResultDB, ModelConfigDB, TurnDB
from agenteval.storage.model_config_repository import ModelConfigRepository
from agenteval.storage.repository import CampaignRepository, RunRepository
from sqlmodel import select
class FakeChatClient:

View File

@ -3,11 +3,10 @@
from datetime import datetime, timedelta, timezone
import pytest
from sqlmodel import Session, SQLModel, create_engine
from agenteval.evaluation.report import generate_campaign_report, summarize_campaign_progress
from agenteval.models import Campaign, CampaignPlanEntry, CampaignStatus, EvalRun, RunStatus
from agenteval.storage.repository import CampaignRepository, RunRepository
from sqlmodel import Session, SQLModel, create_engine
T0 = datetime(2026, 1, 1, 0, 0, 0, tzinfo=timezone.utc)
@ -15,8 +14,14 @@ T0 = datetime(2026, 1, 1, 0, 0, 0, tzinfo=timezone.utc)
@pytest.fixture()
def report_session(tmp_path):
from agenteval.storage.db import ( # noqa: F401
CampaignDB, EvalResultDB, EvalRunDB, EvalTargetDB, FileCategoryDB,
FileRecordDB, ScenarioDB, TurnDB,
CampaignDB,
EvalResultDB,
EvalRunDB,
EvalTargetDB,
FileCategoryDB,
FileRecordDB,
ScenarioDB,
TurnDB,
)
engine = create_engine(
f"sqlite:///{tmp_path / 'campaign_report.db'}",

View File

@ -12,6 +12,7 @@ from agenteval.models import (
SchedulerState,
)
from agenteval.storage.repository import CampaignRepository, TargetRepository
from tests.unit.test_repository import _make_target

View File

@ -3,11 +3,10 @@
from datetime import datetime, timedelta, timezone
import pytest
from sqlmodel import Session, SQLModel, create_engine
from agenteval.evaluation.report import build_campaign_timeline
from agenteval.models import Campaign, CampaignPlanEntry, CampaignStatus, EvalRun, RunStatus
from agenteval.storage.repository import CampaignRepository, RunRepository
from sqlmodel import Session, SQLModel, create_engine
T0 = datetime(2026, 1, 1, 0, 0, 0, tzinfo=timezone.utc)
@ -15,8 +14,14 @@ T0 = datetime(2026, 1, 1, 0, 0, 0, tzinfo=timezone.utc)
@pytest.fixture()
def timeline_session(tmp_path):
from agenteval.storage.db import ( # noqa: F401
CampaignDB, EvalResultDB, EvalRunDB, EvalTargetDB, FileCategoryDB,
FileRecordDB, ScenarioDB, TurnDB,
CampaignDB,
EvalResultDB,
EvalRunDB,
EvalTargetDB,
FileCategoryDB,
FileRecordDB,
ScenarioDB,
TurnDB,
)
engine = create_engine(
f"sqlite:///{tmp_path / 'campaign_timeline.db'}",

View File

@ -4,15 +4,25 @@ Deleting a run should automatically delete its turns and results.
Deleting a target/scenario should automatically delete its runs.
"""
import pytest
from agenteval.models import (
Case, CaseType, ChannelType, EvalResult, EvalRun, EvalTarget, PlatformType,
RunStatus, Scenario, TargetStatus, Turn,
Case,
CaseType,
ChannelType,
EvalResult,
EvalRun,
EvalTarget,
PlatformType,
RunStatus,
Scenario,
Turn,
)
from agenteval.storage.db import EvalResultDB, EvalRunDB, EvalTargetDB, ScenarioDB, TurnDB
from agenteval.storage.repository import (
ResultRepository, RunRepository, ScenarioRepository, TargetRepository,
ResultRepository,
RunRepository,
ScenarioRepository,
TargetRepository,
)
@ -37,10 +47,10 @@ def test_delete_run_cascades_to_turns_and_results(db_session):
TargetRepository(db_session).create(_make_target())
ScenarioRepository(db_session).create(_make_scenario())
run = RunRepository(db_session).create(EvalRun(
RunRepository(db_session).create(EvalRun(
id="r-1", target_id="t-1", scenario_id="s-1", status=RunStatus.COMPLETED,
))
turn = ResultRepository(db_session).save_turn(Turn(
ResultRepository(db_session).save_turn(Turn(
id="tu-1", run_id="r-1", case_id="c1", round_index=1,
))
ResultRepository(db_session).save_result(EvalResult(

View File

@ -7,15 +7,22 @@ timeouts, and concurrent case execution via the semaphore.
import asyncio
from typing import Any
import pytest
from agenteval.channels.base import SendResult
from agenteval.evaluation.engine import CancelledError, EvalEngine, TimeoutConfig
from agenteval.evaluation.engine import EvalEngine, TimeoutConfig
from agenteval.models import (
Case, CaseOutcomeSummary, CaseType, ChannelType, EvalTarget, Expectation, PlatformType,
RunStatus, Scenario, TargetStatus,
Case,
CaseOutcomeSummary,
CaseType,
ChannelType,
EvalTarget,
Expectation,
PlatformType,
RunStatus,
Scenario,
TargetStatus,
)
from agenteval.storage.repository import RunRepository
from tests.unit.mock_channel import MockChannel

View File

@ -1,18 +1,13 @@
"""Unit tests for HttpChannel, OpenClawChannel, and async rule evaluation."""
import asyncio
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from agenteval.channels.http import HttpChannel, _get_path
from agenteval.channels.openclaw import OpenClawChannel
from agenteval.channels.base import SendResult
from agenteval.evaluation.rules.keyword import KeywordMatchRule
from agenteval.evaluation.rules.response_time import ResponseTimeRule
from agenteval.models import Case, CaseType, Expectation, Turn
# ── _get_path helper ─────────────────────────────────────────────────────
def test_get_path_simple():

View File

@ -4,7 +4,6 @@ import json
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from agenteval.evaluation.rules.llm_score import LlmScoreRule
from agenteval.models import Case, CaseType, Turn

View File

@ -1,24 +1,38 @@
"""Unit tests for report generation: generate_report, generate_compare_report, render_markdown_report."""
import pytest
from sqlmodel import Session, SQLModel, create_engine
from agenteval.evaluation.report import (
generate_compare_report,
generate_report,
)
from agenteval.evaluation.report_render import render_json, render_markdown
from agenteval.models import (
Case, CaseType, EvalResult, EvalRun, EvalTarget, RunStatus, Scenario, Turn,
PlatformType, ChannelType, TargetStatus,
Case,
CaseType,
ChannelType,
EvalResult,
EvalRun,
EvalTarget,
PlatformType,
RunStatus,
Scenario,
TargetStatus,
Turn,
)
from agenteval.storage.repository import ResultRepository, RunRepository, ScenarioRepository, TargetRepository
from sqlmodel import Session, SQLModel, create_engine
@pytest.fixture()
def report_session(tmp_path):
from agenteval.storage.db import ( # noqa: F401
EvalResultDB, EvalRunDB, EvalTargetDB, FileCategoryDB, FileRecordDB, ScenarioDB, TurnDB,
EvalResultDB,
EvalRunDB,
EvalTargetDB,
FileCategoryDB,
FileRecordDB,
ScenarioDB,
TurnDB,
)
engine = create_engine(
f"sqlite:///{tmp_path / 'report_test.db'}",

View File

@ -1,16 +1,27 @@
"""Tests for S2 new rules: json_schema, safety, semantic_similarity,
and rule combination logic (all/any/weighted)."""
import asyncio
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from agenteval.evaluation.engine import EvalEngine
from agenteval.evaluation.rules.json_schema import JsonSchemaRule, _get_path
from agenteval.evaluation.rules.safety import SafetyRule
from agenteval.evaluation.rules.semantic import SemanticSimilarityRule, _cosine
from agenteval.models import Case, CaseType, EvalRuleConfig, Expectation, RuleLogic, Turn
from agenteval.models import (
Case,
CaseType,
EvalRuleConfig,
EvalTarget,
PlatformType,
RuleLogic,
RunStatus,
Scenario,
TargetStatus,
Turn,
)
from tests.unit.mock_channel import MockChannel
# ── helpers ──────────────────────────────────────────────────────────────
@ -278,11 +289,6 @@ async def test_semantic_empty_dialog():
# ── Rule combination logic (engine integration) ───────────────────────────
from agenteval.evaluation.engine import EvalEngine, TimeoutConfig
from agenteval.models import EvalTarget, PlatformType, RunStatus, Scenario, TargetStatus
from tests.unit.mock_channel import MockChannel
def _make_target() -> EvalTarget:
return EvalTarget(

View File

@ -6,11 +6,9 @@ from pathlib import Path
import pytest
import yaml
from agenteval.scenarios.loader import load_scenario_file, validate_scenario, ScenarioValidationError
from agenteval.scenarios.loader import ScenarioValidationError, load_scenario_file, validate_scenario
from agenteval.scenarios.templates import get_template, list_templates
# ── templates ─────────────────────────────────────────────────────────────
def test_list_templates_returns_list():

View File

@ -1,10 +1,9 @@
"""Unit tests for agenteval.utils.llm — the shared LLM utility functions."""
import json
import pytest
from agenteval.utils.llm import extract_reply_text, extract_content_from_llm_response, parse_json_from_llm_text
from agenteval.utils.llm import extract_content_from_llm_response, extract_reply_text, parse_json_from_llm_text
# ── extract_reply_text ───────────────────────────────────────────────────

View File

@ -2,8 +2,6 @@
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
async def test_webhook_not_called_when_url_not_configured():
with patch("agenteval.utils.webhook.get_settings") as mock_settings: