#!/usr/bin/env bash set -euo pipefail show_help() { cat <<'EOF' sf-test-run โ€” wrapper for focused Apex test execution USAGE: sf-test-run -to (-cn | -sn | -al) [-lv ] [-cv] [-wt ] [-hp] OPTIONS: -to Target org alias or username to run tests in (required) -cn Comma-separated test class names -sn Comma-separated test suite names -al Run all tests in the org -lv Test level (RunLocalTests, RunAllTestsInOrg, RunSpecifiedTests) -cv Generate code coverage report -wt Wait time in minutes (default: 10) -hp Show this help EXAMPLES: 1) Run specific test classes: sf-test-run -to DEMO-ORG -cn "MyTestClass,AnotherTestClass" 2) Run test suites: sf-test-run -to DEMO-ORG -sn "UnitTests,IntegrationTests" 3) Run all local tests with coverage: sf-test-run -to DEMO-ORG -lv RunLocalTests -cv 4) Run all tests in org (be careful!): sf-test-run -to DEMO-ORG -al -wt 30 5) Quick test with custom wait time: sf-test-run -to DEMO-ORG -cn "QuickTest" -wt 5 TEST LEVELS: - RunLocalTests: Run all tests in your org except managed package tests - RunAllTestsInOrg: Run all tests including managed package tests - RunSpecifiedTests: Run only specified test classes/suites Notes: - Default wait time is 10 minutes - Use -cv to generate detailed coverage reports - RunAllTestsInOrg can take a very long time - Test results will be displayed in formatted output EOF } # Default values ORG="" CLASSES="" SUITES="" ALL_TESTS=false TEST_LEVEL="" COVERAGE=false WAIT_TIME=10 if [[ $# -eq 0 ]]; then show_help exit 0 fi # Parse arguments manually for two-character options while [[ $# -gt 0 ]]; do case $1 in -to|--target-org) if [[ -n "${2:-}" && ! "$2" =~ ^- ]]; then ORG="$2" shift 2 else echo "Error: -to requires a target org argument" >&2 show_help exit 1 fi ;; -cn|--class-names) if [[ -n "${2:-}" && ! "$2" =~ ^- ]]; then CLASSES="$2" shift 2 else echo "Error: -cn requires class names argument" >&2 show_help exit 1 fi ;; -sn|--suite-names) if [[ -n "${2:-}" && ! "$2" =~ ^- ]]; then SUITES="$2" shift 2 else echo "Error: -sn requires suite names argument" >&2 show_help exit 1 fi ;; -al|--all) ALL_TESTS=true shift ;; -lv|--level) if [[ -n "${2:-}" && ! "$2" =~ ^- ]]; then TEST_LEVEL="$2" shift 2 else echo "Error: -lv requires a test level argument" >&2 show_help exit 1 fi ;; -cv|--coverage) COVERAGE=true shift ;; -wt|--wait) if [[ -n "${2:-}" && ! "$2" =~ ^- ]]; then WAIT_TIME="$2" shift 2 else echo "Error: -wt requires a wait time argument" >&2 show_help exit 1 fi ;; -hp|--help) show_help exit 0 ;; -*) echo "Unknown option: $1" >&2 echo show_help exit 1 ;; *) echo "Unexpected argument: $1" >&2 echo show_help exit 1 ;; esac done # Validate required parameters if [[ -z "$ORG" ]]; then echo "Error: Target org (-to) is required." >&2 echo show_help exit 1 fi # Validate that at least one test method is specified if [[ -z "$CLASSES" && -z "$SUITES" && "$ALL_TESTS" != "true" && -z "$TEST_LEVEL" ]]; then echo "Error: Must specify -cn (classes), -sn (suites), -al (all tests), or -lv (test level)." >&2 echo show_help exit 1 fi # Validate wait time if ! [[ "$WAIT_TIME" =~ ^[0-9]+$ ]] || [[ "$WAIT_TIME" -lt 1 ]]; then echo "Error: Wait time must be a positive number." >&2 exit 1 fi # Validate test level if specified if [[ -n "$TEST_LEVEL" ]]; then case "$TEST_LEVEL" in "RunLocalTests"|"RunAllTestsInOrg"|"RunSpecifiedTests") # Valid test levels ;; *) echo "Error: Invalid test level. Use RunLocalTests, RunAllTestsInOrg, or RunSpecifiedTests." >&2 exit 1 ;; esac fi # Silent environment check if ! command -v sf >/dev/null 2>&1; then echo "โŒ Salesforce CLI (sf) not found!" echo echo "Running environment check to help you get started..." echo SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" if [[ -x "$SCRIPT_DIR/sf-check" ]]; then "$SCRIPT_DIR/sf-check" elif command -v sf-check >/dev/null 2>&1; then sf-check else echo "sf-check not found. Please install the Salesforce CLI from:" echo "https://developer.salesforce.com/tools/sfdxcli" fi exit 1 fi # Build the command CMD=(sf apex run test) CMD+=(--target-org "$ORG") CMD+=(--wait "$WAIT_TIME") CMD+=(--result-format human) # Determine test execution method if [[ -n "$TEST_LEVEL" ]]; then CMD+=(--test-level "$TEST_LEVEL") elif [[ "$ALL_TESTS" == "true" ]]; then CMD+=(--test-level "RunAllTestsInOrg") elif [[ -n "$CLASSES" ]]; then IFS=',' read -ra CLASSES_ARR <<< "$CLASSES" for CLASS in "${CLASSES_ARR[@]}"; do CLASS=$(echo "$CLASS" | xargs) # Trim whitespace [[ -n "$CLASS" ]] && CMD+=(--tests "$CLASS") done elif [[ -n "$SUITES" ]]; then IFS=',' read -ra SUITES_ARR <<< "$SUITES" for SUITE in "${SUITES_ARR[@]}"; do SUITE=$(echo "$SUITE" | xargs) # Trim whitespace [[ -n "$SUITE" ]] && CMD+=(--suites "$SUITE") done fi # Add code coverage if requested if [[ "$COVERAGE" == "true" ]]; then CMD+=(--code-coverage) fi # Show what we're running echo "๐Ÿงช Running Apex tests in org '$ORG'..." if [[ -n "$TEST_LEVEL" ]]; then echo " Level: $TEST_LEVEL" elif [[ "$ALL_TESTS" == "true" ]]; then echo " Level: RunAllTestsInOrg (all tests)" elif [[ -n "$CLASSES" ]]; then echo " Classes: $CLASSES" elif [[ -n "$SUITES" ]]; then echo " Suites: $SUITES" fi echo " Wait time: ${WAIT_TIME} minutes" [[ "$COVERAGE" == "true" ]] && echo " Code coverage: enabled" echo echo ">>> Running: ${CMD[*]}" echo # Create a temporary file to capture output TEMP_OUTPUT=$(mktemp) if "${CMD[@]}" 2>&1 | tee "$TEMP_OUTPUT"; then echo echo "โœ… Test execution completed!" # Parse and display summary from output if grep -q "Test Results" "$TEMP_OUTPUT"; then echo echo "๐Ÿ“Š Test Summary:" grep -A 20 "Test Results" "$TEMP_OUTPUT" | head -20 fi # Show coverage summary if coverage was requested if [[ "$COVERAGE" == "true" ]] && grep -q "Coverage" "$TEMP_OUTPUT"; then echo echo "๐Ÿ“ˆ Coverage Summary:" grep -A 10 -B 2 "Coverage" "$TEMP_OUTPUT" fi # Check for failures if grep -q "FAIL" "$TEMP_OUTPUT" || grep -q "Error" "$TEMP_OUTPUT"; then echo echo "โš ๏ธ Some tests failed. Check the output above for details." rm -f "$TEMP_OUTPUT" exit 1 fi else echo echo "โŒ Test execution failed" rm -f "$TEMP_OUTPUT" exit 1 fi # Clean up rm -f "$TEMP_OUTPUT"