Как сделать TDD и модульное тестирование в PowerShell?

С появлением MS PowerShell во всех новых серверных продуктах я начинаю (неохотно) думать, что мне нужно отнестись к этому серьезно. Частью "серьезно" является TDD. Нашли ли вы хорошие методы для модульного тестирования сценариев Power Shell?

Я нашел образцы насмешек от Mr Geek Noise - но мне бы очень хотелось что-то вроде RhinoMocks. Брайан Хартсок имеет пример запуска тестов для строк powershell из MS Test. Немного хакерский, но, похоже, работает.

То, что я хочу, это опыт работы с Powershell TDD, который так же чист, как и на "настоящих" языках.


Обновите, чтобы уточнить:

Первые два ответа пытаются отвлечь меня от тестирования Powershell. Мнения интересные. Я не хочу знать, стоит ли тестировать в powershell. Это субъективный вопрос, который нужно задать на другом форуме. Я хочу решение для модульного тестирования PowerShell. Если вы думаете, что это плохая идея (это может быть), относитесь к ней как к веселому академическому вопросу.

  • Да, языки сценариев склеивают разрозненные системы. Тем не менее, как уже указывалось, также легко издеваться и ломать швы на динамическом языке.
  • Я не спрашиваю о "отладке". Отладка - чрезвычайно полезная тема. Я позволю кому-то еще спросить это.
  • Может быть, сценарии PS должны быть простыми. Язык поддерживает модульность, и неизбежно, что сложные процессы будут реализованы в PS (даже если это плохая идея).
  • Ответ на этот вопрос не "Вы не можете". Я могу видеть (из связанных блогов - которые являются немного старыми), что некоторые люди добились прогресса в проблеме.

Чтобы переформулировать: Как реализовать автоматизированное тестирование логики Powershell в стиле xUnit? Интеграционные тесты интересны, модульные тесты, которые ломают зависимости, наиболее интересны.

Ответ 1

Scott Muc начал проект для облегченной структуры BDD для PowerShell под названием Pester:

https://github.com/pester/Pester

Ответ 2

PsUnit теперь обновляется с помощью фреймворка. У меня была такая же проблема, как и у вас несколько месяцев назад, и я почувствовал, что PsUnit был большим и сложным для количества сценариев, которые мне приходилось писать, поэтому я написал свою собственную инфраструктуру unit test для PS. Например, PS имеют такую ​​же charectaristics, что и другие языки-языки script Языки, например, вы можете переопределять функции в любом месте в любое время, даже с областью действия в методах тестирования, которые отлично подходят для фальсификации (a.k.a. mocking). То есть, если у вас есть функция или объект, которые вы хотите проверить, которые зависят от других функций, вы можете объявить их в своем тестовом методе для создания локальной поддельной реализации.

Итак, с точки зрения того, какую тестовую структуру вы предпочитаете использовать, я бы сказал, что PS очень легко TDD. По крайней мере, это был мой опыт.

Ответ 3

Я думаю, что вы спрашиваете о "стратегиях тестирования" вместо TDD, поэтому я отвечу на оба вопроса.

Основная часть вашей работы в PowerShell будет интегрировать кучу разрозненных систем с помощью командлетов и объектов. Если вы хотите быть уверенными в том, что ваши скрипты PowerShell работают, приложите как можно больше усилий для создания идеальной промежуточной среды, чтобы максимально точно протестировать все эти системы.

Запуск ваших скриптов в идеальной промежуточной среде будет бесконечно более ценным, чем "формирование вашего дизайна" через TDD или "тестирование вашего намерения кода" с послеобеденными модульными тестами.

Небольшие заметки, которые могут помочь:

  • Переключатель -whatif существует во встроенных командлетах. Также я узнал, что вы тоже можете это сделать: -whatif:$someBool - вы узнаете, когда вам это нужно.
  • В ISE, входящем в V2, есть отладчик. Сладкое.
  • Вы всегда можете скопировать собственный командлет на С# и делать то, что вы там хотите.

Ответ 4

Мертвая дискуссия, но проблемы очень живы.

Единственное, что я вижу в обсуждении полезности модульного тестирования PS, учитывая его предполагаемое использование, включает модули в корпоративной системе. Представьте себе настройку предприятия с центральным хранилищем для общих сетевых/файловых задач, реализованных в PS. В этом случае у вас есть небольшое количество разработчиков и сетевых специалистов, все из которых имеют слегка перекрывающиеся обязанности. Разработчик создает модуль, инкапсулирующий бизнес-логику, и его полезность сразу же признается таковой, что в мгновение ока другие встраиваются и включают модуль в свои собственные усилия. Модуль включается во что угодно: от одноразовых интерактивных скриптов до средних клиентских приложений; Хотя некоторые могут не согласиться с вариантами использования для языка сценариев оболочки, эволюция является постоянной в этой области.

В этом сценарии я считаю, что есть значение при определении набора "контрактов" для этих общих модулей. Если обмен знаниями является неотъемлемой частью организации, тогда возможно, что более чем один человек будет изменять эти модули. Наличие модульных тестов подтвердит целостность модулей, будет иметь большое значение для поддержания порядка и минимизации хаоса, таким образом поддерживая (возможно, увеличивая) значение самих модулей.

Что касается предпочтительного подхода, я еще не принял его. PS напоминает жидкое/динамичное/подвижное вещество. Содержащая его в жесткой структуре, например, то, что я видел с TDD, кажется неестественным. Однако, учитывая приведенный выше сценарий, эту цель нельзя игнорировать. Nevermind, я разорван, жаль тратить ваше время. Спасибо, что прочитали.

Ответ 5

Я пишу некоторые базовые сценарии PowerShell с TDD, например, следующую модель:

Во-первых, спецификация в SUT_spec.ps1:

Import-Module -Name .\my_SUT.ps1

[email protected]{}
[email protected]{}
f1 $case1_input $case1_output

$case1_result = $case1_output["Output"] -eq "expected"
"f1 case1: $case1_result"

# repeat for all test cases

Remove-Module -Name my_SUT

Во-вторых, мой модуль (SUT) как функция в файле my_SUT.ps1:

function f1($the_input, $the_output)
{
    #take input from $the_input hashtable, process it and put output into $the_output hashtable.

    $the_output["Output"]="results"
}

В-третьих, высвобождаемая основная точка входа в виде отдельного файла, такого как SUT_spec.ps1, но с входными данными из фактических внешних источников.

Ответ 6

С вашего вопроса я думаю, что вы направляетесь к разочарованию. Powershell - это всего лишь небольшой язык командной строки. Конечно, он может делать все, что может сделать С#, и даже больше, но тогда может быть ассемблерный язык. Конечно, это также OO и подключился к библиотекам .NET, но это также С#, который является гораздо более понятным языком.

Если решение длиннее, чем один лайнер, или вы думаете, что вам нужно TDD, то вы не хотите использовать Powershell. Это загадочный язык, полный сюрпризов, которого следует избегать для чего-то сложного.

Если вы хотите сделать какой-то специальный поиск, заменить или форматировать текст или посмотреть в своей файловой системе, то Powershell - ваш друг. То, что вы действительно хотите сделать, это использовать его немного каждый день и часто повторяться, чтобы оставаться в курсе синтаксиса. По этой причине также избегайте библиотек Powershell с открытым исходным кодом и забывайте писать собственные CmdLets, если у вас нет особо специализированного случая для использования в командной строке ad hoc. Правила связывания труб являются тайными и уродливыми.

Это все, конечно, мое мнение, но я долгое время пользователь Powershell, и теперь я намного счастливее, когда я смотрю на него так.