---
name: step-07-tests
description: Scaffold tests via MCP for all modified layers
model: opus
prev_step: steps/step-06-resolve.md
next_step: steps/step-08-run-tests.md
---

# Step 7: Tests

> **MANDATORY STEP — This is NOT optional.** APEX requires tests for completion.
> If you reached this step, you MUST scaffold and run tests before finishing.

**Goal:** Scaffold comprehensive tests using MCP tools. Target: >= 80% coverage.

---

## 0. Ensure Frontend Test Tooling Exists (if frontend was generated)

> **Before scaffolding frontend tests, the test infrastructure must be in place.**

```bash
# Check if Vitest is installed
WEB_DIR=$(find . -name "package.json" -not -path "*/node_modules/*" -exec dirname {} \; 2>/dev/null | head -1)
if [ -n "$WEB_DIR" ]; then
  cd "$WEB_DIR"

  # Install test dependencies if missing
  if ! grep -q '"vitest"' package.json 2>/dev/null; then
    npm install -D vitest @testing-library/react @testing-library/jest-dom @testing-library/user-event jsdom @types/testing-library__jest-dom
  fi

  # Create vitest.config.ts if missing
  if [ ! -f "vitest.config.ts" ]; then
    cat > vitest.config.ts << 'VITEST_EOF'
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
import path from 'path';

export default defineConfig({
  plugins: [react()],
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: ['./src/test/setup.ts'],
    css: true,
    include: ['src/**/*.test.{ts,tsx}'],
  },
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  },
});
VITEST_EOF
  fi

  # Create test setup file if missing
  mkdir -p src/test
  if [ ! -f "src/test/setup.ts" ]; then
    cat > src/test/setup.ts << 'SETUP_EOF'
import '@testing-library/jest-dom';
SETUP_EOF
  fi

  # Add test script to package.json if missing
  if ! grep -q '"test"' package.json 2>/dev/null; then
    # Use npm pkg set for safe JSON manipulation
    npm pkg set scripts.test="vitest run"
    npm pkg set scripts.test:watch="vitest"
    npm pkg set scripts.test:coverage="vitest run --coverage"
  fi

  cd -
fi
```

---

## 1. Ensure Test Projects Exist

### 1a. Unit Test Project

```bash
# Check for existing unit test project
UNIT_PROJECT=$(find tests/ -name "*.Tests.Unit.csproj" 2>/dev/null | head -1)

if [ -z "$UNIT_PROJECT" ]; then
  PROJECT_NAME=$(basename *.sln .sln)
  dotnet new xunit -n "${PROJECT_NAME}.Tests.Unit" -o "tests/${PROJECT_NAME}.Tests.Unit"
  dotnet add "tests/${PROJECT_NAME}.Tests.Unit" package Moq
  dotnet add "tests/${PROJECT_NAME}.Tests.Unit" package FluentAssertions
  for proj in src/*/*.csproj; do
    dotnet add "tests/${PROJECT_NAME}.Tests.Unit" reference "$proj"
  done
  dotnet sln add "tests/${PROJECT_NAME}.Tests.Unit/${PROJECT_NAME}.Tests.Unit.csproj"
fi
```

### 1b. Integration Test Project (for step-04 DB validation)

```bash
# Check for existing integration test project
INT_PROJECT=$(find tests/ -name "*.Tests.Integration.csproj" 2>/dev/null | head -1)

if [ -z "$INT_PROJECT" ]; then
  PROJECT_NAME=$(basename *.sln .sln)
  dotnet new xunit -n "${PROJECT_NAME}.Tests.Integration" -o "tests/${PROJECT_NAME}.Tests.Integration"
  dotnet add "tests/${PROJECT_NAME}.Tests.Integration" package Moq
  dotnet add "tests/${PROJECT_NAME}.Tests.Integration" package FluentAssertions
  dotnet add "tests/${PROJECT_NAME}.Tests.Integration" package Respawn
  dotnet add "tests/${PROJECT_NAME}.Tests.Integration" package Microsoft.EntityFrameworkCore.SqlServer
  for proj in src/*/*.csproj; do
    dotnet add "tests/${PROJECT_NAME}.Tests.Integration" reference "$proj"
  done
  dotnet sln add "tests/${PROJECT_NAME}.Tests.Integration/${PROJECT_NAME}.Tests.Integration.csproj"
fi
```

> **Note:** Integration tests use `DatabaseFixture` + `Respawn` with SQL Server LocalDB.
> See step-04 section 5c for details.

---

## 2. Scaffold Tests via MCP

For each layer that was modified:

### Domain Tests
```
Call: mcp__smartstack__scaffold_tests
  target_layer: "domain"
  module: "{module_code}"
  test_type: "unit"

Tests: entity creation, validation, domain events, value objects
```

### Application Tests
```
Call: mcp__smartstack__scaffold_tests
  target_layer: "application"
  module: "{module_code}"
  test_type: "unit"

Tests: service logic, CQRS handlers, FluentValidation
```

### API Tests
```
Call: mcp__smartstack__scaffold_tests
  target_layer: "api"
  module: "{module_code}"
  test_type: "integration"

Tests: controller endpoints, authorization, response DTOs
```

### Security Tests
```
Call: mcp__smartstack__scaffold_tests
  module: "{module_code}"
  test_type: "security"

Tests: RequirePermission enforcement, multi-tenant isolation
```

### Frontend Form Tests
```
For each module with create/edit pages:
  → Generate EntityCreatePage.test.tsx and EntityEditPage.test.tsx
  → Co-located next to the page component (NOT in __tests__/ folder)

Required test coverage:
  - Rendering: form renders with all expected fields
  - Validation: required fields show errors on empty submit
  - Submission: successful submit calls API and navigates back
  - Pre-fill (edit only): entity data loaded into fields
  - Navigation: back/cancel button calls navigate(-1)
  - Error handling: API error displays error message

Tools: Vitest + React Testing Library + @testing-library/user-event
Mock API: vi.mock() or MSW — NEVER real API calls
```

---

## 3. Suggest Additional Scenarios

```
Call: mcp__smartstack__suggest_test_scenarios
  module: "{module_code}"

Review suggestions and add relevant test cases.
```

---

## 4. Analyze Coverage

```
Call: mcp__smartstack__analyze_test_coverage
  module: "{module_code}"

Target: >= 80% coverage
If under 80%: identify uncovered paths, scaffold additional tests
```

---

## 5. Test Summary

```
**APEX SmartStack - Tests Scaffolded**

| Layer | Tests Created | Coverage |
|-------|--------------|----------|
| Domain | {count} | {%} |
| Application | {count} | {%} |
| API | {count} | {%} |
| Security | {count} | {%} |
| Frontend Forms | {count} | {%} |

**Total tests:** {count}
**Estimated coverage:** {%}
```

---

## 6. Save Output (if save_mode)

Write to `{output_dir}/07-tests.md` with test scaffolding results.

---

## NEXT STEP

Load `steps/step-08-run-tests.md`
