FindDuplicateTestMethodsInSameFileName.ps1 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. # FindDuplicateTestMethodsInSameFileName.ps1
  2. param (
  3. [string]$solutionPath = ".\Tests"
  4. )
  5. # Set the base path for relative paths (current directory when script is run)
  6. $basePath = Get-Location
  7. # Define projects to ignore (add your project names or path patterns here)
  8. $ignoreProjects = @(
  9. "StressTests"
  10. # Add more as needed, e.g., "Tests/SubFolder/OldProject"
  11. )
  12. # Function to extract method names from a C# file
  13. function Get-TestMethodNames {
  14. param ($filePath)
  15. $content = Get-Content -Path $filePath -Raw
  16. $testMethods = @()
  17. # Match test attributes and capture method names with flexible spacing/comments
  18. $methodPattern = '(?s)(\[TestMethod\]|\[Test\]|\[Fact\]|\[Theory\])\s*[\s\S]*?public\s+(?:void|Task)\s+(\w+)\s*\('
  19. $methods = [regex]::Matches($content, $methodPattern)
  20. foreach ($match in $methods) {
  21. $methodName = $match.Groups[2].Value # Group 2 is the method name
  22. if ($methodName) { # Ensure we only add non-empty method names
  23. $testMethods += $methodName
  24. }
  25. }
  26. return $testMethods
  27. }
  28. # Collect all test files
  29. $testFiles = Get-ChildItem -Path $solutionPath -Recurse -Include *.cs |
  30. Where-Object { $_.FullName -match "Tests" -or $_.FullName -match "Test" }
  31. # Group files by filename
  32. $fileGroups = $testFiles | Group-Object -Property Name
  33. # Dictionary to track method names and their locations, scoped to same filenames
  34. $duplicates = @{}
  35. foreach ($group in $fileGroups) {
  36. if ($group.Count -gt 1) { # Only process files that exist in multiple locations
  37. $fileName = $group.Name
  38. $methodMap = @{} # Track methods for this specific filename
  39. foreach ($file in $group.Group) {
  40. # Skip files in ignored projects
  41. $skipFile = $false
  42. foreach ($ignore in $ignoreProjects) {
  43. if ($file.FullName -like "*$ignore*") {
  44. $skipFile = $true
  45. break
  46. }
  47. }
  48. if ($skipFile) { continue }
  49. $methods = Get-TestMethodNames -filePath $file.FullName
  50. foreach ($method in $methods) {
  51. if ($methodMap.ContainsKey($method)) {
  52. # Duplicate found for this method in the same filename
  53. if (-not $duplicates.ContainsKey($method)) {
  54. $duplicates[$method] = @($methodMap[$method])
  55. }
  56. $duplicates[$method] += $file.FullName
  57. } else {
  58. $methodMap[$method] = $file.FullName
  59. }
  60. }
  61. }
  62. }
  63. }
  64. # Output results with relative paths
  65. if ($duplicates.Count -eq 0) {
  66. Write-Host "No duplicate test method names found in files with the same name across projects." -ForegroundColor Green
  67. } else {
  68. Write-Host "Duplicate test method names found in files with the same name across projects:" -ForegroundColor Yellow
  69. foreach ($dup in $duplicates.Keys) {
  70. Write-Host "Method: $dup" -ForegroundColor Cyan
  71. foreach ($fullPath in $duplicates[$dup]) {
  72. $relativePath = Resolve-Path -Path $fullPath -Relative -RelativeBasePath $basePath
  73. Write-Host " - $relativePath" -ForegroundColor White
  74. }
  75. }
  76. # Display total number of duplicate methods
  77. Write-Host "Total number of duplicate methods: $($duplicates.Count)" -ForegroundColor Magenta
  78. # Fail the pipeline by setting a non-zero exit code
  79. exit 1
  80. }