I would like to define stand-alone functions in my PowerShell script and be able to Pester test the functions without executing the rest of the script. Is there any way to do this without defining the functions in a separate file?
In the following pseudocode example, how do I test functionA or functionB without executing mainFunctionality?
script.ps1:
functionA
functionB
...
mainFunctionality
script.Tests.ps1:
BeforeAll {
. $PSScriptRoot/script.ps1 # This will execute the mainFunctionality, which is what I want to avoid
}
Describe 'functionA' {
# ... tests
}
I believe in Python, you can do this by wrapping your "mainFunctionality" inside this condition, so I am looking for something similar in Powershell.
if __name__ == '__main__':
mainFunctionality
Ref: What does if __name__ == "__main__": do?
CodePudding user response:
Yes, you can use the Invoke-Expression cmdlet to test functions in a PowerShell script without executing the script. This cmdlet allows you to execute a string as if it were a command.
For example, if you have a function called Test-Function in your script, you can use the following command to test it: Invoke-Expression -Command "Test-Function"
function functionA {
# Do something
}
function functionB {
# Do something
}
function mainFunctionality {
# Do something
functionA
# Do something
functionB
# Do something
}
mainFunctionality
Yes, you can test functions in a PowerShell script without executing the rest of the script. To do this, you can use the Invoke-Pester command to run specific tests in the script. For example, if you wanted to test the functions functionA and functionB, you could use the following command:
Invoke-Pester -Script .\MyScript.ps1 -TestName functionA,functionB
This will execute the tests for the specified functions without executing the rest of the script.
CodePudding user response:
Using the PowerShell Abstract Syntax Tree (AST) to just grab functionA
and invoke it:
$ScriptBlock = {
function functionA {
Write-Host 'Do something A'
}
function functionB {
Write-Host 'Do something A'
}
function mainFunctionality {
# Do something
functionA
# Do something
functionB
# Do something
}
mainFunctionality
}
Using NameSpace System.Management.Automation.Language
$Ast = [Parser]::ParseInput($ScriptBlock, [ref]$null, [ref]$null) # or: ParseFile
$FunctionA = $Ast.FindAll({
$Args[0] -is [ScriptBlockAst] -and $Args[0].Parent.Name -eq 'functionA'
}, $True)
Invoke-Expression $FunctionA.EndBlock
Do something A