This commit implements a unified test orchestration system that coordinates
all test suites across the BlackRoad Operating System monorepo, providing
consistent testing behavior between local development and CI/CD environments.
## Core Components
### 1. Test Orchestrator Script (test_all.sh)
- Unified interface to run all test suites
- Smart suite detection with existence checks
- Two operational modes:
* Best-effort: Run all suites, report summary (default)
* Strict mode: Fail-fast on first error (--strict)
- Color-coded, structured output with summary table
- Modular suite functions for easy extension
- Result tracking with pass/fail/skip status and duration
- Verbose mode for detailed test output
Supported test suites:
- Backend (FastAPI + pytest)
- Agents (200+ AI agent ecosystem)
- Operator Engine (GitHub automation)
- Python SDK (pytest)
- TypeScript SDK (Jest)
- Frontend (structure validation)
### 2. GitHub Actions Workflow (.github/workflows/test-orchestrator.yml)
- Runs orchestrator in CI using same script as local dev
- Service containers (Postgres, Redis) for integration tests
- Multi-language runtime setup (Python 3.11, Node 20)
- Dependency caching for faster builds
- Test artifact uploads (coverage, reports)
- Manual workflow dispatch with suite selection
- Coverage reporting for PRs (Codecov integration)
- Automatic PR status comments
### 3. Comprehensive Documentation (TESTING.md)
- Complete testing guide for developers and AI assistants
- Quick start examples
- Suite-by-suite documentation
- Local development setup instructions
- CI/CD integration guide
- Test writing best practices
- Troubleshooting FAQ with common issues and solutions
- Framework-specific examples
## Reusable Templates (.templates/test-orchestrator/)
Created generic templates for use in other repositories:
### Template Files
- test_all.sh.template - Generic orchestrator script
- test-orchestrator.yml.template - Generic CI workflow
- TESTING.md.template - Generic testing documentation
- PROMPTS.md - AI assistant prompts for implementation
- README.md - Template usage guide and customization instructions
### Key Features
- Clear placeholders ({{REPO_NAME}}, {{PROJECT_DESCRIPTION}}, etc.)
- Comprehensive inline comments
- Framework-agnostic design (Python/Node/Go/Rust examples)
- Adaptation guides for different project structures
- AI assistant prompts for Claude, Copilot, ChatGPT
### Use Cases
- Multi-language monorepos
- Microservices architectures
- Data science projects
- Infrastructure projects
- Any project needing unified test orchestration
## Benefits
1. **Consistency**: Same test experience locally and in CI
2. **Discoverability**: New contributors know exactly how to run tests
3. **Maintainability**: Single pattern to learn and maintain
4. **Extensibility**: Easy to add new test suites
5. **CI-Friendly**: Optimized for GitHub Actions
6. **Reusability**: Templates can be copied to any repo
## Usage
Local development:
./test_all.sh # Run all suites
./test_all.sh --strict # Fail-fast mode
./test_all.sh --suite backend # Run specific suite
./test_all.sh --verbose # Detailed output
CI triggers automatically on:
- Push to main, claude/**, copilot/**, codex/** branches
- Pull requests to main
- Manual workflow dispatch
## Migration Notes
This implementation:
- Preserves existing test scripts (scripts/run_backend_tests.sh)
- Works alongside existing CI workflows
- Can be adopted gradually or all at once
- Requires no changes to existing test code
## Future Enhancements
Potential additions:
- Matrix testing across Python/Node versions
- Performance benchmarking suite
- Flaky test detection
- Test result caching
- Slack/Discord notifications
---
Pattern adapted for: BlackRoad Operating System monorepo
Designed for: Maximum reusability across projects
Target audience: Developers, DevOps engineers, AI assistants
Test Orchestrator Templates
Reusable test orchestrator pattern for any monorepo
These templates provide a complete testing infrastructure that you can copy to any repository. The pattern has been battle-tested in BlackRoad Operating System and is designed to be easily adaptable.
What's Included
test_all.sh.template- Universal test orchestrator scripttest-orchestrator.yml.template- GitHub Actions workflowTESTING.md.template- Comprehensive testing documentation
Quick Start: Copy to New Repo
1. Copy Templates
# In your target repository
mkdir -p .github/workflows
# Copy orchestrator script
cp /path/to/BlackRoad/.templates/test-orchestrator/test_all.sh.template ./test_all.sh
chmod +x test_all.sh
# Copy GitHub Actions workflow
cp /path/to/BlackRoad/.templates/test-orchestrator/test-orchestrator.yml.template .github/workflows/test-orchestrator.yml
# Copy documentation
cp /path/to/BlackRoad/.templates/test-orchestrator/TESTING.md.template ./TESTING.md
2. Customize for Your Repo
Edit test_all.sh and replace placeholders:
{{REPO_NAME}}→ Your repository name{{PROJECT_DESCRIPTION}}→ Brief project description- Suite functions → Adapt to your project structure
Edit .github/workflows/test-orchestrator.yml:
- Update service containers if needed
- Adjust cache paths
- Modify environment variables
Edit TESTING.md:
- Update project-specific details
- Add your test suites
- Customize examples
3. Run Tests
./test_all.sh
Adapting to Different Project Structures
Example 1: Pure Python Project
# test_all.sh - Keep only Python suites
run_backend_tests() {
# Your main Python package
}
run_cli_tests() {
# CLI tool tests
}
run_integration_tests() {
# Integration tests
}
Example 2: Pure Node.js Project
# test_all.sh - Keep only Node suites
run_api_tests() {
# Express/Fastify API
}
run_frontend_tests() {
# React/Vue/Svelte
}
run_sdk_tests() {
# Client SDK
}
Example 3: Microservices
# test_all.sh - One suite per service
run_auth_service_tests() {
cd services/auth && npm test
}
run_api_gateway_tests() {
cd services/api-gateway && go test ./...
}
run_data_service_tests() {
cd services/data && pytest
}
Pattern Philosophy
Core Principles
- One script to rule them all:
test_all.shis the single source of truth - CI = Local: Same script runs everywhere
- Best-effort by default: Run all suites, report at end
- Strict mode available: Fail-fast when needed
- Clear output: Color-coded, structured, summary table
Benefits
✅ Consistency: Same test experience across all repos ✅ Discoverability: New contributors know exactly how to run tests ✅ Maintainability: One pattern to learn and maintain ✅ Extensibility: Easy to add new test suites ✅ CI-friendly: Works perfectly with GitHub Actions
Customization Guide
Adding a New Test Suite
- Create suite function in
test_all.sh:
run_myapp_tests() {
log_suite "MyApp (description)"
local start_time=$(date +%s)
# Check if suite exists
if [[ ! -d "$ROOT/myapp" ]]; then
log_skip "myapp/ directory not found"
record_result "myapp" "SKIP" "0s"
return 0
fi
cd "$ROOT/myapp"
# Run your tests
log_info "Running tests..."
npm test # or pytest, or whatever
local exit_code=$?
local end_time=$(date +%s)
local duration=$((end_time - start_time))
if [[ $exit_code -eq 0 ]]; then
log_success "MyApp tests passed"
record_result "myapp" "PASS" "${duration}s"
else
log_error "MyApp tests failed"
record_result "myapp" "FAIL" "${duration}s"
return 1
fi
cd "$ROOT"
}
- Add to main execution block:
# In main execution section
if [[ -z "$SPECIFIC_SUITE" ]]; then
run_backend_tests || true
run_myapp_tests || true # Add here
# ...
fi
- Add to suite list in
print_summary():
for suite in backend myapp frontend; do # Add "myapp"
# ...
done
- Add to --help:
AVAILABLE SUITES:
backend Backend API tests
myapp MyApp tests # Add here
frontend Frontend tests
Removing Unnecessary Suites
If your project doesn't have certain suites (e.g., no TypeScript), simply remove:
- The suite function (
run_sdk_typescript_tests) - The call in main execution
- The entry in
print_summary() - The entry in
--help
Changing Test Frameworks
Replace test commands in suite functions:
# From pytest to unittest
pytest -v
# to
python -m unittest discover
# From Jest to Vitest
npm test
# to
npx vitest run
# From npm to pnpm
npm install
# to
pnpm install
GitHub Actions Customization
Service Containers
Add/remove as needed in .github/workflows/test-orchestrator.yml:
services:
postgres: # Remove if not needed
image: postgres:15-alpine
# ...
mysql: # Add if needed
image: mysql:8
env:
MYSQL_ROOT_PASSWORD: test
# ...
mongodb: # Add if needed
image: mongo:7
# ...
Matrix Testing
Test across multiple versions:
jobs:
orchestrator:
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12']
node-version: ['18', '20']
steps:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
Scheduled Runs
Add cron schedule:
on:
push:
branches: ["main"]
schedule:
- cron: '0 2 * * *' # Run at 2 AM daily
Examples from Other Projects
Example: Data Science Project
# test_all.sh
run_notebooks_tests() {
log_suite "Jupyter Notebooks (validation)"
jupyter nbconvert --to notebook --execute notebooks/*.ipynb
}
run_models_tests() {
log_suite "ML Models (validation)"
pytest tests/models/ -v
}
run_data_pipeline_tests() {
log_suite "Data Pipeline (integration)"
python -m data_pipeline.test_runner
}
Example: Infrastructure Project
# test_all.sh
run_terraform_tests() {
log_suite "Terraform (validation)"
cd infra/terraform
terraform fmt -check
terraform validate
}
run_ansible_tests() {
log_suite "Ansible (syntax check)"
cd infra/ansible
ansible-playbook --syntax-check playbook.yml
}
run_docker_tests() {
log_suite "Docker (build test)"
docker build -t myapp:test .
}
Example: Mobile App Project
# test_all.sh
run_ios_tests() {
log_suite "iOS App (XCTest)"
cd ios
xcodebuild test -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 15'
}
run_android_tests() {
log_suite "Android App (JUnit)"
cd android
./gradlew test
}
run_shared_tests() {
log_suite "Shared Code (Kotlin Multiplatform)"
cd shared
./gradlew allTests
}
AI Assistant Prompt
Use this prompt to have AI assistants (Claude/Copilot/ChatGPT) adapt these templates:
I want to use the BlackRoad Test Orchestrator pattern in my repository.
Here's my project structure:
[paste tree output or describe structure]
Here are my test commands:
- Component A: [command]
- Component B: [command]
- Component C: [command]
Please:
1. Adapt test_all.sh.template to my project
2. Customize test-orchestrator.yml.template for my CI needs
3. Update TESTING.md.template with my project details
Keep the same structure and philosophy, just adapt the suite functions and paths.
Migration from Existing Test Scripts
If you already have test scripts:
1. Inventory Existing Scripts
find . -name "*test*" -type f -executable
# List all test-related scripts
2. Map to Orchestrator Suites
| Old Script | New Suite Function |
|---|---|
scripts/test-backend.sh |
run_backend_tests() |
scripts/test-frontend.sh |
run_frontend_tests() |
Makefile target test |
Suite functions |
3. Migrate Gradually
Keep old scripts during transition:
run_backend_tests() {
log_suite "Backend"
# Call old script temporarily
bash scripts/test-backend.sh
# Record result based on exit code
if [[ $? -eq 0 ]]; then
record_result "backend" "PASS" "Xs"
else
record_result "backend" "FAIL" "Xs"
fi
}
4. Refactor Over Time
Once orchestrator is working, gradually refactor suite functions to be self-contained.
Troubleshooting
Common Adaptation Issues
Issue: Suite detection doesn't work
Fix: Check directory paths in suite functions (if [[ ! -d "$ROOT/myapp" ]])
Issue: Tests fail in CI but pass locally Fix: Check environment variables, service containers, and paths
Issue: Colors don't show in CI Fix: This is normal; GitHub Actions strips color codes from logs
Issue: --suite flag doesn't work for new suite Fix: Add new suite to the case statement in main execution
Support
- Original Implementation: BlackRoad Operating System
- Issues: Report in your repository's issue tracker
- Questions: Refer to
TESTING.mdin BlackRoad repo for detailed examples
License
These templates are provided as-is from the BlackRoad Operating System project. Adapt freely for your own projects.
Happy Testing! 🧪✨