Skip to content

Commit

Permalink
Merge pull request #326 from pester/Fail-It-on-BeforeEach/BeforeAll-fail
Browse files Browse the repository at this point in the history
Make errors in BeforeEach and AfterEach fail the test
  • Loading branch information
nohwnd committed Apr 25, 2015
2 parents 3eb8052 + 6c33020 commit 05b2397
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 18 deletions.
32 changes: 23 additions & 9 deletions Functions/It.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -230,17 +230,36 @@ function Invoke-Test
}
else
{
Invoke-TestCaseSetupBlocks

$errorRecord = $null
try{
try
{
Invoke-TestCaseSetupBlocks

do
{
$null = & $ScriptBlock @Parameters
} until ($true)
} catch {
}
catch
{
$errorRecord = $_
}
finally
{
#guarantee that the teardown action will run and prevent it from failing the whole suite
try
{
if (-not ($Skip -or $Pending))
{
Invoke-TestCaseTeardownBlocks
}
}
catch
{
$errorRecord = $_
}
}


$result = Get-PesterResult -Test $ScriptBlock -ErrorRecord $errorRecord
$orderedParameters = Get-OrderedParameterDictionary -ScriptBlock $ScriptBlock -Dictionary $Parameters
Expand All @@ -252,11 +271,6 @@ function Invoke-Test
$Pester.testresult[-1] | & $OutputScriptBlock
}

if (-not ($Skip -or $Pending))
{
Invoke-TestCaseTeardownBlocks
}

Exit-MockScope
$Pester.LeaveTest()
}
Expand Down
2 changes: 2 additions & 0 deletions Functions/SetupTeardown.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,5 @@ Describe 'Finishing TestGroup Setup and Teardown tests' {
$script:ContextAfterAllCounter | Should Be 1
}
}

#Testing if failing setup or teardown will fail 'It' is done in the TestsRunningInCleanRunspace.Tests.ps1 file
10 changes: 1 addition & 9 deletions Functions/SetupTeardown.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,7 @@ function Invoke-Blocks
foreach ($block in $ScriptBlock)
{
if ($null -eq $block) { continue }

try
{
. $block
}
catch
{
Write-Error -ErrorRecord $_
}
. $block
}
}

Expand Down
60 changes: 60 additions & 0 deletions Functions/TestsRunningInCleanRunspace.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,63 @@ Describe "Tests running in clean runspace" {
$result.TotalCount | Should Be 4
}
}

Describe 'Guarantee It fail on setup or teardown fail (running in clean runspace)' {
#these tests are kinda tricky. We need to ensure few things:
#1) failing BeforeEach will fail the test. This is easy, just put the BeforeEach in the same try catch as the invocation
# of It code.
#2) failing AfterEach will fail the test. To do that we might put the AfterEach to the same try as the It code, BUT we also
# want to guarantee that the AfterEach will run even if the test in It will fail. For this reason the AfterEach must be triggered in
# a finally block. And there we are not protected by the catch clause. So we need another try in the the finally to catch teardown block
# error. If we fail to do that the state won't be correctly cleaned up and we can get strange errors like: "You are still in It block", when
# running next test. For the same reason I am putting the "ensure all tests run" tests here. otherwise you get false positives because you cannot determine
# if the suite failed because of the whole suite failed or just a single test failed.

It 'It fails if BeforeEach fails' {
$testSuite = {
Describe 'Guarantee It fail on setup or teardown fail' {
BeforeEach {
throw [System.InvalidOperationException] 'test exception'
}

It 'It fails if BeforeEach fails' {
$true
}
}
}

$result = Invoke-PesterInJob -ScriptBlock $testSuite

$result.FailedCount | Should Be 1
$result.TestResult[0].FailureMessage | Should Be "test exception"
}

It 'It fails if AfterEach fails' {
$testSuite = {
Describe 'Guarantee It fail on setup or teardown fail' {
It 'It fails if AfterEach fails' {
$true
}

AfterEach {
throw [System.InvalidOperationException] 'test exception'
}
}

Describe 'Make sure all the tests in the suite run' {
#when the previous test fails in after each and
It 'It is pending' -Pending {}
}
}

$result = Invoke-PesterInJob -ScriptBlock $testSuite

if ($result.PendingCount -ne 1)
{
throw "The test suite in separate runspace did not run to completion, it was likely terminated by an uncaught exception thrown in AfterEach."
}

$result.FailedCount | Should Be 1
$result.TestResult[0].FailureMessage | Should Be "test exception"
}
}

0 comments on commit 05b2397

Please sign in to comment.