Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
5f18288
Add support for .NET 10.0 and update documentation for mocking interf…
Nov 12, 2025
289f493
Update API documentation and enhance README for SMock library
Nov 12, 2025
bc6d048
Add advanced usage patterns, migration guide, and troubleshooting doc…
Nov 12, 2025
ea6bd2d
Add comprehensive test examples for Sequential and Hierarchical APIs,…
Nov 16, 2025
5200f05
Refactor Hierarchical Parameter Validation test to improve path valid…
Nov 16, 2025
29021a8
Refactor async method mocks to use context-based setup and improve te…
Nov 16, 2025
9a88239
Refactor Web API order processing flow test to use random number gene…
Nov 16, 2025
b67fc25
Update test result logging paths in build and test job for OS-specifi…
Nov 16, 2025
975e1ab
Enhance CI pipeline with retry logic for tests and coverage report up…
Nov 19, 2025
1ec4838
Update Codecov action configuration to include token and specify work…
Nov 19, 2025
d45f772
Enhance test reporting by parsing results and creating a detailed PR …
Nov 19, 2025
c5f1e37
Enhance PR comment with detailed test results and build information
Nov 19, 2025
9d0f241
Add test rate calculation to environment variables and update success…
Nov 20, 2025
d0a0dc6
Enhance TRX file parsing for test results and add last updated timest…
Nov 20, 2025
199fdbd
Update pass rate calculation in environment variables and enhance tes…
Nov 20, 2025
78de14d
Refactor pass test rate calculation in environment variables for impr…
Nov 20, 2025
8be915e
Remove code coverage collection from test commands and update pass ra…
Nov 20, 2025
fbe3ff8
Refactor test command execution and enhance TRX file output logging i…
Nov 20, 2025
7d5e57b
Refactor pass test rate calculation for improved readability and main…
Nov 20, 2025
668825b
Enhance TRX counters parsing with null safety and detailed debug output
Nov 20, 2025
a62da52
Enhance test command logging and add TRX results parsing script for i…
Nov 20, 2025
20b2108
Rename debug parameter to EnableDebug for clarity and consistency in …
Nov 20, 2025
983f63c
Refactor test verbosity settings to minimal for cleaner output and re…
Nov 20, 2025
337a5d2
Add cleanup step for TRX files and enhance framework version detectio…
Nov 20, 2025
5b8c39b
Refactor build and test job to remove TRX cleanup step and streamline…
Nov 20, 2025
7ec60e9
Disable exit on error during test execution to ensure all frameworks …
Nov 20, 2025
92b33c4
Enhance build and test workflows to support multiple configurations (…
Nov 20, 2025
3508704
Fix input variable references in build and test job configuration
Nov 20, 2025
7976f48
Add configuration input to build and test job for customizable build …
Nov 20, 2025
7e3689a
Fix indentation in build_and_test_job.yaml for configuration input
Nov 20, 2025
71168fd
Remove unnecessary setup and teardown methods in NUnit tests for clea…
Nov 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 162 additions & 0 deletions .github/scripts/Parse-TestResults.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#!/usr/bin/env pwsh
<#
.SYNOPSIS
Parses TRX test result files and outputs test statistics
.DESCRIPTION
Parses .trx files generated by dotnet test and extracts test statistics.
Outputs results to GitHub environment variables for CI/CD workflows.
.PARAMETER SourcePath
Path to search for .trx files (defaults to "./src")
.PARAMETER EnableDebug
Enable debug output for troubleshooting (defaults to $false)
#>

param(
[Parameter(Mandatory = $false)]
[string]$SourcePath = "./src",

[Parameter(Mandatory = $false)]
[switch]$EnableDebug
)

function Get-AttributeValue {
param($Node, $AttributeName)
if ($Node.$AttributeName) { [int]$Node.$AttributeName } else { 0 }
}

# Initialize counters
$totalTests = 0
$passedTests = 0
$failedTests = 0
$skippedTests = 0
$executionTime = [TimeSpan]::Zero
$frameworkVersions = @()

# Find TRX files
$trxFiles = Get-ChildItem -Path $SourcePath -Filter "*.trx" -Recurse
Write-Output "Found $($trxFiles.Count) TRX files"

if ($trxFiles.Count -eq 0) {
Write-Warning "No TRX files found in path: $SourcePath"
exit 1
}


foreach ($file in $trxFiles) {
try {
[xml]$trx = Get-Content $file.FullName
$namespace = @{ns = 'http://microsoft.com/schemas/VisualStudio/TeamTest/2010'}

# Parse test summary
$summary = Select-Xml -Xml $trx -XPath "//ns:ResultSummary/ns:Counters" -Namespace $namespace
if ($summary) {
$counters = $summary.Node

if ($EnableDebug) {
Write-Output "Processing $($file.Name):"
$counters.Attributes | ForEach-Object { Write-Output " $($_.Name) = $($_.Value)" }
}

# Get counts with safe parsing
$total = Get-AttributeValue $counters 'total'
$passed = Get-AttributeValue $counters 'passed'
$failed = Get-AttributeValue $counters 'failed'

$totalTests += $total
$passedTests += $passed
$failedTests += $failed

if ($EnableDebug) {
Write-Output " Results: Total=$total, Passed=$passed, Failed=$failed"
}
}

# Parse execution time
$times = Select-Xml -Xml $trx -XPath "//ns:Times" -Namespace $namespace
if ($times) {
$start = [DateTime]$times.Node.start
$finish = [DateTime]$times.Node.finish
$executionTime = $executionTime.Add($finish - $start)
}

# Extract framework version from test settings or deployment
$testSettings = Select-Xml -Xml $trx -XPath "//ns:TestSettings" -Namespace $namespace
if ($testSettings -and $testSettings.Node.deploymentRoot) {
$deploymentPath = $testSettings.Node.deploymentRoot
if ($deploymentPath -match '(net\d+\.\d+|netstandard\d+\.\d+|netframework\d+\.\d+|net\d+)') {
$framework = $matches[1]
if ($frameworkVersions -notcontains $framework) {
$frameworkVersions += $framework
if ($EnableDebug) {
Write-Output " Found framework: $framework"
}
}
}
}

# Alternative: Extract from file path (for cases where deployment info isn't available)
if ($file.FullName -match '(net\d+\.\d+|netstandard\d+\.\d+|netframework\d+\.\d+|net\d+)') {
$framework = $matches[1]
if ($frameworkVersions -notcontains $framework) {
$frameworkVersions += $framework
if ($EnableDebug) {
Write-Output " Found framework from path: $framework"
}
}
}
} catch {
Write-Warning "Failed to parse TRX file: $($file.FullName). Error: $_"
}
}

# Calculate pass rate
if ($totalTests -gt 0) {
$passTestRate = "**$([math]::Round(($passedTests / $totalTests) * 100, 1))%** ($passedTests/$totalTests tests passed)"
} else {
$passTestRate = "No tests found"
}

# Generate timestamp
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss UTC"

# Calculate skipped tests using simple math
$skippedTests = $totalTests - $passedTests - $failedTests

if ($EnableDebug) { Write-Output "Calculated skipped tests: $totalTests - $passedTests - $failedTests = $skippedTests" }

# Format framework versions
$testedFrameworks = if ($frameworkVersions.Count -gt 0) {
($frameworkVersions | Sort-Object) -join ", "
} else {
"Not detected"
}

# Output results
Write-Output "Test Results Summary:"
Write-Output "Total: $totalTests, Passed: $passedTests, Failed: $failedTests, Skipped: $skippedTests"
Write-Output "Pass Rate: $passTestRate"
Write-Output "Duration: $($executionTime.ToString('hh\:mm\:ss'))"
Write-Output "Frameworks Tested: $testedFrameworks"

# Final validation check
if ($skippedTests -eq 0) {
Write-Output ""
Write-Output "WARNING: No skipped tests detected. This could mean:"
Write-Output "1. Your test suite doesn't have any skipped tests ([Skip], [Ignore], etc.)"
Write-Output "2. The TRX format is different than expected"
Write-Output "3. Test conditions aren't being met that would cause skips"
Write-Output ""
Write-Output "To verify, try adding a test with [Skip] or [Ignore] attribute in your test suite."
}

# Output to GitHub environment variables
if ($env:GITHUB_ENV) {
"TEST_TOTAL=$totalTests" | Out-File -FilePath $env:GITHUB_ENV -Append
"TEST_PASSED=$passedTests" | Out-File -FilePath $env:GITHUB_ENV -Append
"TEST_FAILED=$failedTests" | Out-File -FilePath $env:GITHUB_ENV -Append
"TEST_SKIPPED=$skippedTests" | Out-File -FilePath $env:GITHUB_ENV -Append
"PASS_TEST_RATE=$passTestRate" | Out-File -FilePath $env:GITHUB_ENV -Append
"TEST_DURATION=$($executionTime.TotalSeconds)" | Out-File -FilePath $env:GITHUB_ENV -Append
"TESTED_FRAMEWORKS=$testedFrameworks" | Out-File -FilePath $env:GITHUB_ENV -Append
"LAST_UPDATED=$timestamp" | Out-File -FilePath $env:GITHUB_ENV -Append
}
33 changes: 29 additions & 4 deletions .github/workflows/build_and_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,44 @@ on:
workflow_dispatch:
workflow_call:
jobs:
buildAndTestUbuntu:
buildAndTestUbuntuRelease:
uses: ./.github/workflows/build_and_test_job.yaml
with:
os: ubuntu-latest
buildAndTestWindows:
configuration: Release
buildAndTestWindowsRelease:
uses: ./.github/workflows/build_and_test_job.yaml
with:
os: windows-latest
buildAndTestMac-x86_64:
configuration: Release
buildAndTestMac-x86_64Release:
uses: ./.github/workflows/build_and_test_job.yaml
with:
os: macos-13
buildAndTestMac-arm64:
configuration: Release
buildAndTestMac-arm64Release:
uses: ./.github/workflows/build_and_test_job.yaml
with:
os: macos-latest
configuration: Release
buildAndTestUbuntuDebug:
uses: ./.github/workflows/build_and_test_job.yaml
with:
os: ubuntu-latest
configuration: Debug
buildAndTestWindowsDebug:
uses: ./.github/workflows/build_and_test_job.yaml
with:
os: windows-latest
configuration: Debug
buildAndTestMac-x86_64Debug:
uses: ./.github/workflows/build_and_test_job.yaml
with:
os: macos-13
configuration: Debug
buildAndTestMac-arm64Debug:
uses: ./.github/workflows/build_and_test_job.yaml
with:
os: macos-latest
configuration: Debug

76 changes: 72 additions & 4 deletions .github/workflows/build_and_test_job.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,24 @@ on:
- macos-latest
- macos-13
default: windows-latest
configuration:
type: choice
description: 'Build configuration. Default: Release'
required: true
options:
- Debug
- Release
default: Release
workflow_call:
inputs:
os:
type: string
required: true
default: ubuntu-latest
configuration:
type: string
required: false
default: Release
jobs:
buildAndTest:
runs-on: ${{ inputs.os }}
Expand All @@ -29,19 +41,23 @@ jobs:
dotnet-version: |
8.0.x
9.0.x
10.0.x
- name: Restore dependencies
run: dotnet restore src
- name: Build
run: dotnet build --configuration Release --no-restore src
run: dotnet build --configuration ${{ inputs.configuration }} --no-restore src
- name: TestWindows
if: ${{ startsWith(inputs.os, 'windows') }}
run: dotnet test --no-build --configuration Release --verbosity minimal --logger "trx;LogFilePrefix=testResults"
run: dotnet test --no-build --configuration ${{ inputs.configuration }} --verbosity minimal --logger "trx;LogFilePrefix=testResults"
working-directory: ./src
- name: TestUnix
if: ${{ startsWith(inputs.os, 'ubuntu') || startsWith(inputs.os, 'macos') }}
run: |
dotnet test --framework net8.0 --no-build --configuration Release --verbosity minimal --logger "trx;LogFileName=net8.0/testResults.trx"
dotnet test --framework net9.0 --no-build --configuration Release --verbosity minimal --logger "trx;LogFileName=net9.0/testResults.trx"
set +e # Disable exit on error to ensure all frameworks are tested
dotnet test --framework net8.0 --no-build --configuration ${{ inputs.configuration }} --verbosity minimal --logger "trx;LogFileName=${{ inputs.os }}/net8.0/testResults.trx"
dotnet test --framework net9.0 --no-build --configuration ${{ inputs.configuration }} --verbosity minimal --logger "trx;LogFileName=${{ inputs.os }}/net9.0/testResults.trx"
dotnet test --framework net10.0 --no-build --configuration ${{ inputs.configuration }} --verbosity minimal --logger "trx;LogFileName=${{ inputs.os }}/net10.0/testResults.trx"
set -e # Re-enable exit on error
working-directory: ./src
- name: Test Report
uses: dorny/test-reporter@v2
Expand All @@ -50,3 +66,55 @@ jobs:
name: Test Report for ${{ inputs.os }}
path: ./src/**/*.trx
reporter: dotnet-trx
- name: Parse Test Results
if: success() || failure()
shell: pwsh
run: |
# Ensure script is executable on Unix systems
if ($IsLinux -or $IsMacOS) {
chmod +x .github/scripts/Parse-TestResults.ps1
}
.github/scripts/Parse-TestResults.ps1 -EnableDebug
- name: Comment PR with Test Results
uses: marocchino/sticky-pull-request-comment@v2
if: github.event.pull_request.number != null && (success() || failure())
with:
recreate: true
header: test-results-${{ inputs.os }}-${{ inputs.configuration }}
message: |
## 🧪 Test Results for ${{ inputs.os }} (${{ inputs.configuration }})

**Build Status:** ${{ job.status == 'success' && '✅ Passed' || '❌ Failed' }}

### 📊 Test Statistics
| Metric | Value |
|--------|-------|
| **Total Tests** | ${{ env.TEST_TOTAL }} |
| **✅ Passed** | ${{ env.TEST_PASSED }} |
| **❌ Failed** | ${{ env.TEST_FAILED }} |
| **⏭️ Skipped** | ${{ env.TEST_SKIPPED }} |
| **⏱️ Duration** | ${{ env.TEST_DURATION }}s |
| **📈 Pass Rate** | ${{ env.PASS_TEST_RATE }} |

### 🔧 Build Information
- **OS:** `${{ inputs.os }}`
- **Configuration:** ${{ inputs.configuration }}
- **Frameworks Tested:** `${{ env.TESTED_FRAMEWORKS }}`

### 📋 Links & Resources
- 📊 [Detailed Test Report](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
- 🔍 [View Test Files](https://github.com/${{ github.repository }}/tree/${{ github.sha }}/src/StaticMock.Tests/Tests)

---
<details>
<summary>🔍 Technical Details</summary>

- **Commit:** [`${{ github.sha }}`](https://github.com/${{ github.repository }}/commit/${{ github.sha }})
- **Branch:** `${{ github.head_ref || github.ref_name }}`
- **Run ID:** `${{ github.run_id }}`
- **Attempt:** `${{ github.run_attempt }}`
- **Workflow:** `${{ github.workflow }}`

</details>

*Last updated: ${{ env.LAST_UPDATED }}*
Loading
Loading