如何在Powershell中进行TDD和单元测试?


69

随着MS将Powershell应用于所有新服务器产品中,我开始(勉强地)认为我需要认真对待它。TDD是“认真对待”的一部分。您是否找到了对Power Shell脚本进行单元测试的好方法?

我从极客噪声先生那里找到了嘲笑的样本-但我真的很喜欢RhinoMocks之类的东西。Brian Hartsock有一个来自MS Test的对Powershell字符串进行运行测试的示例。有点骇人听闻,但似乎可行。

我想要的是Powershell TDD体验,就像“真实”语言一样干净。


更新以澄清:

前两个答案试图使我远离测试Powershell。意见很有趣。我不想知道在Powershell中测试是否是个好主意。这是一个主观的问题,应该在其他论坛中提出。我想要一个对Powershell进行单元测试的解决方案。如果您认为这是个坏主意(可能是),请将其视为一个有趣的学术问题。

  • 是的,脚本语言将不同的系统粘合在一起。但是,正如已经指出的那样,以动态语言模拟和破坏接缝也很容易。
  • 我不是在问“调试”。调试是一个非常有用的主题。我让别人问。
  • 也许PS脚本应该很简单。该语言支持模块化,并且不可避免地会在PS中实现复杂的流程(即使是一个不好的主意)。
  • 这个问题的答案不是“您不能”。我可以看到(从链接的博客-有点旧了),有些人在解决该问题上取得了进展。

重新说明一下如何以xUnit样式实现Powershell逻辑的自动化测试? 集成测试很有趣,而打破依赖关系的单元测试最有趣。


1
看看stackoverflow.com/questions/1004424/…还有一个类似的问题,其中包含一些链接(PSUnit和Lee Holmes发布)
stej

1
切勿掉以轻心。它以最少的代码实现了强大的功能。
D3vtr0n 2012年

Answers:


44

Scott Muc启动了一个用于PowerShell的轻量级BDD框架项目Pester:

https://github.com/pester/Pester


2
比PsUnit好得多的设计。它不需要破坏配置文件或安装程序。我已经打搅它,并将在本周开始使用它。
陡峭的


我还使用Pester在PowerShell的TDD上撰写了三部分的系列文章–请参阅实用的PowerShell单元测试
Michael Sorens 2015年

11

现在,PsUnit已使用框架进行了更新。几个月前,我遇到了与您相同的问题,并且我觉得PsUnit对于要编写的脚本数量来说既庞大又复杂,所以我为PS编写了自己的单元测试框架。PS具有与其他脚本语言(例如python)相同的特征,例如,即使在测试方法中具有范围(对于模拟(又称为模拟))来说,也可以随时随地覆盖函数。也就是说,如果您要测试的函数或对象依赖于其他函数,则可以在测试方法中声明它们以创建本地伪造的实现。

因此,考虑选择哪种测试框架,我想说PS对TDD来说很容易。至少那是我的经验。


1
PsUnit非常漂亮,轻巧。
伊恩·帕特里克·休斯

3

我认为您是在问“测试策略”而不是TDD,所以我将回答这两个问题。

在PowerShell中进行的大部分工作将通过cmdlet和对象管道集成许多不同的系统。如果您想确信自己的PowerShell脚本能正常工作,请尽最大努力构建一个完美的暂存环境,以便尽可能准确地测试所有这些系统。

与在TDD上“充实您的设计”或在事后进行单元测试“测试代码的意图”相比,在理想的暂存环境中运行脚本将具有更大的价值。

小注释可能会有所帮助:

  • -whatif开关位于内置cmdlet中。我也发现您也可以这样做:-whatif:$someBool-您会在需要时知道。
  • V2中的ISE具有调试器。甜。
  • 您始终可以在C#中编写自定义cmdlet,然后在其中执行任何操作。

嗯...你也怀疑它的可能性。请注意,Geek Noise博客演示了一种模拟解决方案(不同的系统)。
陡峭的

我可能认为,但是谁在乎呢?知道在测试和脚本中都键入“ \\ server \ fileshare”有什么价值?您要么过度指定与外部cmdlet的交互,要么仅测试自己系统中的交互(最终将仅占脚本的一小部分。)我认为这很有用,但是再次,您将收获通过在暂存环境中进行实际测试(如果可能,还可以进行生产),会带来更大的收益
Peter Seale,2009年

2
系统测试和单元测试都没有带来“更大的好处”-两者都需要。如果我正在测试“与外部cmdlet的交互”,则它不是单元测试。这是受益于单元测试/模拟的常见逻辑的一个简单示例:我们有一个部署后脚本,该脚本在Windows事件日志中标识有趣的错误-垃圾邮件除外。时髦的地方在这里很出色-不需要cmdlet。过滤条件复杂而微妙。提取where-object条件以运行并测试各种输入。容易提出其他例子。
陡峭的

