Shipping Software - A response to Joel Spolsky

Joel recently posted The Duct Tape Programmer which has received an enormous amount of buzz, both positive and negative. At work, I received emails telling me that the article is a must read, while receiving different emails flaming Joel. If you haven’t read it, I highly encourage you to do so. In short, it is about shipping software above all else. I have spent the evening catching up on blogs, many of which are just responses to Joel’s, so I felt I should jump on the bandwagon. »

Using Extension Methods to clean up Mocks (MoQ)

Mock’s can quickly become an ugly beast. They require lots of complex setup and verification. I have had good luck with using extension methods to simplify the complexity. Assume we have the following code to implement our data layer on top of some ReST API. public interface IWebClient { string DownloadString(string url); string UploadValues(string method, string address, NameValueCollection data); } public class WebClientWrapper : IWebClient { private WebClient client; public WebClientWrapper() { client = new WebClient(); } public string DownloadString(string url) { return client.DownloadString(url); } public string UploadValues(string method, string address, NameValueCollection data) { return Encoding.UTF8.GetString(client.UploadValues(address, method, data)); } } In the business/domain layer, we have a class that uses IWebClient to get some information from the API. »

Using Pipeline.Input for Powershell testing

Last week, I posted about how to unit test powershell, which I have been working with a little bit over the weekend. One thing I quickly realized was testing interaction with the pipeline is a must for Powershell. It’s pretty easy to do. Let’s start with the Get-Service cmdlet that ships with Powershell. If you load up reflector, you will see the follow class definition. [Cmdlet("Get", "Service", DefaultParameterSetName="Default")] public sealed class GetServiceCommand : MultipleServiceCommandBase { // Methods public GetServiceCommand(); protected override void ProcessRecord(); // Properties [Parameter(Position=0, ParameterSetName="Default", ValueFromPipelineByPropertyName=true, ValueFromPipeline=true), Alias(new string[] { "ServiceName" })] public string[] Name { get; set; } } Remembering the base test fixture from the previous post on TDD in Powershell, I can quickly write up a few tests that test a few different use cases of the get-service cmdlet with [Test] public void Get_Service_with_single_string_in_pipeline() { // "MySQL" | get-service var name = "MySQL"; var pipeline = Runspace.CreatePipeline(); pipeline.Input.Write(name); pipeline.Commands.Add("get-service"); var result = pipeline.Invoke(); AssertThatPipelineResultIsService(result, name); } [Test] public void Get_Service_with_single_object_in_pipeline_using_Name_property() { //New-Object PSObject | Add-Member NoteProperty Name "MySQL" -PassThru | get-service var name = "MySQL"; var pipeline = Runspace.CreatePipeline(); pipeline.Input.Write(new { Name = name }); pipeline.Commands.Add("get-service"); var result = pipeline.Invoke(); AssertThatPipelineResultIsService(result, name); } [Test] public void Get_Service_with_single_object_in_pipeline_using_ServiceName_property() { //New-Object PSObject | Add-Member NoteProperty ServiceName "MySQL" -PassThru | get-service var name = "MySQL"; var pipeline = Runspace.CreatePipeline(); pipeline.Input.Write(new { ServiceName = name }); pipeline.Commands.Add("get-service"); var result = pipeline.Invoke(); AssertThatPipelineResultIsService(result, name); } private void AssertThatPipelineResultIsService(Collection<psobject> result, string name) { Assert.That(result.Count == 1); Assert.That(result[0].BaseObject is ServiceController); Assert.That((result[0].BaseObject as ServiceController).ServiceName == name); } By using pipeline.Input.Write(), I can write to the pipeline before invoking commands. »

TDD with Powershell, from the client perspective

Is it possible? Yes, and it is actually relatively easy. The hardest part can be figuring out how to mock/stub out certain functionality so your testing small units as opposed to full acceptance testing. The line can get blurry, but I don’t really care. Testing is half the battle. But to be clear, the focus of my testing is to test how a snap-in is working. It sounds like an integration test, and maybe it is, but there is no reason you couldn’t test any powershell script using some of the steps outlined here. »

Database integration testing, Interested?

Testing database queries is super important, but not easy enough. It can be done, but usually you have to write custom test fixtures and spend too much time doing it. Every project needs to test database integration, so why isn’t there a library out there to make it easier? NDbUnit seems somewhat dead, and only works on a specific set of database providers. Even worse, it relies on a ton of XML setup, which I hate. »

They grow up so fast

A few days ago, a developer at work said something that made me cringe, “Every day we write more legacy code”. My first instinct was to reinstate our corporal punishment policy. Then he said something quite amazing that I didn’t expect, “Any code we are afraid to change, because it isn’t thoroughly tested, is legacy code.” I cried. Literally. Figuratively. I know he read this in Working Effectively with Legacy Code, but to really see him get the importance of testing is awesome. »

The Smell of Assertionless Tests

Today I found myself at a crossroads regarding testing. In my efforts to have pure unit tests, I had created tests with no assertions. Each test contained a mock object that verified multiple expectations, but no assertions. While each mock expectation could be thought of as an assertion, is it really a good idea to test the algorithm? I say no. The algorithm shouldn’t matter. The only thing that should matter is the input and output of each function. »