Validate code changes by intelligently selecting and running the appropriate test suites. Use this when editing code to verify changes work correctly, run tests, validate functionality, or check for regressions. Automatically discovers affected test suites, selects the minimal set of venvs needed for validation, and handles test execution with Docker services as needed.
This skill helps you efficiently validate code changes by running the appropriate subset of the test suite. It uses scripts/run-tests to intelligently discover affected tests and run only what's necessary for validation.
Use this skill when you have:
scripts/run-tests--list first - see matching environments before executingdocs/contributing-testing.rst is the source of truth for testing proceduresFirst, determine which files were modified:
I'll use the scripts/run-tests script to discover what test suites match your changes:
scripts/run-tests --list <edited-files>
This outputs JSON showing:
Rather than running ALL available venvs (which could take hours), I'll select the minimal set needed to validate your changes:
When you modify files like:
ddtrace/internal/core/*, ddtrace/_trace/*, ddtrace/trace/*ddtrace/_monkey.py, ddtrace/settings/*ddtrace/constants.pyStrategy: Run core tracer + internal tests with 1 venv each
tracer suite with latest Python + internal suite with latest PythonWhen you modify files like:
ddtrace/contrib/flask/*, ddtrace/contrib/django/*, etc.ddtrace/contrib/*/patch.py or integration-specific codeStrategy: Run ONLY the affected integration suite with 1-2 venvs
contrib::flask suite with latest PythonWhen you modify tests/ files (but not test infrastructure):
-- -k test_nameWhen you modify:
tests/conftest.py, tests/suitespec.yml, riotfile.py, .riot/requirements/, or scripts/run-testsStrategy: Run a quick smoke test suite
internal suite with 1 venv as a sanity checkI'll run the selected venvs. On the first invocation in a session, always run without -s to ensure the venv has dd-trace-py properly installed:
scripts/run-tests --venv <hash1> --venv <hash2>
On subsequent runs, pass -s before the test-command separator to reuse the current ddtrace installation:
scripts/run-tests -s --venv <hash1> --venv <hash2>
When to use -s (skip base install) on subsequent runs:
When to omit -s even on subsequent runs (force rebuild):
.pyx, .pxd), or CMake files were modified (e.g., under ddtrace/internal/, ddtrace/appsec/_iast/_taint_tracking/, src/native/)setup.py, pyproject.toml, or setup.cfg were modifiedriotfile.py or .riot/requirements/ files were modifiedThis will:
If tests pass: ✅ Your changes are validated!
If tests fail: 🔴 I'll:
For re-running specific tests (use -s since the venv is already built):
scripts/run-tests -s --venv <hash> -- -vv -k test_name
When you encounter test failures, follow this systematic approach:
-vv or -vvv for detailed outputFrom scripts/run-tests --list, you'll see output like:
{
"suites": [
{
"name": "tracer",
"venvs": [
{
"hash": "abc123",
"python_version": "3.8",
"packages": "..."
},
{
"hash": "def456",
"python_version": "3.11",
"packages": "..."
}
]
}
]
}
Latest Python version is your default choice
One venv per suite is usually enough for iteration
Minimize total venvs
Consider test runtime
--venv DirectlyWhen you have a specific venv hash you want to run, you can use it directly without specifying file paths:
scripts/run-tests --venv e06abee
The --venv flag automatically searches all available venvs across all suites, so it works regardless of what files you have locally changed. This is useful when:
Changed file: ddtrace/contrib/internal/flask/patch.py
scripts/run-tests --list ddtrace/contrib/internal/flask/patch.py
# Output shows: contrib::flask suite available
# Select output (latest Python):
# Suite: contrib::flask
# Venv: hash=e06abee, Python 3.13, flask
# First run: no -s to ensure venv is properly set up
scripts/run-tests --venv e06abee
# Subsequent runs: use -s since only Python files changed
scripts/run-tests -s --venv e06abee
Changed file: ddtrace/_trace/tracer.py
scripts/run-tests --list ddtrace/_trace/tracer.py
# Output shows: tracer suite, internal suite available
# Select strategy:
# - tracer: latest Python (e.g., abc123)
# - internal: latest Python (e.g., def456)
# First run: no -s
scripts/run-tests --venv abc123 --venv def456
# Subsequent runs: use -s since only Python files changed
scripts/run-tests -s --venv abc123 --venv def456
Changed file: tests/contrib/flask/test_views.py
scripts/run-tests --list tests/contrib/flask/test_views.py
# Output shows: contrib::flask suite
# First run: no -s
scripts/run-tests --venv flask_py311 -- -vv tests/contrib/flask/test_views.py
# Subsequent runs: use -s to skip rebuild
scripts/run-tests -s --venv flask_py311 -- -vv tests/contrib/flask/test_views.py
After the first run shows a test failing, use -s to iterate quickly:
scripts/run-tests -s --venv flask_py311 -- -vv -k test_view_called_twice
# Focused on the specific failing test with verbose output
-s on subsequent runs: Reuse the current ddtrace installation when only Python files changed-k filter when re-running failuresgit status-s after merging from main: Native code or dependencies may have changed, requiring a rebuild-s when C/Cython/CMake files changed: Native extensions must be recompiledFor comprehensive testing guidance, refer to the contributing documentation:
docs/contributing-testing.rst - Detailed testing guidelines
scripts/run-tests usage examplesdocs/contributing.rst - PR and testing requirements
docs/contributing-design.rst - Test architecture context
When to reference these docs:
contributing-testing.rstcontributing.rstcontributing-design.rst# Manually check/stop services:
docker compose ps
docker compose down
tests/suitespec.yml to understand suite patterns-k to run subset of testsThe scripts/run-tests system:
tests/suitespec.yml-- separator.Primary suites for validation:
tracer: Core tracing functionality testsinternal: Internal component testscontrib::*: Integration with specific libraries (flask, django, etc.)integration_*: Cross-library integration scenariostelemetry, profiling, appsec, llmobs, etc.Some suites require environment setup:
DD_TRACE_AGENT_URL: For snapshot-based testsYou can limit CPU and memory resources to simulate resource-constrained CI environments where multiple jobs run in parallel. This helps reproduce flaky tests that fail due to timing issues, race conditions, or resource exhaustion.
Environment Variables:
DD_TEST_CPUS: CPU limit (e.g., 0.25, 0.5, 1.0, 2.0)DD_TEST_MEMORY: Memory limit with unit (e.g., 512m, 1g, 2g)Usage:
# Run tests with resource constraints
DD_TEST_CPUS=0.5 DD_TEST_MEMORY=1g scripts/run-tests --venv <hash>
# Run specific test file with heavy constraints
DD_TEST_CPUS=0.25 DD_TEST_MEMORY=1g scripts/run-tests tests/path/to/test.py
# Multiple runs to catch intermittent failures
for i in {1..10}; do
DD_TEST_CPUS=0.5 DD_TEST_MEMORY=1g scripts/run-tests --venv <hash> -- --randomly-seed=$RANDOM
done
Recommended Resource Limits:
Moderate Load (Typical Shared CI):
DD_TEST_CPUS=2.0 DD_TEST_MEMORY=4g
Simulates a CI runner with some other jobs running. Good for initial testing.
Heavy Load (Busy CI Server):
DD_TEST_CPUS=1.0 DD_TEST_MEMORY=2g
Simulates a heavily loaded CI server with many concurrent jobs. Recommended starting point for reproducing flaky tests.
Extreme Load (Stress Testing):
DD_TEST_CPUS=0.5 DD_TEST_MEMORY=1g
Simulates extreme resource contention. Good for surfacing timing issues and race conditions.
Critical Failure Conditions:
DD_TEST_CPUS=0.25 DD_TEST_MEMORY=512m
Forces maximum resource pressure. Use this to find the breaking point or reproduce worst-case scenarios.
When to Use Resource Limits:
Verifying Limits Are Applied:
# Check configuration before running
DD_TEST_CPUS=0.5 DD_TEST_MEMORY=1g docker compose config | grep -A 5 testrunner
# Monitor actual resource usage during test run (in another terminal)
docker stats
Example: Testing a Flaky Test
# Run a known flaky test 20 times with resource constraints
DD_TEST_CPUS=0.5 DD_TEST_MEMORY=1g scripts/run-tests \
tests/appsec/integrations/flask_tests/test_iast_flask_testagent.py::test_iast_unvalidated_redirect \
-- --count=20
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer