Test Suite Speedup — Implementation Plan
For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: Reduce full test suite from ~82s to ~55s by fixing the 5 slowest tests.
Architecture: Test-only changes. Mock expensive I/O (CPU sampling, filesystem scanning) in tests that don’t need it, and reduce intentional sleeps. No production code changes.
Tech Stack: Python unittest.mock.patch, tempfile, pytest.
Important context:
- CPU checker at
apps/checkers/checkers/cpu.py:49callspsutil.cpu_percent(interval=1.0)in a loop — 5 samples × 1s = 5s. - The context node at
apps/orchestration/nodes/context.py:52instantiates checkers with default args viachecker_cls(). - The disk scanner at
apps/intelligence/providers/local.py:528runssubprocess.run(["du", ...], timeout=30)and falls back toPath.rglob("*"). - All 3 integration tests in
test_integration.pyverify pipeline orchestration, not CPU accuracy.
Task 1: Mock CPU sampling in 3 integration tests (~15s saved)
Files:
- Modify:
apps/orchestration/_tests/test_integration.py
Step 1: Add mock decorator to TestPipelineIntegration class
At the top of the file, add the unittest.mock import. Then decorate the class with a @patch that makes psutil.cpu_percent return instantly:
In apps/orchestration/_tests/test_integration.py, change the imports and class definition:
# apps/orchestration/_tests/test_integration.py
"""Integration tests for the complete pipeline system."""
from unittest.mock import patch
from django.test import TestCase
from apps.orchestration.definition_orchestrator import DefinitionBasedOrchestrator
from apps.orchestration.models import PipelineDefinition, PipelineRun
@patch("psutil.cpu_percent", return_value=42.0)
class TestPipelineIntegration(TestCase):
"""Integration tests for complete pipelines."""
Then add _mock_cpu as the first parameter (after self) to every test method in the class. There are 4 test methods:
def test_context_to_intelligence_pipeline(self, _mock_cpu):def test_pipeline_with_optional_failing_node(self, _mock_cpu):def test_transform_between_nodes(self, _mock_cpu):def test_pipeline_creates_run_record(self, _mock_cpu):
The bodies stay identical — only the signatures change.
Step 2: Run tests to verify they pass
Run: uv run pytest apps/orchestration/_tests/test_integration.py -v Expected: 4 PASS, each completing in < 1s instead of ~5s.
Step 3: Commit
git add apps/orchestration/_tests/test_integration.py
git commit -m "test: mock psutil.cpu_percent in integration tests — saves ~15s"
Task 2: Reduce sleep in timeout test (~5s saved)
Files:
- Modify:
apps/orchestration/_tests/test_nodes.py
Step 1: Change sleep duration
In apps/orchestration/_tests/test_nodes.py, find TestIntelligenceCallWithTimeout.test_timeout_branch (line ~1161). Change the time.sleep(5) to time.sleep(0.5):
def test_timeout_branch(self):
"""_call_with_timeout returns None on timeout."""
from apps.orchestration.nodes.intelligence import IntelligenceNodeHandler
handler = IntelligenceNodeHandler()
def slow_func():
import time
time.sleep(0.5)
return "never"
result = handler._call_with_timeout(slow_func, timeout=0.01)
assert result is None
The timeout is 0.01s, so 0.5s is still 50x longer — proves the same timeout behavior.
Step 2: Run test to verify it passes
Run: uv run pytest apps/orchestration/_tests/test_nodes.py::TestIntelligenceCallWithTimeout::test_timeout_branch -v Expected: PASS in < 1s.
Step 3: Commit
git add apps/orchestration/_tests/test_nodes.py
git commit -m "test: reduce sleep in timeout test from 5s to 0.5s"
Task 3: Mock filesystem in disk scan test (~5s saved)
Files:
- Modify:
apps/intelligence/_tests/providers/test_local.py
Step 1: Replace real filesystem scan with tempdir
In apps/intelligence/_tests/providers/test_local.py, find test_provider_disk_progress_callback (line ~117). Replace the test to use a temporary directory instead of scanning real /tmp:
def test_provider_disk_progress_callback(self):
"""Provider should call progress_callback during disk scanning."""
import tempfile
progress_messages = []
def capture_progress(msg):
progress_messages.append(msg)
provider = LocalRecommendationProvider(
large_file_threshold_mb=1000, # High threshold to scan without finding much
progress_callback=capture_progress,
)
with tempfile.TemporaryDirectory() as tmpdir:
# Create a small file so the scan has something to traverse
Path(tmpdir, "testfile.txt").write_text("hello")
provider._get_disk_recommendations(tmpdir)
assert any("Scanning" in msg for msg in progress_messages)
assert any(tmpdir in msg or "Scanning" in msg for msg in progress_messages)
Note: The original test asserts any("/tmp" in msg ...). With a tempdir, the path will be something like /var/folders/.../tmpXXX. The _progress call at line 296 in local.py does self._progress(f"Scanning {path}..."), so the tmpdir path will appear in the messages. We assert tmpdir in msg to verify the callback received the correct path.
Step 2: Run test to verify it passes
Run: uv run pytest apps/intelligence/_tests/providers/test_local.py::TestLocalRecommendationProvider::test_provider_disk_progress_callback -v Expected: PASS in < 1s.
Step 3: Run full provider test suite for regressions
Run: uv run pytest apps/intelligence/_tests/providers/test_local.py -v Expected: All PASS.
Step 4: Commit
git add apps/intelligence/_tests/providers/test_local.py
git commit -m "test: use tempdir instead of real /tmp in disk scan test — saves ~5s"
Task 4: Final verification — full suite timing
Step 1: Run full test suite with timing
Run: uv run pytest --durations=10 Expected: Total time ~55s (down from ~82s). No test should take > 2s.
Step 2: Run linting
Run: uv run black --check . && uv run ruff check . Expected: Clean.
Step 3: If any formatting fixes needed, commit
git add -A
git commit -m "chore: lint fixes for test speedup"