Test .NET library using PowerShell and Visual Studio Debugger

Often times, when a developer builds a C# library, there is always a need for unit testing it. If your company already has strictly guidelines on how to enforce unit testing before any code is checked in, you might want to read the policy procedure about how to do it. Visual Studio Team System 2008 can be configured to enforce such policy that if any unit tests fail, the check in is rejected. You can right click on the solution->New->Add project->Test->Test project to create unit tests. Every time, you change the data in your test, you need to re-compile the test dll and run the test. Don’t you think that’s an overhead for changing calls from ”client.CreateEmail("XBOX", "hil1@msn.com");” to “client.CreateEmail("Live", "hil1@msn.com");”? PowerShell comes handy to solve this problem. You can easily code unit tests for your methods and change them without re-compiling. Here is how:

1. Install Windows PoweShell

2. Open a PowerShell window, type powershell and hit enter. Notice there are 2 powershell.exe processes running. One is the parent and the other is the child. You are in the child process. Use process explorer to observe the 2 processes and write down the child process ID.

3. Build the .NET library solution. The .dll should reside in bin\Debug folder.

4. At powershell prompt, run PS > $loadResult = [Reflection.Assembly]::LoadFrom("D:\product\src\test\DataAccess\bin\Debug\Microsoft.IT.Product.Library.dll"). All the dll files referenced by Microsoft.IT.Product.Library.dll will also be loaded. Be aware that if you use [Reflection.Assembly]::LoadFile, the referenced dll files will NOT be loaded.

5. If you see no errors and $loadResult shows no errors, you are probably fine.

6. Command to instantiate your class: PS > $verify = New-Object Microsoft.IT.Product.Library.VerifyData("Data Source=.;Initial Catalog=EmailStore;Integrated Security=True"). Notice that VerifyData is the class name which takes a constructor of 1 string argument.

7. Run a unit test on a method: PS > $verify.EmailExists("testuser@msn.com"). If the constructor throws an exception, you will see the following:
New-Object : Exception calling ".ctor" with "1" argument(s): "Database EmailStore does not exist"

At line:1 char:21

+ $verify = New-Object <<<< Microsoft.IT.Product.Library.VerifyData("Data Source=.;Initial Catalog=EmailStore;Integrated Security=True")

8. In Visual Studio 2008, click on Debug->Attach to Process… You should be able to see 2 PowerShell processes. Choose the child process. Remember you call [Reflection.Assembly]::LoadFrom in the child powershell process.

9. After successfully attached to the correct process, you should be able to set break points at anywhere within your library. If the break point says “No symbols have been loaded for this document”, you probably have attached to the wrong powershell process.

10. You can use PowerShell to run all the methods in your library to unit test them in Visual Studio. When you are done testing, unfortunately, you can’t unload the assembly. You need to exit the Child PowerShell to unload the assembly. Otherwise, you will get error when building the solution: Unable to delete file. That is because the child PowerShell process is still holding the loaded assembly. Simply type exit at the child PowerShell prompt to unload it.

11. To test static method in the library, use [Microsoft.IT.Product.Library.VerifyData]::RandomString(4). RandomString is a static method that takes 1 int argument.