feat: run tests in background with progress polling
Improve the testing dashboard to run pytest in the background: - Add background task execution using FastAPI's BackgroundTasks - Create test_runner_tasks.py following existing background task pattern - API now returns immediately after starting the test run - Frontend polls for status every 2 seconds until completion - Show running indicator with elapsed time counter - Resume polling if user navigates away and returns while tests running - Tests continue running even if user closes the page 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -25,6 +25,25 @@ class TestRunnerService:
|
||||
def __init__(self):
|
||||
self.project_root = Path(__file__).parent.parent.parent
|
||||
|
||||
def create_test_run(
|
||||
self,
|
||||
db: Session,
|
||||
test_path: str = "tests",
|
||||
triggered_by: str = "manual",
|
||||
) -> TestRun:
|
||||
"""Create a test run record without executing tests"""
|
||||
test_run = TestRun(
|
||||
timestamp=datetime.now(UTC),
|
||||
triggered_by=triggered_by,
|
||||
test_path=test_path,
|
||||
status="running",
|
||||
git_commit_hash=self._get_git_commit(),
|
||||
git_branch=self._get_git_branch(),
|
||||
)
|
||||
db.add(test_run)
|
||||
db.flush()
|
||||
return test_run
|
||||
|
||||
def run_tests(
|
||||
self,
|
||||
db: Session,
|
||||
@@ -33,7 +52,7 @@ class TestRunnerService:
|
||||
extra_args: list[str] | None = None,
|
||||
) -> TestRun:
|
||||
"""
|
||||
Run pytest and store results in database
|
||||
Run pytest synchronously and store results in database
|
||||
|
||||
Args:
|
||||
db: Database session
|
||||
@@ -44,21 +63,19 @@ class TestRunnerService:
|
||||
Returns:
|
||||
TestRun object with results
|
||||
"""
|
||||
# Create test run record
|
||||
test_run = TestRun(
|
||||
timestamp=datetime.now(UTC),
|
||||
triggered_by=triggered_by,
|
||||
test_path=test_path,
|
||||
status="running",
|
||||
)
|
||||
db.add(test_run)
|
||||
db.flush() # Get the ID
|
||||
test_run = self.create_test_run(db, test_path, triggered_by)
|
||||
self._execute_tests(db, test_run, test_path, extra_args)
|
||||
return test_run
|
||||
|
||||
def _execute_tests(
|
||||
self,
|
||||
db: Session,
|
||||
test_run: TestRun,
|
||||
test_path: str,
|
||||
extra_args: list[str] | None,
|
||||
) -> None:
|
||||
"""Execute pytest and update the test run record"""
|
||||
try:
|
||||
# Get git info
|
||||
test_run.git_commit_hash = self._get_git_commit()
|
||||
test_run.git_branch = self._get_git_branch()
|
||||
|
||||
# Build pytest command with JSON output
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
|
||||
json_report_path = f.name
|
||||
@@ -66,7 +83,7 @@ class TestRunnerService:
|
||||
pytest_args = [
|
||||
"python", "-m", "pytest",
|
||||
test_path,
|
||||
f"--json-report",
|
||||
"--json-report",
|
||||
f"--json-report-file={json_report_path}",
|
||||
"-v",
|
||||
"--tb=short",
|
||||
@@ -120,8 +137,6 @@ class TestRunnerService:
|
||||
test_run.status = "error"
|
||||
logger.error(f"Error running tests: {e}")
|
||||
|
||||
return test_run
|
||||
|
||||
def _process_json_report(self, db: Session, test_run: TestRun, report: dict):
|
||||
"""Process pytest-json-report output"""
|
||||
summary = report.get("summary", {})
|
||||
|
||||
Reference in New Issue
Block a user