Когда люди (по крайней мере, люди) думают о Пауэршилле, они думают о некоторых магических командах и, возможно, о некоторых сценариях и где -то больше. PowerShell — это больше, чем это. Это не только последовательный язык программирования, но и функциональный язык. Вы можете создавать функции и модули, но не только вы можете использовать их в качестве управления конфигурацией с DSC и другими инструментами, вы можете использовать их на платформах без серверов, таких как функции AWS Lambda или Azure, вы можете создавать облачные решения либо на Azure, либо на AWS. Вы можете построить полные решения с PowerShell.
Даже если PowerShell рассматривается как инструменты OPS, она следует те же методы и закономерности, чем любой другой язык программирования. Единое тестирование является одним из этих моделей. Это гарантирует, что раздел по кодам раздела работал, как и ожидалось.
PowerShell владеет модульной структурой тестирования. Его имя ПЕСТЕР , Это вездесущий тест и издевательная структура для PowerShell. Это язык определения домена и набор инструментов для запуска устройства и приемлемого теста.
Установка Пестера
Даже если Pester теперь установлен по умолчанию в Windows 10, лучше обновить его до последней версии (теперь в 4.8.x, скоро в 5.x). Пестер может быть установлен на Windows PowerShell (даже на старой версии) и на PowerShell Core
Install-module -name Pester
Вам может потребоваться использовать параметр силы Если другой уже установлен
Install-module -name Pester -force
Да, вам больше не нужно использовать -Skippublisherchek, модуль Pester теперь подписан.
Основа
Тестовый скрипт начинается с описания. Опишите Block Создайте тестовый контейнер, где вы можете разместить данные и скрипт для выполнения ваших тестов. Каждая переменная, созданная внутри блока описывания, удаляется в конце выполнения блока.
Describe { # Test Code here }
Вы можете добавить теги и имя в каждый описывающий блок, чтобы определить сценарий тестирования
Describe -tag "SQL" -name "test1" { # Test Code here } Describe -tag "SQL" -name "test2" { # Test Code here }
Тесты внутри описывающего блока могут быть сгруппированы в контекст. Контекст также является контейнером, и каждая данных или переменная, созданная внутри контекста, удаляется в конце контекста контекста контекста и описывает определение применения.
Describe -tag "SQL" -name "Sqk2017" { # Scope Describe Context "Context 1" { # Test code Here # Scope describe 1 } Context "Context 2" { # Test code Here # Scope describe 2 } }
Это блокирует
Чтобы создать тест с Pester, мы просто используем ключевое слово. ИТ -блоки содержат испытательный скрипт. Этот сценарий должен сделать исключение. Блоки должны иметь явное описание, «возвращает имя чего -то» и блок сценария. Описание должно быть уникальным в сфере областей (описать или контекст). ИТ -описание может быть статичным или динамически созданным (т.е. вы можете использовать переменную в соответствии с описанием, если описание уникально)
Команда должна позволить вам сравнивать объекты, что -то из вашего кода с ожидаемым что -то, и бросить ошибку, если его блок не удается. Следует представить утверждение, что -то, что должно быть правдой, а если не бросить ошибку.
Есть несколько утверждений:
Быть | Сравните 2 объекта |
Beexactly | Сравните 2 объекта в чувствительном режиме. |
Begreaterthan | Объект должен быть больше значения |
Begreaterorequal | Объект должен быть больше или равным, чем значение |
Бейн | тест Если объект в массиве |
Блеск | Объект должен быть меньше, чем значение |
Белесорекал | Объект должен быть менее или равным, чем значение |
Быть будто | Выполнить сравнение -li |
BelikeExactly | Выполнить чувствительный к корпусу -LI сравнение |
Стало | Проверьте тип значения, подобного Оператор -IS |
Будь настоящим | Проверьте, верно ли значение |
BEFALSE | Проверьте, является ли значение ложным |
Havecount | Массив/сбор должен иметь указанное количество значений |
Содержать | Массив/коллекция должна содержать значение, например, оператор -контрав. |
Существует | Проверьте, существует ли объект в PSProvider (файл, реестр, …) |
FileContentMatch | Сравнение резервуара в текстовом файле |
FileContentMatchExactly | Сравнение Case Celective Regex в текстовом файле |
Filecontentmatchmultiline | Сравнение резервуара в многослойном текстовом файле |
Соответствие | Сравнение режима |
Совпадает | Сравнение чувствительного к случаю корпуса |
Бросать | Проверьте, бросает ли сценарий ошибку |
Бенуллоремпти | Проверяет, являются ли значения нулевые или пустую строку |
Describe "test" { It "true is not false" { $true | Should -Be $true } }
Как видите, ИТ -блок делится на две части. Первый, название, идентифицируйте тест. Второй, сценарий Bock может содержать любой код, который вам нужен, если вы передаете результат с оператором, который должен быть с помощью трубопровода. Оператор должен оценивать данные и принять ошибку, если условие оператора не соответствует. Мы также можем создать негативное утверждение с ключевым словом -NOT
Describe "test" { It "true is never false" { $true | Should -not -Be $false } }
Когда я пишу модульные тесты, мне часто нужно проверить одну и ту же часть кода или функции несколько раз с различными условиями или различными данными. Поскольку я ленивый, я не люблю писать один и тот же тест больше, чем один Или, может быть, два раза. Для этого мне просто нужен словарный объект и -testcase
$BufferSize = 4 $DataTypeName = [System.Byte[]]::new($BufferSize) $RandomSeed = [System.Random]::new() $RandomSeed.NextBytes($DataTypeName) $TestData = @(@{"TestValue" = "Value One"; "TestType" = "String"},@{"TestValue" = 2; "TestType" = "int32"},@{"TestValue" = $DataTypeName; "TestType" = "Byte[]"}) function get-DataTypeName { [CmdletBinding()] param ( $value ) return ($value.getType()).name } Describe "test some values" { It "Test ifis a Object" -TestCase $TestData { param($TestValue, $TestType) get-DataTypeName -value $TestValue | Should -Be $TestType } }
Когда вы используете -testcase с словарным объектом, IT -блок повторяет объект и выполнит тест для каждой итерации. Чтобы отобразить значение в описании ИТ, необходимо <>. Внутри ИТ -блока; Вам необходимо передавать данные в качестве параметров и получить их значение в переменных параметрах
О том, как писать и запустить тесты PESTER
Вы можете практически запустить Pester в любом файле PowerShell, но согласно соглашению рекомендуется использовать файл с именем xxx.tests.ps1. Один на файл PowerShell в вашем решении. Если у вас есть один файл на функцию, это означает один pester .tests.ps1. Вы можете разместить Pester -файлы в ту же папку, что и ваш исходный код, или вы можете использовать папку Tests в корне репозитория. Лично я предпочитаю использовать папку Tests, но где бы ни находились тестовые файлы, им нужно загрузить код.
Для этого вы можете установить сценарий, который вам нужно проверить.
Чтобы запустить все тесты в файлах .tests.ps1, вам просто нужно использовать Invoke-Pester из папки Tests. Если IT и описывают блоки, являются сердцем процесса тестирования, Invoke-Pester может быть печенью, поскольку она может фильтровать тесты и трансформировать результат.
С использованием параметра -testname или/и -tag в сочетании с -Passthru Вы можете фильтровать описать блок с именем теста или тегов.
Парам -strict позволяет рассмотреть любой ожидающий или скайп -тест, создаст сбой.
По умолчанию Пестер дает результат непосредственно в виде текста в консоли. В некоторой ситуации вы можете использовать другой формат.
Параметр -Passthru позволяет создать пользовательский объект PowerShell вместо стандартного вывода. Он производит PscustomObject с количеством тестов, количество пропущенных, пропущенных, ожидающих или неудачных. Он также содержит массив, испытанный со всеми результатами испытаний.
Переключатель -enableExist сделает выход Invoke -Pester с кодом выхода. Этот код равен 0, если все тесты проходят или количество неудачного теста. Это может быть полезно, что некоторые сценарии непрерывной интеграции.
Параметры OutputFile и OutputFormat будут перенаправлять выход в файл в формате NUNIT XML. По умолчанию Pester 4.x выведет результат с использованием формата NUNIT с использованием 2.5 схемы. Вы не можете изменить событие формата с -OutputFormat (Существует только одно возможное значение NUNITXML). Использование вывода может быть полезно с некоторым инструментом CI, который отображается NUNIT TEST Результат
Покрытие кода
Мера покрытия кода. Степень, в которой ваш код выполняется вашими тестами. Мера выражается в процентах. Процент покрытия не означает, что модуль или скрипт не составил ошибок, это означает только то, что код был запущен в процессе тестирования.
Чтобы сгенерировать метрику покрытия кода с помощью Pester, вам нужно использовать Invoke -Pester с -Коверж по пути сценария, который вам необходимо проверить.
invoke-pester -script .\function.test.ps1 -coverage .\function.ps1
Вы можете использовать подстановочный знак и кому для анализа нескольких файлов
invoke-pester -script .\functions.test.ps1 -coverage .\function.ps1, .\*.psm1
Вы также можете использовать хэштату для покрытия. Он должен содержать ключ пути. Вы можете использовать функциональный ключ для ограничения анализа этими функциями, или вы можете использовать Startline или Endline для ограничения анализа.
Обратите внимание, что на 100% покрытие не подразумевает, что код не содержит ошибок, это просто признак того, что весь ваш код был выполнен во время теста
Расширенное использование
Тест-драйв
Функции может потребоваться манипулировать файловой системой, она может создавать, удалять или изменять один или несколько файлов. Нежелательно изменить файловую систему на этапе испытания. Пестер обеспечивает диск с именем TestDrive:. Диск доступен в сфере теста (описать или контекст) и автоматически удаляется в конце сферы действия. При использовании тестового диска Pester создает случайную папку в $ env: TMP и используйте его для размещения файла из текущего тестового диска в область. Вы можете использовать TestDrive: \ или переменная $ testDrive для выполнения любой операции файла во время теста.
Describe "test" { new-item (Join-Path $TestDrive 'File.txt') It "Test if File.txt exist" { (test-path -path (Join-Path $TestDrive 'File.txt') ) | Should -Be $true } }
Насмешка
Сценарии и функции основаны на модулях и функциях, которые могут не присутствовать на тестовой машине, или выполнять разрушительную работу. Вы разрабатываете функцию, которая создает или удаляет учетную запись Active Directory. У вас может не быть никакого модуля Active Directory на тестовом компьютере, и/или вы не хотите вносить какие -либо изменения на производственном компьютере, вы создаете модуль, который изменяет конфигурацию сервера, и вы не хотите ничего менять на этапе тестирования Анкет Вы просто должны быть уверены, что код верен.
Измешивание в Пестере, пусть имитируйте результат функции или команды, вызванной во время теста. Когда вы используете Mock, вы просто создаете результат для данной команды, чтобы вы могли проверить другую часть своего сценария.
Чтобы издеваться над функцией или командой, вам просто нужно использовать макет и имя функции или команды.
Describe "test" { Mock remove-something { } It "Test if remove-something return null" { remove-something | Should BeNullOrEmpty } }
Измешивание ограничено масштабом теста, описывающей или контекста. Если вам нужно протестировать различное поведение, вы можете использовать -Праметрафильтер для создания разных результатов
Describe "test" { Mock Get-AswerAboutLifeUniverseEverything { return 42 } -ParameterFilter { $Name -eq "42" } Mock Get-AswerAboutLifeUniverseEverything { return 42 } -ParameterFilter { $Name -eq "57" } Mock Get-AswerAboutLifeUniverseEverything { return 42 } It "Test if Get-AswerAboutLifeUniverseEverything return 42" { Get-AswerAboutLifeUniverseEverything | Should be 42 } It "Test if Get-AswerAboutLifeUniverseEverything -Name 42 return 42" { Get-AswerAboutLifeUniverseEverything -Name 42 | Should be 42 } It "Test if Get-AswerAboutLifeUniverseEverything -Name 57 return 42" { Get-AswerAboutLifeUniverseEverything -Name 57 | Should be 42 } }
Вы можете использовать макет внутри ИТ -блока, в данном случае Mock будет доступен в родительской области.
Вы можете проверить, была ли вызвана высмеиваемая команда на этапе испытания. Можно проверить это двумя способами
Assert -verifiablemocks, добавьте ошибку, если макетная команда помечена как -вериваемое
Describe "test" { Mock Get-AswerAboutLifeUniverseEverything { return 42 } -Verifiable It "Test if remove-something return 42" { Get-AswerAboutLifeUniverseEverything | Should be 42 } Assert-VerifiableMocks }
Еще один способ проверить выполнение высмеивающей команды-использовать Assert-Mockcalled. Assert-Mockcalled должен быть помещен в блок IT. Вам нужно использовать его с параметром -commandName. Параметр возьмите имя высмеивающей команды
Describe "test" { Mock Get-AswerAboutLifeUniverseEverything { return 42 } It "Test if remove-something return 42" { Get-AswerAboutLifeUniverseEverything | Should be 42 } It "Test if remove-something was called" { Assert-MockCalled -CommandName Get-AswerAboutLifeUniverseEverything } }
Вы можете контролировать, сколько раз была вызвана высмеиваемая команда с параметром -times. Тест параметров времени x, если высмеиваемая команда была вызвана как минимум x раз. Если вам нужно проверить, что высмеиваемая команда называется только x раз, когда вы можете использовать -эксплуатировано
При насмешении функции или командлета вам может потребоваться вернуть объект. Например, Get-Aduser возвращает Microsoft. ActiveDirectory. Управление. Объект Aduser. Большую часть времени вы можете использовать объект Pscustom, чтобы высмеивать возвращенный объект
Describe "test" { Mock Get-AdUser { $AObject = [PSCustomObject]@{ Surname = "Marc" UserPrincipalName = "marc@mydomain.com" Enabled = $true SamAccountName = "marc" ObjectClass = "user" } Return $AdObject } -ParameterFilter { $Identity -eq "Marc" } It "Test if the User is Valid" { (Get-AdUser -identity "Marc").Enabled | Should betrue } It " Test if the User UPN " { (Get-AdUser -identity "Marc").UserPrincipalName | Should be "marc@mydomain.com" } }
Но иногда PscustomOmobject недостаточно. Это тот случай, когда вы используете класс в своем скрипте. Вы можете использовать новый MockObject для возврата любого типа объекта. New-MockObject Fake любой тип объекта без необходимости создавать его. Вы можете использовать его, чтобы издеваться над любым .NET Тип или у вас есть тип на основе класса
Mock Get-Something { New-MockObject -type 'System.Diagnostics.Process' }
В некоторой ситуации вам может потребоваться выполнить какой -то код до после тестов. Это может быть переменная инициализация или настройка среды.
Например, вы можете создать несколько файлов внутри тестового диска, открыть соединение с веб -сервисом, создать случайные данные. BefaReall и Afterall должны находиться внутри блока описания или контекста. Его можно размещать в любом месте в блоке, но лучше разместить BefaReall в начале и в конце концов.
Передеда и после обучения на каждом, он блокирует так же, как BefaReall/Afterall
Модульное тестирование
PESTER можно использовать для тестирования модуля PowerShell. Но помните, что Пестеру нужно получить доступ к коду для тестового кода. Первый шаг, так как модуль загружается в память, вам нужно инструктировать PowerShell для удаления модуля. Если нет, вы не можете проверить фактическую версию вашего кода.
Get-module -name 'TheModule' -all | remove-module -force -erroraction SilentContinue
Вы можете импортировать модуль
Import-Module -name PathTo\TheModule.psd1 -force -ErrorAction Stop
Проблемы, это у вас будет доступ только к публичной функции, объявленной Inside FunctionTo. Чтобы избежать этого, вам нужно использовать InModuScope
InModuleScope TheModule { Describe 'Module Test' { It 'test one not exported function' { Get-NotExportFunction | Should not Throw } } }
Это было мое знакомство с Пестером. Скажи мне, что ты думаешь
Оригинал: «https://dev.to/omiossec/unit-testing-in-powershell-introduction-to-pester-1de7»