Wednesday 24 November 2021

Scanning solutions for NUnit test adapter via Powershell

Checking that we have added test adapter for NUnit so that our tests in Azure Devops are run

A challenge with running tests inside Powershell can be if NUnit test adapter Nuget package is missing from the solution. If you run test using NUnit 2.x, you require NUnitTestAdapter. If you use NUnit 3.x, NUnit3TestAdapter is required. The following Powershell script can be used to check if we have added a Nuget package reference at least to one such test project in the solution. We have here some tests that will list up all PackageReference in csproj files of the solution. Note: this requires the following setup of your Nuget package references listed in the solution.
  • You have to have csproj projects in the solution
  • You must use PackageReference, i.e. list up nuget packages in the csproj file. This will not work if you instead use packages lock json format or packages.config.
The Powershell functions are these:
 
 
 
 Function Get-ProjectInSolution {
    [CmdletBinding()] param (
        [Parameter()][string]$Solution
    )
    $SolutionPath = $Solution
    $SolutionFile = Get-Item $SolutionPath
    $SolutionFolder = $SolutionFile.Directory.FullName

    Get-Content $Solution |
        Select-String 'Project\(' |
        ForEach-Object {
            $projectParts = $_ -Split '[,=]' | ForEach-Object { $_.Trim('[ "{}]') }
            [PSCustomObject]@{
                File = $projectParts[2]
                Guid = $projectParts[3]
                Name = $projectParts[1]
            }
        } |
        Where-Object File -match "csproj$" |
        ForEach-Object {
            Add-Member -InputObject $_ -NotePropertyName FullName -NotePropertyValue (Join-Path $SolutionFolder $_.File) -PassThru
        }
}

Function Get-TestProjectInSolution {
[CmdletBinding()] param (
[Parameter()][string]$Solution)
  
  $projects = & Get-ProjectInSolution $Solution
  $testProjects = $projects | Where-Object { $_.Name -like '*Test*' }
  return $testProjects
}


Function Get-PackagesInProject {
[CmdletBinding()] param (
[Parameter()][string]$ProjectFile)

Get-Content $ProjectFile | Write-Host 
}


# Get-ProjectInSolution "C:\dev\somesolution\someacme.sln" 

Function List-PackagesOfTestProjectInSolution {
[CmdletBinding()] param (
[Parameter()][string]$SolutionFile)

  & Get-TestProjectInSolution $SolutionFile | ForEach-Object {
   $filePath = $_.FullName 
   Write-Host $filePath
  (Get-Content $_.FullName | Find "<PackageReference Include")
}
}

 
    Function Get-PackagesOfTestProjectInSolution {
[CmdletBinding()] param (
[Parameter()][string]$SolutionFile)

$dict = @{}

  & Get-TestProjectInSolution $SolutionFile | ForEach-Object {
    $filePath = $_.FullName 
    # Write-Host $filePath
    if (-not $dict.ContainsKey($filePath)) {
        $dict[$filePath] = (Get-Content $_.FullName | Find "<PackageReference Include")
    }
    return $dict 
  }

}

Function Has-NunitTestAdapterPackageInTestProjectinSolution {
[CmdletBinding()] param (
[Parameter()][string]$SolutionFile) 
 $packagesDict = Get-PackagesOfTestProjectInSolution $SolutionFile
$allPackagesString = $packagesDict.Values
$isNunitTestAdapterFound = ($allPackagesString -like "*NUnit*TestAdapter*").Length -gt 0
return $isNunitTestAdapterFound
}


Get-PackagesOfTestProjectInSolution "C:\dev\someacme\someacme.sln" 

$isNunitTestAdapterPresent = Has-NunitTestAdapterPackageInTestProjectinSolution "C:\dev\someacme\somecme.sln" 

Write-Host "Is NUnit test adapter added?" $isNunitTestAdapterPresent

    
    
    
    
For example, we could run the function call : List-PackagesOfTestProjectInSolution "C:\dev\someacme\someacme.sln" And we get our lists of package references in that solution (here we only look inside projects with a name containing "Test":