Skip to content

Commit

Permalink
Skip blocks without runnable tests (#2447)
Browse files Browse the repository at this point in the history
* Use new certificate thumbprint

* Skip blocks when no tests should execute

* Don't modify blocks that are excluded

Caused wrong Result as Skipped takes precedence over NotRun

* Add test for onetime setup/teardown on skipped blocks

* Update test

* Cleanup

---------

Co-authored-by: Jakub Jareš <[email protected]>
  • Loading branch information
fflaten and nohwnd authored May 17, 2024
1 parent 93c6610 commit d324f29
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 45 deletions.
37 changes: 37 additions & 0 deletions src/Pester.Runtime.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2073,6 +2073,7 @@ function PostProcess-DiscoveredBlock {
}

$blockShouldRun = $false
$allTestsSkipped = $true
if ($tests.Count -gt 0) {
foreach ($t in $tests) {
$t.Block = $b
Expand Down Expand Up @@ -2152,11 +2153,19 @@ function PostProcess-DiscoveredBlock {
$testsToRun[-1].Last = $true
$blockShouldRun = $true
}

foreach ($t in $testsToRun) {
if (-not $t.Skip) {
$allTestsSkipped = $false
break
}
}
}
}

$childBlocks = $b.Blocks
$anyChildBlockShouldRun = $false
$allChildBlockSkipped = $true
if ($childBlocks.Count -gt 0) {
foreach ($cb in $childBlocks) {
$cb.Parent = $b
Expand All @@ -2171,9 +2180,17 @@ function PostProcess-DiscoveredBlock {
$childBlocksToRun[0].First = $true
$childBlocksToRun[-1].Last = $true
}

foreach ($cb in $childBlocksToRun) {
if (-not $cb.Skip) {
$allChildBlockSkipped = $false
break
}
}
}

$shouldRunBasedOnChildren = $blockShouldRun -or $anyChildBlockShouldRun
$shouldSkipBasedOnChildren = $allTestsSkipped -and $allChildBlockSkipped

if ($b.ShouldRun -and -not $shouldRunBasedOnChildren) {
if ($PesterPreference.Debug.WriteDebugMessages.Value) {
Expand All @@ -2182,6 +2199,26 @@ function PostProcess-DiscoveredBlock {
}

$b.ShouldRun = $shouldRunBasedOnChildren

if ($b.ShouldRun) {
if (-not $b.Skip -and $shouldSkipBasedOnChildren) {
if ($PesterPreference.Debug.WriteDebugMessages.Value) {
if ($b.IsRoot) {
Write-PesterDebugMessage -Scope Skip "($($b.BlockContainer)) Container will be skipped because all included children are marked as skipped."
} else {
Write-PesterDebugMessage -Scope Skip "($($b.Path -join '.')) Block will be skipped because all included children are marked as skipped."
}
}
$b.Skip = $true
} elseif ($b.Skip -and -not $shouldSkipBasedOnChildren) {
if ($PesterPreference.Debug.WriteDebugMessages.Value) {
Write-PesterDebugMessage -Scope Skip "($($b.Path -join '.')) Block was marked as skipped, but one or more children are explicitly requested to be run, so the block itself will not be skipped."
}
# This is done to execute setup and teardown before explicitly included tests, e.g. using line filter
# Remaining children have already inherited block-level Skip earlier in this function as expected
$b.Skip = $false
}
}
}
}

Expand Down
133 changes: 88 additions & 45 deletions tst/Pester.Runtime.ts.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -1225,52 +1225,49 @@ i -PassThru:$PassThru {
$container.EachTestTeardown | Verify-Equal 0
}

t "skipping all items in a block will skip the parent block" {
# this is not implemented, but is a possible feature
# which could be implemented together with "if any test is explicitly unskipped in child
# then the block should run, this will be needed for running tests explicitly by path I think
# it also should be taken into consideration whether or not adding a lazySkip is a good idea and how it would
# affect implementation of this. Right now skipping the block goes from parent down, and skipping all items in a block
# will not prevent the parent block setups from running

# $container = @{
# OneTimeTestSetup = 0
# OneTimeTestTeardown = 0
# EachTestSetup = 0
# EachTestTeardown = 0
# TestRun = 0
# }
t 'skipping all items in a block will skip the parent block' {
$container = @{
OneTimeTestSetup = 0
OneTimeTestTeardown = 0
EachTestSetup = 0
EachTestTeardown = 0
TestRun = 0
}

$actual = Invoke-Test -SessionState $ExecutionContext.SessionState -BlockContainer (New-BlockContainerObject -ScriptBlock {
New-OneTimeTestSetup -ScriptBlock { $container.OneTimeTestSetup++ }
New-OneTimeTestTeardown -ScriptBlock { $container.OneTimeTestTeardown++ }

New-Block 'parent block' {
New-OneTimeTestSetup -ScriptBlock { $container.OneTimeTestSetup++ }
New-OneTimeTestTeardown -ScriptBlock { $container.OneTimeTestTeardown++ }

New-EachTestSetup -ScriptBlock { $container.EachTestSetup++ }
New-EachTestTeardown -ScriptBlock { $container.EachTestTeardown++ }

New-Test 'test1' -Skip {
$container.TestRun++
'a'
}

# $actual = Invoke-Test -SessionState $ExecutionContext.SessionState -BlockContainer (New-BlockContainerObject -ScriptBlock {
# New-Block "parent block" {
# New-Block "parent block" {
# # putting this in child block because each test setup is not supported in root block
# New-OneTimeTestSetup -ScriptBlock { $container.OneTimeTestSetup++ }
# New-OneTimeTestTeardown -ScriptBlock { $container.OneTimeTestTeardown++ }

# New-EachTestSetup -ScriptBlock { $container.EachTestSetup++ }
# New-EachTestTeardown -ScriptBlock { $container.EachTestTeardown++ }

# New-Test "test1" -Skip {
# $container.TestRun++
# "a"
# }

# New-Test "test2" -Skip {
# $container.TestRun++
# "a"
# }
# }
# }
# })

# # $actual.Blocks[0].Skip | Verify-True
# $actual.Blocks[0].ErrorRecord.Count | Verify-Equal 0
# $container.TestRun | Verify-Equal 0
# $container.OneTimeTestSetup | Verify-Equal 0
# $container.OneTimeTestTeardown | Verify-Equal 0
# $container.EachTestSetup | Verify-Equal 0
# $container.EachTestTeardown | Verify-Equal 0
New-Block 'inner block' -Skip {
New-Test 'test2' {
$container.TestRun++
'a'
}
}
}
})

# Should be marked as Skip by runtime
$actual.Blocks[0].Skip | Verify-True
$actual.Blocks[0].ErrorRecord.Count | Verify-Equal 0

$container.TestRun | Verify-Equal 0
$container.OneTimeTestSetup | Verify-Equal 0
$container.OneTimeTestTeardown | Verify-Equal 0
$container.EachTestSetup | Verify-Equal 0
$container.EachTestTeardown | Verify-Equal 0
}
}

Expand Down Expand Up @@ -1341,6 +1338,52 @@ i -PassThru:$PassThru {
$container.EachBlockTeardown1 | Verify-Equal 1
# $container.OneTimeBlockTeardown1 | Verify-Equal 1
}

t 'setup and teardown are executed on skipped parent blocks when a test is explicitly included' {
$container = @{
OneTimeTestSetup = 0
OneTimeTestTeardown = 0
EachTestSetup = 0
EachTestTeardown = 0
TestRun = 0
}

$sb = {
New-OneTimeTestSetup -ScriptBlock { $container.OneTimeTestSetup++ }
New-OneTimeTestTeardown -ScriptBlock { $container.OneTimeTestTeardown++ }

New-Block 'parent block' -Skip {
New-OneTimeTestSetup -ScriptBlock { $container.OneTimeTestSetup++ }
New-OneTimeTestTeardown -ScriptBlock { $container.OneTimeTestTeardown++ }

New-EachTestSetup -ScriptBlock { $container.EachTestSetup++ }
New-EachTestTeardown -ScriptBlock { $container.EachTestTeardown++ }

New-Test 'test1' -Skip { # <--- Linefilter here ($sb assignment + 11 lines). Should run
$container.TestRun++
'a'
}

New-Test 'test2' -Skip { # Should not run
$container.TestRun++
'a'
}
}
}

$f = New-FilterObject -Line "$($sb.File):$($sb.StartPosition.StartLine + 11)"
$actual = Invoke-Test -SessionState $ExecutionContext.SessionState -BlockContainer (New-BlockContainerObject -ScriptBlock $sb) -Filter $f

# Should be marked as Skip = false by runtime
$actual.Blocks[0].Skip | Verify-False
$actual.Blocks[0].ErrorRecord.Count | Verify-Equal 0

$container.TestRun | Verify-Equal 1
$container.OneTimeTestSetup | Verify-Equal 2
$container.OneTimeTestTeardown | Verify-Equal 2
$container.EachTestSetup | Verify-Equal 1
$container.EachTestTeardown | Verify-Equal 1
}
}

b "plugins" {
Expand Down

0 comments on commit d324f29

Please sign in to comment.