name: Test Suite on: push: branches: [ main, develop ] pull_request: branches: [ main ] jobs: unit-tests: runs-on: ubuntu-latest strategy: matrix: python-version: ["3.11", "3.12"] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Cache dependencies uses: actions/cache@v3 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }} restore-keys: | ${{ runner.os }}-pip- - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt pip install -r tests/requirements-test.txt - name: Run unit tests run: | pytest tests/unit/ -v \ --cov=domain \ --cov=application \ --cov=infrastructure \ --cov-report=xml \ --cov-report=term-missing \ --cov-fail-under=85 \ --tb=short \ --durations=10 - name: Upload coverage to Codecov uses: codecov/codecov-action@v3 with: file: ./coverage.xml flags: unit-tests name: codecov-umbrella integration-tests: runs-on: ubuntu-latest needs: unit-tests steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 with: python-version: "3.12" - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt pip install -r tests/requirements-test.txt - name: Run integration tests run: | pytest tests/integration/ -v \ --tb=short \ --maxfail=5 \ --timeout=300 - name: Archive test artifacts if: failure() uses: actions/upload-artifact@v3 with: name: integration-test-artifacts path: | tests/integration/logs/ tests/integration/outputs/ e2e-tests: runs-on: ubuntu-latest needs: [unit-tests, integration-tests] steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 with: python-version: "3.12" - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt pip install -r tests/requirements-test.txt - name: Run end-to-end tests (non-slow) run: | pytest tests/e2e/ -v \ -m "not slow" \ --tb=short \ --maxfail=3 \ --timeout=600 - name: Run smoke tests run: | pytest tests/ -v \ -m "smoke" \ --tb=short \ --timeout=120 performance-tests: runs-on: ubuntu-latest needs: [unit-tests, integration-tests] if: github.event_name == 'push' && github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 with: python-version: "3.12" - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt pip install -r tests/requirements-test.txt - name: Run performance tests run: | pytest tests/e2e/performance/ -v \ -m "performance" \ --tb=short \ --timeout=1200 - name: Archive performance results uses: actions/upload-artifact@v3 with: name: performance-results path: | performance-results.json performance-charts/ code-quality: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 with: python-version: "3.12" - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r tests/requirements-test.txt - name: Run flake8 run: | flake8 domain/ application/ infrastructure/ --count --select=E9,F63,F7,F82 --show-source --statistics flake8 domain/ application/ infrastructure/ --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - name: Run mypy run: | mypy domain/ application/ infrastructure/ --ignore-missing-imports - name: Check code formatting with black run: | black --check domain/ application/ infrastructure/ - name: Check import sorting with isort run: | isort --check-only domain/ application/ infrastructure/ security-scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 with: python-version: "3.12" - name: Install dependencies run: | python -m pip install --upgrade pip pip install safety bandit - name: Run safety check run: | pip freeze | safety check --json - name: Run bandit security linter run: | bandit -r domain/ application/ infrastructure/ -f json -o bandit-results.json - name: Upload security scan results uses: actions/upload-artifact@v3 with: name: security-scan-results path: | bandit-results.json test-summary: runs-on: ubuntu-latest needs: [unit-tests, integration-tests, e2e-tests, code-quality, security-scan] if: always() steps: - name: Check test results run: | echo "Unit Tests: ${{ needs.unit-tests.result }}" echo "Integration Tests: ${{ needs.integration-tests.result }}" echo "E2E Tests: ${{ needs.e2e-tests.result }}" echo "Code Quality: ${{ needs.code-quality.result }}" echo "Security Scan: ${{ needs.security-scan.result }}" if [[ "${{ needs.unit-tests.result }}" == "failure" || "${{ needs.integration-tests.result }}" == "failure" || "${{ needs.e2e-tests.result }}" == "failure" ]]; then echo "❌ Test suite failed" exit 1 else echo "✅ Test suite passed" fi - name: Update status badge if: github.ref == 'refs/heads/main' run: | # This would update a status badge in the README echo "Test suite status: PASSING" > test-status.txt - name: Upload test summary uses: actions/upload-artifact@v3 with: name: test-summary path: test-status.txt