问题
I have the following function (the function is an auxiliary function of an another function and it works correctly):
function Get-UserManager {
[CmdletBinding()]
param (
[pscredential] $credential,
[ValidateSet('ID')][string]$searchType,
[string]$searchString,
)
try {
$reply = Invoke-RestMethod -Method Get -Uri $full_uri -Credentia $cred
} catch {
Write-Verbose "Couldn't connect to the End Point"
Write-Debug "$($_.Exception)"
return $userListObject
}
$reply.elements | ForEach-Object {
return $_
}
}
I am required to write a PowerShell test for the following function (The test must include all possible outputs, because I need the code coverage to be 100%).
Can someone please help me how do I write a PowerShell test that can check all the possible outputs of this function?
The test should be like this:
$moduleRoot = Resolve-Path "$PSScriptRoot\.."
$moduleName = Split-Path $moduleRoot -Leaf
$cred = Get-Credential
Describe "Demonstarting Code Coverage of: $moduleName" {
It "Calls Function: get-UserManager" {
{Get-UserManager -credential $cred -searchType ID -searchString
'12345' -delimiter} | Should Be $userListObject
}
}
回答1:
I assume you're using Pester, which is a Behaviour-Driven Development (BDD) framework. That is, it is designed to help you verify the behaviour of your code.
Ideally, you'd design the tests first according to the specification, then write the code, but as you already have the code, you'll need to think about possible ways it could be used and how you expect it to behave in each case. For example, looking at your code, what do you expect to happen if $searchString
is empty or invalid credentials are passed? How can you test this actually happens?
Incidentally, code coverage is related to the execution paths in your code and just because you have 100% coverage, doesn't mean you have completely tested the code. For example, consider this basic function:
function Get-Product {
Param (
$Param1,
$Param2
)
return $Param1 * $Param2
}
A single test that calls, say, Get-Product -Param1 12 -Param2 3
will have 100% code coverage as it tests all possible paths in the code, but it doesn't tell me how my code handles, for example, $Param1
being a string (e.g. "12") or one parameter is negative, etc, so I haven't really tested it thoroughly.
回答2:
Your code is currently non-functional, I assume because you reduced it to share on StackOverflow but have left some key elements out. For example $full_uri
and $userListObject
aren't populated but are used in the function and you have an extra comma in your param block.
That being said, you probably want to take the approach of using Mocking to simulate parts of your script so you can force different behaviour to occur and visit every path in order to get 100% code coverage. For example you need a test where the API returns an exception and enters your Catch
block. That might look like this:
Describe "Demonstarting Code Coverage of: $moduleName" {
Context 'Unable to connect to the endpoint' {
Mock Invoke-RestMethod { Throw 'Endpoint unavailable' }
Mock Write-Verbose
Mock Write-Debug
It 'Should enter the catch block when the endpoint returns an error' {
Get-UserManager -Verbose -Debug
Assert-MockCalled Write-Verbose -Times 1 -Exactly
Assert-MockCalled Write-Debug -Times 1 -Exactly
}
}
}
If you're completely new to Pester, Mocking can be a tricky topic to get your head around at first. I recommend doing some learning on Pester first. I did a talk on Getting Started with Pester at PSDay last year that you might find informative.
来源:https://stackoverflow.com/questions/56223485/writing-tests-for-powershell-functions