ISEPester.psm1
#region prefix code #region content of file ImportModule try { Import-Module -Name Pester -MinimumVersion 5.0 -ErrorAction Stop } catch { Write-Error -Message "Failed to import module Pester - can't continue. Error: $_" return } #endregion #endregion #region private functions #region content of file Get-psISE function Get-psISE { <# .Synopsis Helper function that returns psISE object (needed for testing /mocking) .Description $psISE automatic variable is read-only and can't be replaced inside ISE. To prevent not being able to test module inside that host - adding simple function that returns this object. .Example $test = Get-psISE Saves value of psISE object into variable test. #> [CmdletBinding()] param () $psISE } #endregion #endregion #region public functions #region content of file Invoke-ISECurrentTest function Invoke-ISECurrentTest { <# .Synopsis Function to run tests based on cursor location in editor file. .Description PowerShell ISE allows to see current location of the cursor in editor tab. Using that information makes it possible to run a test based on that location. Logic is: - if the cursor is on the line with container name (It, Context, Describe) that block is called. - if the cursor is on the line inside any `It` block - that block only would be called. .Example Invoke-ISECurrentTest Runs test on the line where cursor in the current file is located. #> [CmdletBinding()] param () try { $ise = Get-psISE } catch { Write-Warning -Message 'Command designed to use in PowerShell ISE' } if (-not (Get-Module -Name Pester)) { try { Import-Module -Name Pester -MinimumVersion 5.0 -ErrorAction Stop } catch { Write-Warning -Message "Failed to import Pester module - $_" } } if ( ($file = $ise.CurrentFile) -and (Test-Path -LiteralPath $file.FullPath) -and ($line = $file.Editor.CaretLineText) -and ($lineNumber = $file.Editor.CaretLine) ) { if (-not $file.IsSaved) { Write-Warning -Message "File $($file.FullPath) is not saved - working on current copy on disk!" } $config = [PesterConfiguration]@{ Run = @{ Path = $file.FullPath } } $config.Output = $script:outputConfiguration if ($line -match '\s*(Describe|Context|It)') { $config.Filter.Line = '{0}:{1}' -f $file.FullPath, $lineNumber } else { $parsedTestFile = [System.Management.Automation.Language.Parser]::ParseFile($file.FullPath, [ref]$null, [ref]$null) $myItBlock = $parsedTestFile.FindAll( { param ( $Ast ) $Ast.CommandElements -and $Ast.CommandElements[0].Value -eq 'It' -and $Ast.Extent.StartLineNumber -le $lineNumber -and $Ast.Extent.EndLineNumber -ge $lineNumber }, $true ) if ($myItBlock) { $config.Filter.Line = '{0}:{1}' -f $file.FullPath, $myItBlock[0].Extent.StartLineNumber } else { Write-Warning -Message "Line '$line' at $lineNumber is not inside It block - perhaps $($file.FullPath) is not a test file?" return } } if ($script:invokeScope -eq 'ParentScope') { Invoke-Pester -Configuration $config } else { & { Invoke-Pester -Configuration $config } } } else { Write-Warning -Message 'Command can work only with test files saved on disk - save it first!' } } #endregion #region content of file Set-ISEPesterConfiguration function Set-ISEPesterConfiguration { <# .Synopsis Function to configure the way Pester tests run in the ISE. .Description Functions allows to configure how tests in context of ISE will behave. It includes: - output options - scoping (to prevent polluting current scope) .Example Set-ISEPesterConfiguration -Verbosity Detailed -StackTraceVerbosity Filtered Changes outpuf of pester calls to: - display detailed results - show filter view for stack trace .Example Set-ISEPesterConfiguration -Invoke ChildScope Configures command to run in the child scope to prevent polluting parent scope. #> [CmdletBinding()] param ( # Verbosity of output [ValidateSet( 'None', 'Normal', 'Detailed', 'Diagnostic' )] [String]$Verbosity, # Verbosity of stack trace [ValidateSet( 'None', 'FirstLine', 'Filtered', 'Full' )] [String]$StackTraceVerbosity, # The CI format of error output in build logs [ValidateSet( 'None', 'Auto', 'AzureDevops', 'GithubActions' )] [String]$CIFormat, # The way of running tests [ValidateSet( 'ParentScope', 'ChildScope' )] [String]$InvokeScope ) foreach ( $key in @( 'Verbosity' 'StackTraceVerbosity' 'CIFormat' ) ) { if ($PSBoundParameters.ContainsKey($key)) { $script:outputConfiguration.$key = $PSBoundParameters.$key } } if ($PSBoundParameters.ContainsKey('InvokeScope')) { $script:invokeScope = $InvokeScope } } #endregion #endregion #region sufix #region content of file ISEAddOn try { $null = $psise.CurrentPowerShellTab.AddOnsMenu.Submenus.Add( 'Run in Pester', { Invoke-ISECurrentTest }, 'CTRL+F8' ) } catch { Write-Warning -Message "Failed to add shortcut - $_" } $script:outputConfiguration = [Pester.OutputConfiguration]::Default $script:invokeScope = 'ParentScope' #endregion #endregion |