feat: Add SampleDataGenerator utility #347
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Automated Testing | |
| on: | |
| pull_request: | |
| branches: [ main, develop ] | |
| types: [ opened, synchronize, reopened, ready_for_review ] | |
| push: | |
| branches: [ main, develop ] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| env: | |
| XCODE_VERSION: '15.0' | |
| SWIFT_VERSION: '5.9' | |
| jobs: | |
| test: | |
| name: Run Tests | |
| runs-on: macos-14 | |
| if: github.event_name != 'pull_request' || github.event.pull_request.draft == false | |
| strategy: | |
| matrix: | |
| destination: | |
| - platform=iOS Simulator,name=iPhone 15 Pro,OS=17.0 | |
| - platform=iOS Simulator,name=iPad Pro (12.9-inch) (6th generation),OS=17.0 | |
| include: | |
| - destination: platform=iOS Simulator,name=iPhone 15 Pro,OS=17.0 | |
| device: iPhone | |
| - destination: platform=iOS Simulator,name=iPad Pro (12.9-inch) (6th generation),OS=17.0 | |
| device: iPad | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup Xcode | |
| uses: maxim-lobanov/setup-xcode@v1 | |
| with: | |
| xcode-version: ${{ env.XCODE_VERSION }} | |
| - name: Cache Swift Package Manager | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/Library/Developer/Xcode/DerivedData/**/SourcePackages | |
| ~/Library/Caches/org.swift.swiftpm | |
| .build | |
| key: ${{ runner.os }}-spm-tests-${{ hashFiles('**/Package.resolved', 'project.yml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-spm-tests- | |
| ${{ runner.os }}-spm- | |
| - name: Install dependencies | |
| run: | | |
| if ! command -v xcodegen &> /dev/null; then | |
| echo "Installing XcodeGen..." | |
| brew install xcodegen | |
| fi | |
| if ! command -v xcpretty &> /dev/null; then | |
| echo "Installing xcpretty..." | |
| gem install xcpretty | |
| fi | |
| - name: Generate Xcode project | |
| run: xcodegen generate | |
| - name: Resolve Swift Package Dependencies | |
| run: | | |
| xcodebuild -resolvePackageDependencies \ | |
| -project HomeInventoryModular.xcodeproj \ | |
| -scheme HomeInventoryApp | |
| - name: List available test schemes | |
| run: | | |
| echo "Available schemes:" | |
| xcodebuild -list -project HomeInventoryModular.xcodeproj | grep -A 20 "Schemes:" || true | |
| - name: Check test targets | |
| id: check_tests | |
| run: | | |
| # Check if UI test target exists and is buildable | |
| if xcodebuild -showBuildSettings -project HomeInventoryModular.xcodeproj -scheme HomeInventoryModularUITests 2>/dev/null | grep -q "PRODUCT_NAME"; then | |
| echo "ui_tests_available=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "ui_tests_available=false" >> $GITHUB_OUTPUT | |
| echo "::warning::UI test target not available or not buildable" | |
| fi | |
| # Check if unit test targets exist - Currently no unit test scheme available | |
| echo "unit_tests_available=false" >> $GITHUB_OUTPUT | |
| echo "::warning::No unit test schemes currently configured" | |
| - name: Run Unit Tests | |
| if: steps.check_tests.outputs.unit_tests_available == 'true' | |
| run: | | |
| # Unit tests currently disabled as no unit test schemes are configured | |
| echo "::notice::Unit tests skipped - no unit test schemes available" | |
| continue-on-error: true | |
| - name: Run UI Tests | |
| if: steps.check_tests.outputs.ui_tests_available == 'true' | |
| run: | | |
| set -o pipefail | |
| xcodebuild test \ | |
| -project HomeInventoryModular.xcodeproj \ | |
| -scheme HomeInventoryModularUITests \ | |
| -destination '${{ matrix.destination }}' \ | |
| -enableCodeCoverage YES \ | |
| -resultBundlePath TestResults-UI-${{ matrix.device }}.xcresult \ | |
| | xcpretty --test --color | |
| continue-on-error: true | |
| - name: Run Accessibility Tests | |
| run: | | |
| # Run accessibility tests if available | |
| if [ -f "HomeInventoryModularUITests/AccessibilityUITests.swift" ]; then | |
| echo "Running accessibility tests..." | |
| set -o pipefail | |
| xcodebuild test \ | |
| -project HomeInventoryModular.xcodeproj \ | |
| -scheme HomeInventoryModularUITests \ | |
| -destination '${{ matrix.destination }}' \ | |
| -testPlan AccessibilityTests \ | |
| -resultBundlePath TestResults-A11y-${{ matrix.device }}.xcresult \ | |
| | xcpretty --test --color || echo "::warning::Accessibility tests failed or not configured" | |
| else | |
| echo "::notice::No accessibility tests found" | |
| fi | |
| continue-on-error: true | |
| - name: Test Module Compilation | |
| run: | | |
| # Test individual module compilation to catch module-specific issues | |
| modules=("Foundation-Core" "Foundation-Models" "Infrastructure-Network" "Infrastructure-Storage" "UI-Components") | |
| for module in "${modules[@]}"; do | |
| if [ -d "$module" ]; then | |
| echo "Testing compilation of $module..." | |
| if [ -f "$module/Package.swift" ]; then | |
| cd "$module" | |
| swift build || echo "::warning::Module $module failed to compile as SPM package" | |
| cd .. | |
| fi | |
| fi | |
| done | |
| - name: Upload Test Results | |
| uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: test-results-${{ matrix.device }} | |
| path: | | |
| TestResults-*.xcresult | |
| retention-days: 5 | |
| - name: Generate Coverage Report | |
| if: matrix.device == 'iPhone' | |
| run: | | |
| # Generate coverage report from xcresult files | |
| if ls TestResults-*.xcresult 1> /dev/null 2>&1; then | |
| echo "Generating coverage report..." | |
| # Use xcov if available, otherwise use built-in xcodebuild coverage | |
| if command -v xcov &> /dev/null; then | |
| xcov -x TestResults-Unit-iPhone.xcresult -o coverage/ --minimum_coverage_percentage 60 | |
| else | |
| echo "xcov not available, extracting basic coverage data..." | |
| for result in TestResults-*.xcresult; do | |
| echo "Coverage data from $result:" | |
| xcrun xccov view --report "$result" || true | |
| done | |
| fi | |
| else | |
| echo "::warning::No test results found for coverage analysis" | |
| fi | |
| continue-on-error: true | |
| - name: Upload Coverage Report | |
| if: matrix.device == 'iPhone' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-report | |
| path: | | |
| coverage/ | |
| *.coverage | |
| retention-days: 10 | |
| - name: Comment Test Results | |
| if: github.event_name == 'pull_request' && matrix.device == 'iPhone' | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const { owner, repo } = context.repo; | |
| const { number } = context.issue; | |
| // Simple test status - in a real implementation, you'd parse the xcresult files | |
| const testStatus = '${{ job.status }}' === 'success' ? '✅ Passed' : '❌ Failed'; | |
| await github.rest.issues.createComment({ | |
| owner, | |
| repo, | |
| issue_number: number, | |
| body: `## 🧪 Test Results | |
| **iPhone Tests:** ${testStatus} | |
| **iPad Tests:** ${{ job.status == 'success' && '✅ Passed' || '❌ Failed' }} | |
| **Coverage:** See artifacts for detailed report | |
| **Test Summary:** | |
| - Unit Tests: ${{ steps.check_tests.outputs.unit_tests_available == 'true' && 'Executed' || 'Skipped (not available)' }} | |
| - UI Tests: ${{ steps.check_tests.outputs.ui_tests_available == 'true' && 'Executed' || 'Skipped (not available)' }} | |
| - Accessibility Tests: ${{ contains(steps.*.outcome, 'success') && 'Executed' || 'Skipped' }} | |
| ${testStatus.includes('Failed') ? '⚠️ Some tests failed - please check the detailed results in the Actions tab.' : ''} | |
| --- | |
| *View detailed results and coverage reports in the [Actions tab](https://github.com/${owner}/${repo}/actions/runs/${{ github.run_id }}).*` | |
| }); | |
| continue-on-error: true | |
| test-summary: | |
| name: Test Summary | |
| runs-on: ubuntu-latest | |
| needs: test | |
| if: always() | |
| steps: | |
| - name: Generate summary | |
| run: | | |
| echo "## Test Execution Summary" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "| Device | Status |" >> $GITHUB_STEP_SUMMARY | |
| echo "|--------|---------|" >> $GITHUB_STEP_SUMMARY | |
| echo "| iPhone | ${{ contains(needs.test.result, 'success') && '✅ Passed' || '❌ Failed' }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "| iPad | ${{ contains(needs.test.result, 'success') && '✅ Passed' || '❌ Failed' }} |" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Overall Result:** ${{ needs.test.result == 'success' && '✅ All tests passed' || '❌ Some tests failed' }}" >> $GITHUB_STEP_SUMMARY | |
| # Status checks are automatically created by GitHub Actions | |
| # Manual status check creation removed due to permission requirements |