0

讨论死气沉沉,但关切仍然存在。

考虑到单元测试PS的预期用途,我认为讨论中缺少一件事,因为它涉及企业系统中的模块。想象一下一个带有中央存储库的企业设置,用于在PS中实现常见的网络/文件级任务。在这种情况下,您将拥有少量的开发人员和网络专家,而他们的职责却有些重叠。开发人员创建了一个封装业务逻辑的模块,并立即确认了其有用性,因此其他人很快就介入了,并在自己的努力中整合了该模块。该模块包含在从一次性交互式脚本到中型客户端应用程序的所有内容中。尽管有些人可能不同意shell脚本语言的用例,但在该领域中,进化是不变的。

在这种情况下,我相信为这些要遵循的通用模块定义一组“合同”是有价值的。如果知识共享对于组织是必不可少的,那么修改这些模块的人可能不止一个。让单元测试验证模块的完整性将大大有助于维持秩序并最大程度地减少混乱,从而维持(也许增加)模块本身的价值。

至于首选方法,我尚未采用。PS让我想到了一种流体/动态/敏捷物质。将其包含在诸如我在TDD中看到的那样的刚性结构中感觉不自然。但是,鉴于上述情况,这个目标是不容忽视的。没关系,我很伤心,很抱歉浪费您的时间。感谢您的阅读。


这听起来与几年前我在“ PowerShell&.Net-建筑系统作为工具包”下的博客chrisoldwood.blogspot.co.uk/2011/11/…上的内容有些相似。我已经在PS中写了很多胶水,如果可以对其进行单元测试,将会感到更加自在-尤其是错误处理,因为在测试环境中通常很难模拟错误处理。
克里斯·奥尔德伍德

0

我正在使用TDD编写一些基本的PowerShell脚本,例如以下模型:

首先,SUT_spec.ps1中的规范:

Import-Module -Name .\my_SUT.ps1

$case1_input=@{}
$case1_output=@{}
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

其次,将my unit(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,但带有来自实际外部源的输入。


-4

从您的问题来看,我认为您将感到失望。Powershell只是一种命令行语言。当然,它可以执行C#可以执行的任何操作,甚至可以执行更多操作,但是汇编语言也可以执行。当然,它也是面向对象的,并且已经连接到.NET库,但是C#也是如此,它是一种更加简洁的语言。

如果解决方案的长度超过一个衬垫,或者您认为需要对其进行TDD,那么您就不想使用Powershell。这是一种充满惊奇的神秘语言,任何复杂的事物都应避免使用。

如果您想进行临时搜索并替换文本或设置其格式,或者在文件系统中四处查看,那么Powershell是您的朋友。您真正想做的是每天使用一点,并经常重复一遍,以保持对语法的熟悉。因此,也要避免使用开放源代码的Powershell库,而不必编写自己的CmdLets,除非您有非常专门的临时命令行用法。管道绑定规则是奥秘和丑陋的。

当然,这全都是我的意见,但是我是Powershell的长期用户,并且现在对它感到更加满意。


2
我假设将编写PowerShell脚本,因为MS正在努力推动它。它将很快变得有用。因为PS脚本将被编写,并且它们将是程序(但是谦虚),所以我希望它们坚固。因此,我想对其进行测试。您可能会不同意,但是,我们将此称为学术练习:您将如何对Powershell脚本进行单元测试?实际的结论可能是它太难了(我认为不是不可能),如果我坚持质量,我应该使用IronPython来编写脚本。:)
陡峭的

毫无疑问,Powershell中的TDD是可能的。毕竟,Powershell完全有可能做到C#可以做到的一切,然后再做到一些。从理论上讲,Powershell的功能性质使其可以成为比C#更好的测试语言。问题只是Powershell的语法和一般设计...好,丑陋且令人惊讶。拥有一年的经验后,让我们再谈谈...
Mike

1
我已经使用PS至少三年了(日常工作主要用于强大的文件功能)-我们现在可以谈谈:)我同意这很丑。但是,它具有很多功能。令人惊讶的是为什么我要测试它。
陡峭

1
顺便说一句,每当我问一个Powershell问题时,我也会倾向于得到答案,告诉我不要使用Powershell,而且很少得到实际的答案,所以我意识到这很烦人。很抱歉!在某些情况下,Powershell是您唯一的选择,例如在客户现场。
迈克

我喜欢PowerShell,并且使用它越多,并且越了解它,我就越喜欢它!我认为有很多像我这样的人。并且不要忘记,PowerShell以NuGet Package Manager Console的形式成为Visual Studio的重要组成部分。
knut
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.