How to do TDD and unit testing in powershell?

强颜欢笑 提交于 2019-11-27 10:54:54
Martin Suchanek

Scott Muc has started a project for a lightweight BDD framework for PowerShell called Pester:

https://github.com/pester/Pester

PsUnit is now updated with a framework. I had the same problem as you a few months ago and I felt PsUnit was to big and complex for the number of scripts I had to write so I wrote my own unit test framework for PS. PS have the same kind of charectaristics as other script languages likepython for example, i.e. you can override functions anywhere at any time even with scope in the test methods which is great for faking (a.k.a. mocking). That is, if you have a function or object you want to test that depends on other functions you can declare them in your test method to create a local fake implementation.

So regardles of which test framework you choose to use I'd say PS is very easy to TDD. That was my experience at least.

I think you're asking about "testing strategies" instead of TDD specifically, so I'll answer both questions.

The bulk of your work in PowerShell will be integrating a bunch of disparate systems via cmdlets and object pipes. If you want to be confident your PowerShell scripts work, put as much effort as possible into building a perfect staging environment, so as to test all these systems as accurately as possible.

Running your scripts in a perfect staging environment will be infinitely more valuable than "fleshing out your design" via TDD or "testing your code's intent" with after-the-fact unit tests.

Small notes that may help:

  • The -whatif switch exists on built-in cmdlets. Also I just found out you can do this as well: -whatif:$someBool - you'll know when you need it.
  • The ISE coming in V2 has a debugger. Sweet.
  • You can always code up a custom cmdlet in C# and do whatever you want there.

Dead discussion but the concerns are very much alive.

The one thing I see missing from the discussion of the usefulness of unit testing PS given its intended use involves modules in an enterprise system. Imagine an enterprise setting with a central repository for common network-/file-level tasks implemented in PS. In this setting, you have a small number of developers and network specialists all of which have slightly overlapping duties. A developer creates a module encapsulating business logic and its usefulness is immediately acknowledged such that in no time, others jump in and incorporate the module in their own efforts. The module is included in anything from one-off interactive scripts to medium-sized client applications; While some might not agree on the use cases for a shell-scripting language, evolution is a constant in this field.

In this scenario, I believe there's value in defining a set of "contracts" for these common modules to follow. If knowledge-sharing is integral to the organization then it's possible more than one person would be modifying these modules. Having unit tests validate the integrity of the modules would go a long way towards maintaining order and minimizing chaos thus sustaining (perhaps increasing) the value of the modules themselves.

As to a preferred approach, I've yet to adopt one. PS brings to mind a fluid/dynamic/agile substance. Containing it within a rigid structure such as what I've seen with TDD feels unnatural. However, given the scenario above, this goal can't be ignored. Nevermind, I'm torn, sorry to waste your time. Thank you for reading.

From your question I think you are headed for disappointment. Powershell is just a little command line language. Sure, it can do anything that C# can do, and even more, but then so can assembly language. Of course it's also OO and hooked in to the .NET libraries, but so is C#, which is a much much cleaner language.

If a solution is longer than a one liner, or you think you need to TDD it, then you don't want to be using Powershell. It's a cryptic language that is full of surprises, to be avoided for anything complicated.

If you want to do some ad hoc search and replace or formatting of text, or look around in your file system, then Powershell is your friend. What you really want to do is to use it a little every day, and repeat yourself often, in order to stay familiar with the syntax. For this reason, also avoid open source Powershell libraries, and forget about writing your own CmdLets, unless you have a very specialized case for ad hoc command line usage. The pipe binding rules are arcane and ugly.

This is all just my opinion of course, but I am a long time Powershell user and am much happier with it now that I look at it like this.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!