简体   繁体   中英

Pester 5.0.2 BeforeAll block code not showing up in Describe block

I recently switched over to Pester 5.0.2 to start doing some testing on a Powershell script I wrote. I am able to break into the BeforeAll block and the paths are being populated as I would expect, however when I get to the Get-ChildItem area in my Describe block the variables from BeforeAll are $null.

BeforeAll {
    $testDir = Split-Path $PSCommandPath -Parent
    $prodDir = Split-Path $testDir -Parent
}
Describe "Tests - All Files in prod" {
    Get-ChildItem $prodDir -File | ForEach-Object {
        $fileName = (Split-Path $_ -leaf).PadRight(20, ' ')
        $filePath = $_.PSPath
        It "Vars not declared or changed between function definitions" {
            [System.Collections.ArrayList]$preSource = (Get-Variable).Name
            . "$filePath" -Sourcing
            [System.Collections.ArrayList]$postSource = (Get-Variable).Name
            $postSource.Remove('preSource')
            $postSource.Remove('UnderTest')
            [array]$diff = Compare-Object $preSource $postSource -PassThru
            $diff | Should -BeNullOrEmpty
        }
        It "$fileName all #*, #?, #TODO tags are removed" {
            $_ | Should -Not -FileContentMatch $([regex]::escape('#TODO'))
            $_ | Should -Not -FileContentMatch $([regex]::escape('#*'))
            $_ | Should -Not -FileContentMatch $([regex]::escape('#?'))
        }
    }
}

I found the answer, but it was a little hard to find in the documentation. This doesn't work any longer because of the new 'Discovery' feature. This runs before all of the Describe,It,Context,BeforeAll,AfterAll, etc... blocks. The code that was run here is then discarded.

I ended up using test cases using the -TestCase parameter to resolve the issue.

EDIT:

Below is version with comments on why it won't work and after that an example on how to set it up.

BeforeAll {
    # This block will run AFTER discovery. Anything you need to be evaluated in front of the tests should
    # be placed here
    $testDir = Split-Path $PSCommandPath -Parent
    $prodDir = Split-Path $testDir -Parent
}
$iWillDisappearAfterDiscovery = 'Byebye'
Describe "Describing your tests" {
    # Code placed here will be run DURING discovery, and will not be availble at runtime. Placing the code from
    # BeforeAll here instead would not work as $testDir and $prodDir would be empty when the tests ran. 
    #
    # The apparent exception to this rule is that the tests are done DURING discovery and then stashed for when
    # the tests run. That means your test cases can be set up here if not done directly inside the -TestCases parameter
    #
    Get-ChildItem $prodDir -File | ForEach-Object {
        $fileName = (Split-Path $_ -leaf).PadRight(20, ' ')
        $filePath = $_.PSPath
        It "Vars not declared or changed between function definitions" {
            [System.Collections.ArrayList]$preSource = (Get-Variable).Name
            . "$filePath" -Sourcing
            [System.Collections.ArrayList]$postSource = (Get-Variable).Name
            $postSource.Remove('preSource')
            $postSource.Remove('UnderTest')
            [array]$diff = Compare-Object $preSource $postSource -PassThru
            $diff | Should -BeNullOrEmpty
        }
        It "$fileName all #*, #?, #TODO tags are removed" {
            $_ | Should -Not -FileContentMatch $([regex]::escape('#TODO'))
            $_ | Should -Not -FileContentMatch $([regex]::escape('#*'))
            $_ | Should -Not -FileContentMatch $([regex]::escape('#?'))
        }
    }
}

# Here's a correct example:

BeforeAll {
    $testDir = Split-Path $PSCommandPath -Parent
    $prodDir = Split-Path $testDir -Parent
}
Describe "Describing your tests" {
    # You can still set them up dynamically as test cases
    [System.Collections.ArrayList]$testCases = @()
    Get-ChildItem $prodDir -File | ForEach-Object {
        $fileName = (Split-Path $_ -leaf).PadRight(20, ' ')
        $filePath = $_.PSPath
        $testCases.Add({fileName = $fileName; filePath = $filePath})
    }
    It "<fileName> Exists" -TestCases $testCases { 
        #using <varName> will dynamically name your tests with data
        # from your test cases
        $filePath | Should -Exist
    }
    It "<fileName> all #*, #?, #TODO tags are removed" {
        $filePath | Should -Not -FileContentMatch $([regex]::escape('#TODO'))
        $filePath | Should -Not -FileContentMatch $([regex]::escape('#*'))
        $filePath | Should -Not -FileContentMatch $([regex]::escape('#?'))
    }
    Context "Different Context, Run different tests" {
        $testCases = @{filename = 'file4'.PadRight(20, ' '); filepath = '/path/to/file4.ps1' },
        @{filename = 'file5'.PadRight(20, ' '); filepath = '/path/to/file5.ps1' }
        It "Exists" {
            $filePath | Should -Exist
        }
    }
    Context "You can also set them up inline like this" -TestCases @(
        $testCases = @{filename = 'file1'.PadRight(20, ' '); filepath = '/path/to/file1.ps1' },
        @{filename = 'file2'.PadRight(20, ' '); filepath = '/path/to/file2.ps1' },
        @{filename = 'file3'.PadRight(20, ' '); filepath = '/path/to/file3.ps1' }
    ) {
        It "Run some tests" {
            $fileName | Should -BeOfType [string]
        }
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM