Instruction file imported from zarfld/AES11-2009 (
.github/instructions/phase-06-integration.instructions.md). Copyright stays with the author.
Phase 06: Integration
Standards: ISO/IEC/IEEE 12207:2017 (Integration Process)
XP Integration: Continuous Integration, Integration Testing, Collective Ownership
🎯 Phase Objectives
- Integrate software units into components
- Integrate components into complete system
- Perform integration testing
- Verify inter-component interfaces
- Automate integration and deployment
- Maintain system integrity through continuous integration
📋 ISO/IEC/IEEE 12207:2017 Compliance
Integration Process Activities
-
Integration Strategy
- Define integration approach (big-bang, incremental, top-down, bottom-up)
- Identify integration sequence
- Define integration environment
-
Integration Execution
- Integrate software units and components
- Execute integration tests
- Document integration results
-
Integration Verification
- Verify integrated components
- Verify interfaces between components
- Resolve integration issues
🎨 XP Practices for Integration
Continuous Integration (CI)
Core Practice:
- Integrate code multiple times per day
- Automated build and test on every commit
- Keep the build green
- Fix broken builds within 10 minutes
Integration Testing
- Test component interactions
- Test external system interfaces
- Test with real (or realistic) dependencies
- Automated integration test suites
Reliability Integration (IEEE 1633 5.4)
To prepare for reliability estimation during/after testing, ensure the following are in place:
- Operational Profile (OP) created for this release (
spec-kit-templates/operational-profile.md), with states, transitions, and relative frequencies mapped to executable tests - Data collection hooks for reliability metrics:
- Execution/duty time capture per test run
- Failure logging with severity and timestamps
- Trend checks (e.g., Laplace, U/N/S-shaped) for stability
- Model selection and fitting workflow defined (e.g., Musa-Okumoto, Goel-Okumoto, Crow/AMSAA)
- Accuracy verification plan comparing SRG estimates to recent observed MTBF (see IEEE 1633 5.4.7)
- Evidence locations and naming conventions (results, model parameters, and reports)
Collective Code Ownership
- Team owns integration process
- Anyone can fix integration issues
- Shared responsibility for system integrity
📝 Required Deliverables
1. Integration Strategy Document
Location: integration-strategy.md
# Integration Strategy
## 1. Integration Approach
### Incremental Integration
We will use **continuous incremental integration**:
- Integrate components as they become available
- Test after each integration
- Fix issues immediately
- Maintain working system at all times
### Integration Sequence
Phase 1: Core Components
- Database layer
- Business logic layer
- API layer
Phase 2: External Integrations
- Authentication service
- Payment gateway
- Email service
Phase 3: UI Components
- Web frontend
- Mobile apps
- Admin dashboard
## 2. Integration Environment
### Development Integration
- **Trigger**: Every commit to feature branch
- **Tests**: Unit + Integration tests
- **Deployment**: None
### Staging Integration
- **Trigger**: Merge to `develop` branch
- **Tests**: Full test suite
- **Deployment**: Staging environment
- **Data**: Anonymized production data
### Production Integration
- **Trigger**: Merge to `main` branch
- **Tests**: Smoke tests
- **Deployment**: Production (blue-green)
- **Rollback**: Automated on failure
## 3. Integration Tools
### CI/CD Pipeline
- **Platform**: GitHub Actions / GitLab CI / Jenkins
- **Build Tool**: [Tool name]
- **Test Runner**: [Tool name]
- **Deployment**: Docker + Kubernetes
### Integration Testing Tools
- **API Testing**: Postman/Newman, REST-assured
- **Database**: TestContainers
- **Mocking**: WireMock, Mockserver
- **Load Testing**: k6, Artillery
## 4. Integration Testing Strategy
### Component Integration Tests
Test interactions between internal components:
```typescript
describe('UserService Integration', () => {
let app: TestApp;
let database: TestDatabase;
beforeAll(async () => {
database = await TestDatabase.create();
app = await TestApp.create({ database });
});
afterAll(async () => {
await app.close();
await database.close();
});
it('should create user and persist to database', async () => {
const userData = { username: 'test', email: 'test@example.com' };
const user = await app.service.user.create(userData);
const saved = await database.users.findById(user.id);
expect(saved).toMatchObject(userData);
});
});
External System Integration Tests
Test interactions with external services:
describe('Payment Gateway Integration', () => {
let mockPaymentServer: MockServer;
beforeAll(() => {
mockPaymentServer = startMockServer(8080);
});
it('should process payment via gateway', async () => {
mockPaymentServer.expectRequest({
method: 'POST',
path: '/payments',
body: { amount: 100 }
}).respondWith({
status: 200,
body: { transactionId: '12345', status: 'success' }
});
const result = await paymentService.process({ amount: 100 });
expect(result.transactionId).toBe('12345');
});
});
4.1 Reliability Test Plan (OP-driven)
Link to or include the OP and explicitly map abstract actions to executable test adapters. Define:
- Model coverage targets (states %, transitions %)
- Structural code coverage thresholds (statement/branch/MCDC as applicable)
- Data collection schema (duty time, failures, restore times)
- SRG model(s) to be fit and criteria for selection
- Reporting cadence and locations for estimates (reliability, availability, residual defects)
5. Continuous Integration Configuration
Build Pipeline
- Checkout: Get latest code
- Install: Install dependencies
- Lint: Check code quality
- Build: Compile/transpile code
- Unit Test: Run unit tests
- Integration Test: Run integration tests
- Security Scan: Check for vulnerabilities
- Build Artifacts: Create deployment artifacts
- Deploy: Deploy to environment (if tests pass)
Quality Gates
- Unit test coverage > 80%
- Integration tests all passing
- No critical vulnerabilities
- Code quality score > 75
- No code smells
6. Integration Issue Resolution
Issue Tracking
- Log all integration failures
- Assign owner immediately
- Target resolution: < 10 minutes
- Escalate if not resolved in 30 minutes
Root Cause Analysis
For recurring integration issues:
- Identify root cause
- Document in post-mortem
- Implement preventive measures
- Update integration tests
7. Traceability
| Component | Design Element | Integration Tests |
|---|---|---|
| UserService | DES-C-001 | INT-TEST-001 |
| PaymentGateway | DES-C-005 | INT-TEST-005 |
### 2. CI/CD Pipeline Configuration
**Location**: `ci-config/github-actions.yml`
```yaml
name: CI/CD Pipeline
on:
push:
branches: [main, develop, 'feature/**']
pull_request:
branches: [main, develop]
env:
NODE_VERSION: '18'
COVERAGE_THRESHOLD: 80
jobs:
lint:
name: Lint Code
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
- name: Check formatting
run: npm run format:check
test:
name: Run Tests
runs-on: ubuntu-latest
needs: lint
services:
postgres:
image: postgres:14
env:
POSTGRES_PASSWORD: test
POSTGRES_DB: testdb
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
redis:
image: redis:7
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run unit tests
run: npm run test:unit -- --coverage
env:
NODE_ENV: test
- name: Run integration tests
run: npm run test:integration
env:
NODE_ENV: test
DATABASE_URL: postgresql://postgres:test@localhost:5432/testdb
REDIS_URL: redis://localhost:6379
- name: Check coverage threshold
run: |
COVERAGE=$(node -p "require('./coverage/coverage-summary.json').total.lines.pct")
echo "Coverage: $COVERAGE%"
if (( $(echo "$COVERAGE < $COVERAGE_THRESHOLD" | bc -l) )); then
echo "Coverage $COVERAGE% is below threshold $COVERAGE_THRESHOLD%"
exit 1
fi
- name: Upload coverage reports
uses: codecov/codecov-action@v3
with:
files: ./coverage/coverage-final.json
flags: unittests
name: codecov-umbrella
security:
name: Security Scan
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v3
- name: Run security audit
run: npm audit --audit-level=high
- name: Run SAST scan
uses: github/codeql-action/analyze@v2
- name: Check for secrets
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: main
head: HEAD
build:
name: Build Application
runs-on: ubuntu-latest
needs: [test, security]
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build application
run: npm run build
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Save Docker image
run: docker save myapp:${{ github.sha }} | gzip > myapp.tar.gz
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: build-artifacts
path: |
dist/
myapp.tar.gz
deploy-staging:
name: Deploy to Staging
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/develop'
environment:
name: staging
url: https://staging.example.com
steps:
- uses: actions/checkout@v3
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: build-artifacts
- name: Deploy to staging
run: |
# Deploy using your preferred method
kubectl apply -f k8s/staging/
- name: Run smoke tests
run: npm run test:smoke
env:
BASE_URL: https://staging.example.com
deploy-production:
name: Deploy to Production
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main'
environment:
name: production
url: https://example.com
steps:
- uses: actions/checkout@v3
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: build-artifacts
- name: Deploy to production (blue-green)
run: |
# Blue-green deployment
kubectl apply -f k8s/production/
- name: Run smoke tests
run: npm run test:smoke
env:
BASE_URL: https://example.com
- name: Rollback on failure
if: failure()
run: kubectl rollout undo deployment/myapp
3. Integration Test Suite
Location: integration-tests/user-workflow.test.ts
import { TestApp } from '../test-utils/TestApp';
import { TestDatabase } from '../test-utils/TestDatabase';
describe('User Workflow Integration Tests', () => {
let app: TestApp;
let db: TestDatabase;
let apiClient: APIClient;
beforeAll(async () => {
// Setup test environment
db = await TestDatabase.create();
app = await TestApp.create({
database: db,
redis: await TestRedis.create()
});
apiClient = app.getAPIClient();
});
afterAll(async () => {
await app.close();
await db.close();
});
beforeEach(async () => {
await db.clear();
});
describe('User Registration Flow', () => {
it('should complete full registration workflow', async () => {
// 1. Register user
const registrationData = {
username: 'newuser',
email: 'newuser@example.com',
password: 'SecurePass123!'
};
const registerResponse = await apiClient.post('/api/auth/register', registrationData);
expect(registerResponse.status).toBe(201);
expect(registerResponse.data).toHaveProperty('userId');
const userId = registerResponse.data.userId;
// 2. Verify user exists in database
const userInDb = await db.users.findById(userId);
expect(userInDb).toBeDefined();
expect(userInDb.username).toBe('newuser');
expect(userInDb.isActive).toBe(true);
// 3. Login with credentials
const loginResponse = await apiClient.post('/api/auth/login', {
username: 'newuser',
password: 'SecurePass123!'
});
expect(loginResponse.status).toBe(200);
expect(loginResponse.data).toHaveProperty('accessToken');
const accessToken = loginResponse.data.accessToken;
// 4. Access protected resource
const profileResponse = await apiClient.get('/api/users/me', {
headers: { Authorization: `Bearer ${accessToken}` }
});
expect(profileResponse.status).toBe(200);
expect(profileResponse.data.username).toBe('newuser');
// 5. Verify audit log
const auditLogs = await db.auditLogs.findByUserId(userId);
expect(auditLogs).toHaveLength(2); // Registration + Login
expect(auditLogs[0].action).toBe('USER_REGISTERED');
expect(auditLogs[1].action).toBe('USER_LOGGED_IN');
});
});
describe('External Service Integration', () => {
it('should integrate with email service', async () => {
const mockEmailServer = startMockEmailServer();
// Register user (triggers welcome email)
const response = await apiClient.post('/api/auth/register', {
username: 'test',
email: 'test@example.com',
password: 'Pass123!'
});
// Verify email was sent
await waitFor(() => {
const emails = mockEmailServer.getReceivedEmails();
expect(emails).toHaveLength(1);
expect(emails[0].to).toBe('test@example.com');
expect(emails[0].subject).toContain('Welcome');
});
mockEmailServer.close();
});
});
});
� Reliability Engineering Activities (IEEE 1633)
1. OP-Driven Reliability Test Design
Prompt: Use .github/prompts/reliability-test-design.prompt.md
During Phase 06, design reliability tests based on the Operational Profile created in Phase 05:
Step 1: Review Operational Profile
- User classes and usage percentages
- Operations ranked by frequency (80-20 rule: top 20% operations = 80% usage)
- MCUM (Markov Chain Usage Model) with states and transitions
- Mission profiles (typical usage sessions)
Step 2: Generate Test Cases from MCUM
- All-States Coverage: Create tests visiting each state
- All-Transitions Coverage: Create tests traversing each transition
- Usage-Weighted Allocation: Allocate more test cases to high-probability transitions
- Example: If T-001 (Login) has 30% probability, allocate 30% of test effort
- Mission Profile Tests: Create end-to-end scenario tests
Step 3: Design Test Adapters Test adapters are self-contained functions that:
- Invoke an operation (from OP)
- Provide inputs (valid/invalid per input events)
- Capture outputs (per output responses)
- Return pass/fail (per FDSC - Failure Definition and Scoring Criteria)
- Are independent (can run in any order)
Example test adapter:
// Test Adapter for Operation: OP-001 (User Login)
// MCUM Transition: T-001 (S-000 Idle → S-001 Authenticated)
interface TestResult {
passed: boolean;
actualState: string;
expectedState: string;
failureSeverity: number; // Per FDSC
executionTime: number; // milliseconds
errorMessage?: string;
}
async function testLogin(username: string, password: string): Promise<TestResult> {
const startTime = Date.now();
const initialState = await getSystemState(); // Should be S-000
try {
const authToken = await systemUnderTest.login(username, password);
const actualState = await getSystemState();
const expectedState = password === 'validPass' ? 'S-001' : 'S-000';
const passed = (actualState === expectedState) && (authToken !== null);
return {
passed,
actualState,
expectedState,
failureSeverity: passed ? 0 : 10, // Critical if login fails
executionTime: Date.now() - startTime,
errorMessage: passed ? undefined : 'Login failed or state incorrect'
};
} catch (error) {
return {
passed: false,
actualState: await getSystemState(),
expectedState: 'S-001',
failureSeverity: 10,
executionTime: Date.now() - startTime,
errorMessage: error.message
};
}
}
Step 4: Allocate Test Effort Apply 80-20 rule:
- Tier 1 (0-50% cumulative usage): 50% of test effort
- Tier 2 (50-80% cumulative usage): 30% of test effort
- Tier 3 (80-95% cumulative usage): 15% of test effort
- Tier 4 (95-100% cumulative usage): 5% of test effort
Critical operations require minimum coverage (100%) regardless of usage frequency.
Deliverable:
- Complete Reliability Test Plan (RTP) document
- Test adapters implemented (in
integration-tests/reliability/) - Test execution automation
- Coverage tracking (states, transitions, operations)
Location: 06-integration/integration-tests/reliability/
2. SRG Data Collection Setup
Prompt: Will use .github/prompts/srg-model-fit.prompt.md in Phase 07
Prepare for Software Reliability Growth (SRG) modeling:
Configure Failure Data Collection:
// Failure data structure (for SRG modeling)
interface FailureRecord {
failureNumber: number; // Sequential: 1, 2, 3, ...
failureTime: number; // Hours (or test case number)
testCase: string; // Test case that failed
operation: string; // OP-XXX
state: string; // S-XXX (state when failed)
severity: number; // FDSC score (1-10)
description: string;
rootCause?: string; // Once investigated
fixed: boolean; // Has fix been applied?
fixTime?: number; // When fixed (hours)
}
// Log failure during test execution
async function logFailure(testResult: TestResult, testCase: string): Promise<void> {
if (!testResult.passed) {
const failureRecord: FailureRecord = {
failureNumber: await getNextFailureNumber(),
failureTime: getCurrentTestTime(), // hours since test start
testCase: testCase,
operation: extractOperation(testCase), // e.g., "OP-001"
state: testResult.actualState,
severity: testResult.failureSeverity,
description: testResult.errorMessage || 'Unknown failure',
fixed: false
};
await saveFailureRecord(failureRecord);
// Also log for monitoring
logger.error('Reliability test failure', {
failureNumber: failureRecord.failureNumber,
failureTime: failureRecord.failureTime,
operation: failureRecord.operation,
severity: failureRecord.severity
});
}
}
// Export SRG data (CSV format for modeling tools)
async function exportSRGData(outputFile: string): Promise<void> {
const failures = await getAllFailures();
const csv = ['FailureNumber,FailureTime,Severity,Operation,State,Fixed'];
failures.forEach(f => {
csv.push(`${f.failureNumber},${f.failureTime},${f.severity},${f.operation},${f.state},${f.fixed}`);
});
await writeFile(outputFile, csv.join('\n'));
}
SRG Data Requirements:
- Timestamp (or test case number) for each failure
- Failure severity (per FDSC)
- Operation that failed (from OP)
- State when failure occurred (from MCUM)
- Fix status (boolean: fixed or not)
Deliverable:
- Failure logging infrastructure
- CSV export for SRG tools
- Failure database schema
3. Continuous Reliability Monitoring
Monitor During Integration Testing:
Metrics to Track:
| Metric | Description | Target | Action if Threshold Exceeded |
|---|---|---|---|
| Test Pass Rate | % of tests passing | ≥ 95% | Investigate failing tests, fix defects |
| Failure Intensity | Failures per hour | Decreasing trend | If increasing, stop and investigate |
| Mean Time Between Failures (MTBF) | Average time between failures | Increasing trend | If decreasing, reliability declining |
| Defect Discovery Rate | Defects found per test hour | < [X] per hour | If increasing, code quality issue |
| Critical Failures | FDSC Severity = 10 | 0 | Immediate fix required |
Reliability Dashboard:
interface ReliabilityMetrics {
testRunNumber: number;
testTime: number; // hours
totalTests: number;
passingTests: number;
failingTests: number;
passRate: number; // percentage
failures: number; // cumulative failures
failureIntensity: number; // failures per hour
mtbf: number; // hours (calculated)
criticalFailures: number;
}
async function calculateReliabilityMetrics(): Promise<ReliabilityMetrics> {
const tests = await getTestResults();
const failures = await getAllFailures();
const testTime = getCurrentTestTime();
const passingTests = tests.filter(t => t.passed).length;
const failingTests = tests.length - passingTests;
const passRate = (passingTests / tests.length) * 100;
const failureIntensity = failures.length / testTime;
const mtbf = testTime / failures.length;
const criticalFailures = failures.filter(f => f.severity === 10).length;
return {
testRunNumber: await getCurrentTestRun(),
testTime,
totalTests: tests.length,
passingTests,
failingTests,
passRate,
failures: failures.length,
failureIntensity,
mtbf,
criticalFailures
};
}
Deliverable: Reliability metrics dashboard (real-time visibility)
4. Integration Quality Gate (Reliability)
Quality Gate Threshold (from SRPP Section 4.3):
- Integration Test Pass Rate: ≥ 95%
- MTBF Estimate: Track trend (should be increasing)
- Critical Failures: 0 (none allowed to proceed to Phase 07)
Pass/Fail Decision:
async function checkReliabilityQualityGate(): Promise<{ passed: boolean; reasons: string[] }> {
const metrics = await calculateReliabilityMetrics();
const reasons: string[] = [];
// Check 1: Pass rate ≥ 95%
if (metrics.passRate < 95) {
reasons.push(`Integration pass rate ${metrics.passRate}% < 95%`);
}
// Check 2: No critical failures
if (metrics.criticalFailures > 0) {
reasons.push(`${metrics.criticalFailures} critical failures open`);
}
// Check 3: MTBF trend (compare to previous run)
const previousMTBF = await getPreviousMTBF();
if (metrics.mtbf < previousMTBF * 0.9) { // 10% decrease threshold
reasons.push(`MTBF declining: ${metrics.mtbf} < ${previousMTBF} (previous)`);
}
return {
passed: reasons.length === 0,
reasons
};
}
If Quality Gate Fails:
- Fix critical defects immediately
- Re-run reliability tests
- Re-assess quality gate
- Do NOT proceed to Phase 07 until gate passed
Deliverable: Quality gate status report
5. SFMEA Updates
Review and update SFMEA (created in Phase 04/05) based on integration failures:
Update CIL (Critical Items List):
- Add new failure modes discovered during integration
- Update RPN (Risk Priority Number) based on actual failure data
- Verify mitigation actions are effective
- Close CIL items that have been mitigated and verified
Deliverable: Updated SFMEA and CIL
�🚨 Critical Requirements for This Phase
Always Do
✅ Integrate continuously (multiple times/day minimum)
✅ Run full test suite on integration
✅ Fix broken builds immediately (<10 min)
✅ Test all component interfaces
✅ Use real dependencies where possible
✅ Automate integration testing
✅ Monitor integration health
✅ Document integration issues
✅ Integrate and build system many times a day
✅ All tests must run flawlessly before integration
✅ Ensure system always works using comprehensive tests
✅ Take small, deliberate steps, checking for feedback
✅ Collect reliability metrics (duty time, failures, restore times) per OP
✅ Automate operations to minimize anomalies
Never Do
❌ Commit on broken build
❌ Skip integration tests
❌ Integrate without testing
❌ Leave build broken overnight (fix within 10 minutes)
❌ Ignore integration failures
❌ Disable failing tests
❌ Leave code unintegrated for more than a couple of hours
❌ Let the press of time urge you to skip tests
📊 Phase Exit Criteria
✅ All components integrated successfully
✅ Integration tests passing
✅ CI/CD pipeline operational
✅ No blocking integration issues
✅ System deploys automatically
✅ Integration documentation complete
✅ OP exists and is referenced by the Reliability Test Plan
✅ Reliability data collection is enabled (duty time + failure logging)
✅ SRG model selection/fitting workflow documented
✅ Reliability exit criteria:
✅ Reliability Test Plan (RTP) complete with OP-driven test cases
✅ Test adapters implemented (self-contained, independent functions)
✅ Usage-weighted test allocation applied (80-20 rule)
✅ Coverage targets met (states 100%, transitions 100%, usage-weighted ≥ 80%)
✅ Failure data collection configured (timestamp, severity, operation, state)
✅ SRG data export working (CSV format ready for modeling)
✅ Reliability quality gate passed (integration pass rate ≥ 95%, MTBF trend increasing, critical failures = 0)
✅ SFMEA and CIL updated based on integration failures
✅ Reliability metrics dashboard operational
🎯 Next Phase
Phase 07: Verification & Validation (07-verification-validation/)
Remember: "If it hurts, do it more often" - The more frequently you integrate, the easier it becomes!