Home > Back-end >  Is there any way to test functions in a PowerShell script without executing the script?
Is there any way to test functions in a PowerShell script without executing the script?

Time:01-27

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
  • Related