Код блока Pester 5.0.2 BeforeAll не отображается в блоке описания

Недавно я перешел на Pester 5.0.2, чтобы начать тестирование сценария Powershell, который я написал. Я могу проникнуть в блок BeforeAll, и пути заполняются, как я и ожидал, однако, когда я добираюсь до области Get-ChildItem в моем блоке Describe, переменные из BeforeAll равны $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('#?'))
        }
    }
}

person Efie    schedule 21.06.2020    source источник


Ответы (1)


Я нашел ответ, но его было немного сложно найти в документации. Это больше не работает из-за новой функции «Discovery». Это выполняется перед всеми блоками Describe, It, Context, BeforeAll, AfterAll и т. д. Код, который был запущен здесь, затем отбрасывается.

В итоге я использовал тестовые примеры с параметром -TestCase для решения проблемы.

РЕДАКТИРОВАТЬ:

Ниже приведена версия с комментариями о том, почему она не будет работать, а затем пример того, как ее настроить.

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]
        }
    }

}
person Efie    schedule 22.06.2020
comment
Я собирался прокомментировать то же самое, что и вчера. Исторически я использовал много циклов ForEach в своих тестах по сравнению с использованием параметра TestCases, поскольку я начал делать это до того, как TestCases стали чем-то особенным (я думаю). Однако, начиная с Pester v5, из-за того, как он проверяет обнаружение, кажется, что это больше не работает для всех случаев, в частности, когда вы сопоставляете переменную с параметром командлета. Использование TestCases является правильной альтернативой. - person Mark Wragg; 23.06.2020
comment
Отредактировано с некоторыми примерами - person Efie; 23.06.2020
comment
На моей стороне $PSCommandPath остается пустым с Pester 5. Что я делаю неправильно? - person Carl in 't Veld; 02.10.2020
comment
Я так не получаю Pester 5. Играю со своими собственными Foreach, я получаю $files cannot be retrieved error - person Lieven Keersmaekers; 12.03.2021
comment
Опубликуйте то, над чем вы работаете, в другом посте, и я постараюсь помочь вам с этим. Мне тоже было сложно. Пока не так много ресурсов для версии 5 о переполнении стека, поэтому ответы на некоторые из этих вопросов там, где это видят другие, вероятно, будут полезны. - person Efie; 12.03.2021
comment
Извините, я не понял, что вы сказали, что просто использовали пример. Какая у тебя версия 5? Они не добавляли поддержку -Foreach до версии 5.1. - person Efie; 12.03.2021
comment
Как вы вызываете тесты? Вы можете изменить уровень детализации вывода, используя устаревший параметр -Output Detailed или -Output Diagnostic. Если вы используете новый предпочтительный метод с объектом конфигурации, вы можете установить для параметра $config.Output.Verbosity значение Detailed. - person Efie; 12.03.2021
comment
Давайте продолжим обсуждение в чате. - person Efie; 12.03.2021