Angular MFE Local Testing Guide | Complete Testing Strategy
This guide provides comprehensive strategies for testing your Angular Micro Frontend application locally, including debugging techniques, performance monitoring, and integration testing approaches.
🧪 Testing Strategy Overview
Section titled “🧪 Testing Strategy Overview”Testing Levels
Section titled “Testing Levels”- Unit Testing: Individual MFE components and services
- Integration Testing: Host-Remote interactions
- End-to-End Testing: Complete user workflows
- Performance Testing: Bundle sizes and load times
- Error Handling Testing: Fallback mechanisms
Testing Environment Setup
Section titled “Testing Environment Setup”Testing Environment Structure:├── Unit Tests (Jest/Jasmine)├── Integration Tests (Custom scripts)├── E2E Tests (Cypress/Protractor)├── Performance Tests (Lighthouse/Bundle Analyzer)└── Manual Testing (Browser DevTools)
🚀 Step 1: Local Development Environment
Section titled “🚀 Step 1: Local Development Environment”1.1 Enhanced Development Scripts
Section titled “1.1 Enhanced Development Scripts”Create comprehensive development scripts in your root directory:
Unix/macOS (start-all-dev.sh):
#!/bin/bash
# Color codes for outputRED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'BLUE='\033[0;34m'NC='\033[0m' # No Color
echo -e "${BLUE}🚀 Starting Angular MFE Development Environment${NC}"echo "==============================================="
# Create logs directorymkdir -p logs
# Function to start an applicationstart_app() { local app_name=$1 local port=$2 local color=$3
echo -e "${color}📦 Starting $app_name on port $port...${NC}" cd $app_name
# Install dependencies if node_modules doesn't exist if [ ! -d "node_modules" ]; then echo -e "${YELLOW}📋 Installing dependencies for $app_name...${NC}" npm install fi
# Start the application npm start > ../logs/$app_name.log 2>&1 & local pid=$! echo $pid > ../logs/$app_name.pid cd ..
echo -e "${GREEN}✅ $app_name started with PID $pid${NC}" return $pid}
# Start all applicationsstart_app "mfe-loan-calculator" 4201 "$BLUE"start_app "mfe-user-dashboard" 4202 "$GREEN"start_app "mfe-transaction-history" 4203 "$YELLOW"start_app "host-banking-app" 4200 "$RED"
echo ""echo -e "${GREEN}🎉 All applications started successfully!${NC}"echo ""echo "📱 Application URLs:"echo " 🏠 Host App: http://localhost:4200"echo " 🧮 Loan Calculator: http://localhost:4201"echo " 📊 User Dashboard: http://localhost:4202"echo " 💳 Transactions: http://localhost:4203"echo ""echo "📊 Remote Entry Points:"echo " http://localhost:4201/remoteEntry.js"echo " http://localhost:4202/remoteEntry.js"echo " http://localhost:4203/remoteEntry.js"echo ""echo -e "${YELLOW}⏳ Waiting 15 seconds for applications to start...${NC}"sleep 15
# Health check functionhealth_check() { local url=$1 local name=$2
if curl -s -f "$url" > /dev/null; then echo -e "${GREEN}✅ $name is healthy${NC}" return 0 else echo -e "${RED}❌ $name is not responding${NC}" return 1 fi}
echo ""echo -e "${BLUE}🔍 Performing health checks...${NC}"health_check "http://localhost:4200" "Host Application"health_check "http://localhost:4201/remoteEntry.js" "Loan Calculator MFE"health_check "http://localhost:4202/remoteEntry.js" "User Dashboard MFE"health_check "http://localhost:4203/remoteEntry.js" "Transaction History MFE"
echo ""echo -e "${GREEN}🎯 Development environment ready!${NC}"echo "Press 'q' to stop all applications..."
# Wait for user input to stopwhile true; do read -n 1 key if [[ $key == 'q' || $key == 'Q' ]]; then break fidone
echo ""echo -e "${YELLOW}🛑 Stopping all applications...${NC}"
# Stop all applicationsfor pidfile in logs/*.pid; do if [ -f "$pidfile" ]; then pid=$(cat "$pidfile") if kill -0 $pid > /dev/null 2>&1; then kill $pid echo -e "${GREEN}✅ Stopped process $pid${NC}" fi rm "$pidfile" fidone
echo -e "${GREEN}🏁 All applications stopped successfully!${NC}"
Windows (start-all-dev.ps1):
# Set console colors for output$Colors = @{ Red = 'Red' Green = 'Green' Yellow = 'Yellow' Blue = 'Blue' White = 'White'}
Write-Host "🚀 Starting Angular MFE Development Environment" -ForegroundColor BlueWrite-Host "===============================================" -ForegroundColor Blue
# Create logs directoryNew-Item -Path "logs" -ItemType Directory -Force | Out-Null
# Function to start an applicationfunction Start-App { param( [string]$AppName, [int]$Port, [string]$Color )
Write-Host "📦 Starting $AppName on port $Port..." -ForegroundColor $Color Set-Location $AppName
# Install dependencies if node_modules doesn't exist if (!(Test-Path "node_modules")) { Write-Host "📋 Installing dependencies for $AppName..." -ForegroundColor Yellow npm install }
# Start the application $process = Start-Process npm -ArgumentList "start" -PassThru -WindowStyle Hidden -RedirectStandardOutput "..\logs\$AppName.log" -RedirectStandardError "..\logs\$AppName.log" $process.Id | Out-File -FilePath "..\logs\$AppName.pid" -Encoding UTF8 Set-Location ..
Write-Host "✅ $AppName started with PID $($process.Id)" -ForegroundColor Green return $process}
# Start all applications$loanCalcProcess = Start-App "mfe-loan-calculator" 4201 "Blue"$dashboardProcess = Start-App "mfe-user-dashboard" 4202 "Green"$transactionProcess = Start-App "mfe-transaction-history" 4203 "Yellow"$hostProcess = Start-App "host-banking-app" 4200 "Red"
Write-Host ""Write-Host "🎉 All applications started successfully!" -ForegroundColor GreenWrite-Host ""Write-Host "📱 Application URLs:" -ForegroundColor CyanWrite-Host " 🏠 Host App: http://localhost:4200"Write-Host " 🧮 Loan Calculator: http://localhost:4201"Write-Host " 📊 User Dashboard: http://localhost:4202"Write-Host " 💳 Transactions: http://localhost:4203"Write-Host ""Write-Host "📊 Remote Entry Points:" -ForegroundColor CyanWrite-Host " http://localhost:4201/remoteEntry.js"Write-Host " http://localhost:4202/remoteEntry.js"Write-Host " http://localhost:4203/remoteEntry.js"Write-Host ""Write-Host "⏳ Waiting 15 seconds for applications to start..." -ForegroundColor YellowStart-Sleep -Seconds 15
# Health check functionfunction Test-HealthCheck { param( [string]$Url, [string]$Name )
try { $response = Invoke-WebRequest -Uri $Url -UseBasicParsing -TimeoutSec 5 if ($response.StatusCode -eq 200) { Write-Host "✅ $Name is healthy" -ForegroundColor Green return $true } else { Write-Host "❌ $Name is not responding" -ForegroundColor Red return $false } } catch { Write-Host "❌ $Name is not responding" -ForegroundColor Red return $false }}
Write-Host ""Write-Host "🔍 Performing health checks..." -ForegroundColor BlueTest-HealthCheck "http://localhost:4200" "Host Application"Test-HealthCheck "http://localhost:4201/remoteEntry.js" "Loan Calculator MFE"Test-HealthCheck "http://localhost:4202/remoteEntry.js" "User Dashboard MFE"Test-HealthCheck "http://localhost:4203/remoteEntry.js" "Transaction History MFE"
Write-Host ""Write-Host "🎯 Development environment ready!" -ForegroundColor GreenWrite-Host "Press 'q' to stop all applications..." -ForegroundColor Yellow
# Wait for user input to stopdo { $key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")} while ($key.Character -ne 'q' -and $key.Character -ne 'Q')
Write-Host ""Write-Host "🛑 Stopping all applications..." -ForegroundColor Yellow
# Stop all applicationstry { Stop-Process -Id $loanCalcProcess.Id -Force -ErrorAction SilentlyContinue Write-Host "✅ Stopped loan calculator process" -ForegroundColor Green} catch { }
try { Stop-Process -Id $dashboardProcess.Id -Force -ErrorAction SilentlyContinue Write-Host "✅ Stopped dashboard process" -ForegroundColor Green} catch { }
try { Stop-Process -Id $transactionProcess.Id -Force -ErrorAction SilentlyContinue Write-Host "✅ Stopped transaction process" -ForegroundColor Green} catch { }
try { Stop-Process -Id $hostProcess.Id -Force -ErrorAction SilentlyContinue Write-Host "✅ Stopped host process" -ForegroundColor Green} catch { }
# Clean up pid filesGet-ChildItem -Path "logs\*.pid" | Remove-Item -Force -ErrorAction SilentlyContinue
Write-Host "🏁 All applications stopped successfully!" -ForegroundColor Green
package.json (root level):
{ "name": "angular-mfe-workspace", "version": "1.0.0", "scripts": { "start:all": "./start-all-dev.sh", "start:all:win": "powershell -ExecutionPolicy Bypass -File .\\start-all-dev.ps1", "test:all": "./test-all.sh", "test:all:win": "powershell -ExecutionPolicy Bypass -File .\\test-all.ps1", "build:all": "./build-all.sh", "build:all:win": "powershell -ExecutionPolicy Bypass -File .\\build-all.ps1", "health:check": "./health-check.sh", "health:check:win": "powershell -ExecutionPolicy Bypass -File .\\health-check.ps1", "logs:view": "tail -f logs/*.log", "logs:view:win": "Get-Content logs\\*.log -Wait", "logs:clear": "rm -rf logs/*.log", "logs:clear:win": "Remove-Item logs\\*.log -Force" }}
1.2 Health Check Script
Section titled “1.2 Health Check Script”Unix/macOS (health-check.sh):
#!/bin/bash
echo "🔍 MFE Health Check Report"echo "=========================="
check_service() { local name=$1 local url=$2 local expected_content=$3
echo -n "Checking $name... "
if curl -s -f "$url" > /dev/null; then if [ ! -z "$expected_content" ]; then if curl -s "$url" | grep -q "$expected_content"; then echo "✅ Healthy (Content verified)" else echo "⚠️ Responding but content mismatch" fi else echo "✅ Healthy" fi else echo "❌ Not responding" fi}
# Check all servicescheck_service "Host Application" "http://localhost:4200" "banking"check_service "Loan Calculator" "http://localhost:4201/remoteEntry.js"check_service "User Dashboard" "http://localhost:4202/remoteEntry.js"check_service "Transaction History" "http://localhost:4203/remoteEntry.js"
echo ""echo "🌐 Testing MFE Integration..."
# Test module federation endpointscurl -s "http://localhost:4201/remoteEntry.js" | head -5echo ""echo "📊 Health check complete!"
Windows (health-check.ps1):
Write-Host "🔍 MFE Health Check Report" -ForegroundColor BlueWrite-Host "==========================" -ForegroundColor Blue
function Test-Service { param( [string]$Name, [string]$Url, [string]$ExpectedContent = $null )
Write-Host "Checking $Name... " -NoNewline
try { $response = Invoke-WebRequest -Uri $Url -UseBasicParsing -TimeoutSec 10 if ($response.StatusCode -eq 200) { if ($ExpectedContent) { if ($response.Content -match $ExpectedContent) { Write-Host "✅ Healthy (Content verified)" -ForegroundColor Green } else { Write-Host "⚠️ Responding but content mismatch" -ForegroundColor Yellow } } else { Write-Host "✅ Healthy" -ForegroundColor Green } } else { Write-Host "❌ Not responding" -ForegroundColor Red } } catch { Write-Host "❌ Not responding" -ForegroundColor Red }}
# Check all servicesTest-Service "Host Application" "http://localhost:4200" "banking"Test-Service "Loan Calculator" "http://localhost:4201/remoteEntry.js"Test-Service "User Dashboard" "http://localhost:4202/remoteEntry.js"Test-Service "Transaction History" "http://localhost:4203/remoteEntry.js"
Write-Host ""Write-Host "🌐 Testing MFE Integration..." -ForegroundColor Cyan
# Test module federation endpointstry { $response = Invoke-WebRequest -Uri "http://localhost:4201/remoteEntry.js" -UseBasicParsing $content = $response.Content $lines = $content -split "`n" | Select-Object -First 5 $lines | ForEach-Object { Write-Host $_ }} catch { Write-Host "Failed to fetch remote entry: $($_.Exception.Message)" -ForegroundColor Red}
Write-Host ""Write-Host "📊 Health check complete!" -ForegroundColor Green
🔍 Step 2: Development Tools & Debugging
Section titled “🔍 Step 2: Development Tools & Debugging”2.1 Browser DevTools Configuration
Section titled “2.1 Browser DevTools Configuration”Create a browser extension or bookmarklet for MFE debugging:
mfe-debug.js:
// MFE Debug Helper - Run in browser console(function() { const MfeDebugger = { // Check if Module Federation is working checkModuleFederation() { console.group('🔍 Module Federation Status');
// Check if webpack is available if (typeof __webpack_require__ !== 'undefined') { console.log('✅ Webpack is available');
// Check loaded modules const loadedModules = Object.keys(__webpack_require__.cache || {}); console.log(`📦 Loaded modules: ${loadedModules.length}`);
// Check for remote entries const remoteEntries = loadedModules.filter(m => m.includes('remoteEntry')); console.log('🌐 Remote entries:', remoteEntries); } else { console.log('❌ Webpack not available'); }
console.groupEnd(); },
// Check MFE health async checkMfeHealth() { console.group('🏥 MFE Health Check');
const mfes = [ { name: 'Loan Calculator', url: 'http://localhost:4201/remoteEntry.js' }, { name: 'User Dashboard', url: 'http://localhost:4202/remoteEntry.js' }, { name: 'Transaction History', url: 'http://localhost:4203/remoteEntry.js' } ];
for (const mfe of mfes) { try { const response = await fetch(mfe.url, { method: 'HEAD' }); console.log(`${response.ok ? '✅' : '❌'} ${mfe.name}: ${response.status}`); } catch (error) { console.log(`❌ ${mfe.name}: Not reachable`); } }
console.groupEnd(); },
// Performance monitoring checkPerformance() { console.group('⚡ Performance Metrics');
if (window.performance) { const navigation = window.performance.getEntriesByType('navigation')[0]; console.log(`🚀 DOM Content Loaded: ${navigation.domContentLoadedEventEnd - navigation.domContentLoadedEventStart}ms`); console.log(`📄 Page Load: ${navigation.loadEventEnd - navigation.loadEventStart}ms`);
// Check resource loading times const resources = window.performance.getEntriesByType('resource'); const remoteEntries = resources.filter(r => r.name.includes('remoteEntry.js'));
remoteEntries.forEach(entry => { console.log(`📦 ${entry.name}: ${entry.responseEnd - entry.requestStart}ms`); }); }
console.groupEnd(); },
// Bundle analysis analyzeBundles() { console.group('📊 Bundle Analysis');
if (typeof __webpack_require__ !== 'undefined') { const cache = __webpack_require__.cache || {}; const modules = Object.keys(cache);
// Group by source const bundleStats = modules.reduce((stats, moduleId) => { const module = cache[moduleId]; if (module && module.id) { const source = moduleId.includes('remoteEntry') ? 'Remote' : 'Local'; stats[source] = (stats[source] || 0) + 1; } return stats; }, {});
console.table(bundleStats); }
console.groupEnd(); },
// Run all checks runAllChecks() { console.clear(); console.log('🔧 MFE Debug Report - ' + new Date().toLocaleTimeString()); console.log('='.repeat(50));
this.checkModuleFederation(); this.checkMfeHealth(); this.checkPerformance(); this.analyzeBundles();
console.log('✅ Debug report complete!'); } };
// Make available globally window.MfeDebugger = MfeDebugger;
console.log('🛠️ MFE Debugger loaded! Use MfeDebugger.runAllChecks() to start.');})();
2.2 VS Code Debugging Configuration
Section titled “2.2 VS Code Debugging Configuration”.vscode/launch.json:
{ "version": "0.2.0", "configurations": [ { "name": "Debug Host App", "type": "chrome", "request": "launch", "url": "http://localhost:4200", "webRoot": "${workspaceFolder}/host-banking-app/src", "sourceMapPathOverrides": { "webpack:/*": "${webRoot}/*" } }, { "name": "Debug Loan Calculator MFE", "type": "chrome", "request": "launch", "url": "http://localhost:4201", "webRoot": "${workspaceFolder}/mfe-loan-calculator/src", "sourceMapPathOverrides": { "webpack:/*": "${webRoot}/*" } }, { "name": "Debug All MFEs", "type": "chrome", "request": "launch", "url": "http://localhost:4200", "webRoot": "${workspaceFolder}", "sourceMapPathOverrides": { "webpack:/*": "${webRoot}/*/src/*" } } ]}
🧪 Step 3: Integration Testing
Section titled “🧪 Step 3: Integration Testing”3.1 MFE Integration Test Suite
Section titled “3.1 MFE Integration Test Suite”test-integration.js:
const puppeteer = require('puppeteer');const { expect } = require('chai');
describe('MFE Integration Tests', () => { let browser; let page;
before(async () => { browser = await puppeteer.launch({ headless: false, // Set to true for CI devtools: true }); page = await browser.newPage();
// Enable console logging page.on('console', msg => console.log('PAGE LOG:', msg.text())); page.on('pageerror', error => console.log('PAGE ERROR:', error.message)); });
after(async () => { await browser.close(); });
it('Should load host application', async () => { await page.goto('http://localhost:4200'); await page.waitForSelector('.app-header');
const title = await page.title(); expect(title).to.include('Banking'); });
it('Should load Loan Calculator MFE', async () => { await page.goto('http://localhost:4200/loan-calculator'); await page.waitForSelector('.loan-calculator', { timeout: 10000 });
const calculator = await page.$('.loan-calculator'); expect(calculator).to.not.be.null; });
it('Should interact with Loan Calculator', async () => { await page.goto('http://localhost:4200/loan-calculator'); await page.waitForSelector('.loan-calculator');
// Test slider interaction const slider = await page.$('#loanAmount'); await slider.click();
// Test dropdown selection await page.select('#interestRate', '5.1');
// Verify calculation updates await page.waitForFunction(() => { const result = document.querySelector('.monthly-payment'); return result && result.textContent.includes('$'); }); });
it('Should navigate between MFEs', async () => { await page.goto('http://localhost:4200');
// Click navigation links await page.click('a[routerLink="/dashboard"]'); await page.waitForSelector('.user-dashboard', { timeout: 5000 });
await page.click('a[routerLink="/loan-calculator"]'); await page.waitForSelector('.loan-calculator', { timeout: 5000 });
await page.click('a[routerLink="/transactions"]'); await page.waitForSelector('.transaction-history', { timeout: 5000 }); });
it('Should handle MFE loading errors gracefully', async () => { // Simulate network error await page.setOfflineMode(true); await page.goto('http://localhost:4200/loan-calculator');
// Check for error handling await page.waitForSelector('.error-message', { timeout: 5000 });
await page.setOfflineMode(false); });});
3.2 Performance Testing
Section titled “3.2 Performance Testing”performance-test.js:
const puppeteer = require('puppeteer');const lighthouse = require('lighthouse');
async function runPerformanceTest() { const browser = await puppeteer.launch({ headless: true, args: ['--remote-debugging-port=9222'] });
const page = await browser.newPage();
// Enable performance monitoring await page.coverage.startJSCoverage(); await page.coverage.startCSSCoverage();
console.log('🚀 Starting performance test...');
// Test host application await page.goto('http://localhost:4200'); await page.waitForLoadState('networkidle');
// Measure bundle sizes const jsCoverage = await page.coverage.stopJSCoverage(); const cssCoverage = await page.coverage.stopCSSCoverage();
let totalJSBytes = 0; let usedJSBytes = 0;
jsCoverage.forEach(entry => { totalJSBytes += entry.text.length; entry.ranges.forEach(range => { usedJSBytes += range.end - range.start - 1; }); });
console.log(`📦 Total JS: ${(totalJSBytes / 1024).toFixed(2)} KB`); console.log(`✅ Used JS: ${(usedJSBytes / 1024).toFixed(2)} KB`); console.log(`📊 JS Usage: ${((usedJSBytes / totalJSBytes) * 100).toFixed(2)}%`);
// Test MFE loading times const mfeTests = [ { name: 'Loan Calculator', url: '/loan-calculator' }, { name: 'User Dashboard', url: '/dashboard' }, { name: 'Transactions', url: '/transactions' } ];
for (const test of mfeTests) { const startTime = Date.now(); await page.goto(`http://localhost:4200${test.url}`); await page.waitForLoadState('networkidle'); const loadTime = Date.now() - startTime;
console.log(`⏱️ ${test.name}: ${loadTime}ms`); }
await browser.close();}
// Run Lighthouse auditasync function runLighthouseAudit() { const browser = await puppeteer.launch({ headless: true, args: ['--remote-debugging-port=9222'] });
const result = await lighthouse('http://localhost:4200', { port: 9222, output: 'json', logLevel: 'info' });
console.log('📊 Lighthouse Results:'); console.log(`Performance: ${result.lhr.categories.performance.score * 100}`); console.log(`Accessibility: ${result.lhr.categories.accessibility.score * 100}`); console.log(`Best Practices: ${result.lhr.categories['best-practices'].score * 100}`); console.log(`SEO: ${result.lhr.categories.seo.score * 100}`);
await browser.close();}
runPerformanceTest();runLighthouseAudit();
🛠️ Step 4: Testing Automation
Section titled “🛠️ Step 4: Testing Automation”4.1 Automated Test Suite
Section titled “4.1 Automated Test Suite”test-all.sh:
#!/bin/bash
echo "🧪 Running Complete MFE Test Suite"echo "================================="
# ColorsGREEN='\033[0;32m'RED='\033[0;31m'YELLOW='\033[1;33m'NC='\033[0m'
# Test resultsTESTS_PASSED=0TESTS_FAILED=0
run_test() { local test_name=$1 local test_command=$2
echo -e "${YELLOW}🔄 Running $test_name...${NC}"
if eval $test_command; then echo -e "${GREEN}✅ $test_name passed${NC}" ((TESTS_PASSED++)) else echo -e "${RED}❌ $test_name failed${NC}" ((TESTS_FAILED++)) fi echo ""}
# Start applications if not runningecho "🚀 Ensuring applications are running..."./start-all-dev.sh &START_PID=$!sleep 20
# Run health checksrun_test "Health Check" "./health-check.sh"
# Run unit tests for each MFErun_test "Host App Unit Tests" "cd host-banking-app && npm test -- --watch=false"run_test "Loan Calculator Unit Tests" "cd mfe-loan-calculator && npm test -- --watch=false"run_test "User Dashboard Unit Tests" "cd mfe-user-dashboard && npm test -- --watch=false"
# Run integration testsrun_test "Integration Tests" "npm run test:integration"
# Run performance testsrun_test "Performance Tests" "node performance-test.js"
# Run E2E testsrun_test "E2E Tests" "npx cypress run --headless"
# Generate test reportecho "📊 Test Results Summary"echo "======================"echo -e "✅ Tests Passed: ${GREEN}$TESTS_PASSED${NC}"echo -e "❌ Tests Failed: ${RED}$TESTS_FAILED${NC}"
if [ $TESTS_FAILED -eq 0 ]; then echo -e "${GREEN}🎉 All tests passed!${NC}" exit 0else echo -e "${RED}💥 Some tests failed!${NC}" exit 1fi
4.2 Continuous Integration Setup
Section titled “4.2 Continuous Integration Setup”.github/workflows/mfe-ci.yml:
name: MFE CI/CD Pipeline
on: push: branches: [ main, develop ] pull_request: branches: [ main ]
jobs: test: runs-on: ubuntu-latest
strategy: matrix: node-version: [18.x, 20.x]
steps: - uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} cache: 'npm'
- name: Install dependencies for all projects run: | cd host-banking-app && npm ci cd ../mfe-loan-calculator && npm ci cd ../mfe-user-dashboard && npm ci cd ../mfe-transaction-history && npm ci
- name: Run linting run: | cd host-banking-app && npm run lint cd ../mfe-loan-calculator && npm run lint cd ../mfe-user-dashboard && npm run lint cd ../mfe-transaction-history && npm run lint
- name: Run unit tests run: | cd host-banking-app && npm test -- --watch=false --browsers=ChromeHeadless cd ../mfe-loan-calculator && npm test -- --watch=false --browsers=ChromeHeadless cd ../mfe-user-dashboard && npm test -- --watch=false --browsers=ChromeHeadless cd ../mfe-transaction-history && npm test -- --watch=false --browsers=ChromeHeadless
- name: Build all applications run: | cd host-banking-app && npm run build cd ../mfe-loan-calculator && npm run build cd ../mfe-user-dashboard && npm run build cd ../mfe-transaction-history && npm run build
- name: Start applications for integration tests run: | ./start-all-dev.sh & sleep 30
- name: Run integration tests run: npm run test:integration
- name: Upload test results uses: actions/upload-artifact@v3 with: name: test-results path: test-results/
🔍 Step 5: Manual Testing Checklist
Section titled “🔍 Step 5: Manual Testing Checklist”5.1 Browser Compatibility Testing
Section titled “5.1 Browser Compatibility Testing”Test matrix for different browsers:
Feature | Chrome | Firefox | Safari | Edge |
---|---|---|---|---|
Host App Loading | ✅ | ✅ | ✅ | ✅ |
MFE Navigation | ✅ | ✅ | ⚠️ | ✅ |
Remote Loading | ✅ | ✅ | ❌ | ✅ |
Responsive Design | ✅ | ✅ | ✅ | ✅ |
5.2 Mobile Testing Checklist
Section titled “5.2 Mobile Testing Checklist”- Navigation: Mobile menu works correctly
- Touch interactions: All buttons and links are touchable
- Responsive design: Layouts adapt to different screen sizes
- Performance: App loads quickly on mobile networks
- MFE loading: Remote modules load correctly on mobile
5.3 Error Scenario Testing
Section titled “5.3 Error Scenario Testing”Test these error scenarios:
-
MFE Unavailable:
- Stop one MFE service
- Navigate to that route
- Verify fallback content displays
-
Network Issues:
- Throttle network to 3G
- Test MFE loading performance
- Verify loading indicators work
-
JavaScript Errors:
- Introduce intentional errors
- Verify error boundaries work
- Check console for proper error reporting
📊 Step 6: Testing Metrics & Reporting
Section titled “📊 Step 6: Testing Metrics & Reporting”6.1 Test Coverage Report
Section titled “6.1 Test Coverage Report”Generate comprehensive test coverage:
coverage-report.js:
const fs = require('fs');const path = require('path');
function generateCoverageReport() { const projects = [ 'host-banking-app', 'mfe-loan-calculator', 'mfe-user-dashboard', 'mfe-transaction-history' ];
let totalLines = 0; let coveredLines = 0; const projectReports = [];
projects.forEach(project => { const coveragePath = path.join(project, 'coverage/lcov-report/index.html');
if (fs.existsSync(coveragePath)) { // Parse coverage data (simplified) const coverage = { project: project, lines: Math.floor(Math.random() * 100), // Mock data functions: Math.floor(Math.random() * 100), branches: Math.floor(Math.random() * 100), statements: Math.floor(Math.random() * 100) };
projectReports.push(coverage); totalLines += 100; coveredLines += coverage.lines; } });
console.log('📊 Test Coverage Report'); console.log('='.repeat(50)); console.table(projectReports); console.log(`Overall Coverage: ${(coveredLines / totalLines * 100).toFixed(2)}%`);}
generateCoverageReport();
6.2 Performance Metrics Dashboard
Section titled “6.2 Performance Metrics Dashboard”Create a simple HTML dashboard for monitoring:
performance-dashboard.html:
<!DOCTYPE html><html><head> <title>MFE Performance Dashboard</title> <style> body { font-family: Arial, sans-serif; margin: 20px; } .metric { background: #f5f5f5; padding: 15px; margin: 10px 0; border-radius: 5px; } .good { border-left: 5px solid #27ae60; } .warning { border-left: 5px solid #f39c12; } .error { border-left: 5px solid #e74c3c; } </style></head><body> <h1>🚀 MFE Performance Dashboard</h1>
<div id="metrics"></div>
<script> async function loadMetrics() { const metrics = [ { name: 'Host App Load Time', value: '1.2s', status: 'good' }, { name: 'Loan Calculator Load', value: '0.8s', status: 'good' }, { name: 'Bundle Size (Host)', value: '245KB', status: 'warning' }, { name: 'Bundle Size (Total)', value: '680KB', status: 'warning' }, { name: 'Time to Interactive', value: '2.1s', status: 'good' } ];
const container = document.getElementById('metrics'); metrics.forEach(metric => { const div = document.createElement('div'); div.className = `metric ${metric.status}`; div.innerHTML = `<strong>${metric.name}:</strong> ${metric.value}`; container.appendChild(div); }); }
loadMetrics();
// Auto-refresh every 30 seconds setInterval(loadMetrics, 30000); </script></body></html>
✅ Local Testing Verification Checklist
Section titled “✅ Local Testing Verification Checklist”Complete Testing Checklist
Section titled “Complete Testing Checklist”- Development environment starts all MFEs successfully
- Health checks pass for all applications
- Navigation works between all MFEs
- Unit tests pass for all projects
- Integration tests verify MFE interactions
- Performance tests meet acceptance criteria
- Error handling works correctly
- Browser compatibility verified across browsers
- Mobile responsiveness tested on multiple devices
- Accessibility requirements met
- Security headers and HTTPS working
- CI/CD pipeline runs successfully
Performance Targets
Section titled “Performance Targets”- ⚡ First Load: < 2 seconds
- 📦 Bundle Size: < 500KB total
- 🔄 MFE Load Time: < 1 second
- 📱 Mobile Performance: Score > 80
- ♿ Accessibility: Score > 90
🚀 What’s Next?
Section titled “🚀 What’s Next?”Your local testing environment is complete! Next steps:
- ✅ Local Testing Complete
- ➡️ Continue to: Azure Deployment - Deploy to production
- 📚 Alternative: Remote Configuration - Advanced remote setup
Your Angular MFE application is now thoroughly tested and ready for deployment! 🎉