Skip to content

Code coverage fails in some circumstances when UseBreakpoints is $false #2306

@johlju

Description

@johlju

Checklist

What is the issue?

I started seening this issue when I started doing class-based resource ~1 year ago, and since it has been troublesome to make a repro case so I just switched to using breakpoints for code coverage instead. But now I managed to repro it with simpler code and simpler tests.

This test works when CodeCoverage.UseBreakpoints = $true but fails when CodeCoverage.UseBreakpoints = $false.

There seems to be a problem somewhere inside Pester when using this new code coverage method.

Expected Behavior

The tests to pass regardless if UseBreakpoints is set to $true or $false.

Steps To Reproduce

File SqlServerDsc.psm1

class StartupParameters
{
    [System.UInt32[]]
    $TraceFlag

    static [StartupParameters] Parse([System.String] $InstanceStartupParameters)
    {
        $startupParameters = [StartupParameters]::new()

        $startupParameterValues = $InstanceStartupParameters -split ';'

        $startupParameters.TraceFlag = [System.UInt32[]] @(
            $startupParameterValues |
                Where-Object -FilterScript {
                    $_ -match '^-T\d+'
                } |
                ForEach-Object -Process {
                    [System.UInt32] $_.TrimStart('-T')
                }
        )

        return $startupParameters
    }
}

function Get-SqlDscTraceFlag
{
    [OutputType([System.UInt32[]])]
    [CmdletBinding(DefaultParameterSetName = 'ByServerName')]
    param
    (
        [Parameter(ParameterSetName = 'ByServiceObject', Mandatory = $true)]
        [Object]
        $ServiceObject
    )

    $traceFlags = [System.UInt32[]] @()

    if ($ServiceObject.StartupParameters)
    {
        $traceFlags = [StartupParameters]::Parse($ServiceObject.StartupParameters).TraceFlag
    }

    return , [System.UInt32[]] $traceFlags
}

File SqlServerDsc.Tests.ps1

BeforeAll {
    Import-Module -Name './SqlServerDsc.psm1' -Force
}

AfterAll {
    # Unload the module being tested so that it doesn't impact any other tests.
    Get-Module -Name 'SqlServerDsc' -All | Remove-Module -Force
}

Describe 'SqlServerDsc' {
    Context 'When one trace flag exist' {
        BeforeAll {
            $mockStartupParameters = '-T4199'

            $mockServiceObject = [PSCustomObject] @{
                StartupParameters = $mockStartupParameters
            }
        }

        Context 'When passing a service object' {
            It 'Should return the correct values' {
                $result = Get-SqlDscTraceFlag -ServiceObject $mockServiceObject

                $result | Should -HaveCount 1
                $result | Should -Contain 4199
            }
        }
    }
}

File debug.ps1

Switch UseBreakpoints to $true to verify that the tests passes using breakpoints for code coverage.

$pesterConfig = New-PesterConfiguration -Hashtable @{
    CodeCoverage = @{
        Enabled = $true
        Path = './SqlServerDsc.psm1'
        OutputPath = './Pester_coverage.xml'
        # Tests fails if this is $false
        UseBreakpoints = $false
    }
    Run = @{
        Path = '*.Tests.ps1'
    }
}

$Error.Clear()
$ErrorView = 'DetailedView'

Invoke-Pester -Configuration $pesterConfig

$Error

Describe your environment

Pester version     : 5.4.0 C:\source\SqlServerDsc\output\RequiredModules\Pester\5.4.0\Pester.psm1                       
PowerShell version : 7.3.2
OS version         : Microsoft Windows NT 10.0.22623.0

Possible Solution?

Sorry, unknown.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions