Geek Noise
Rants, rambles, news and notes by Peter Provost
27

Replacing ExpectedException in NUnit 2.4

Friday, 27 June 2008 06:14 by Peter Provost

Jim Newkirk, Brad Wilson and I have been in agreement about the evils of ExpectedException for a long time. When Jim and Brad wrote xUnit.net, in fact, they left it out and opted instead for a new Throws method that lets you be a lot more precise about what and when you are testing the exception.

But NUnit 2.4.x doesn't have this feature (2.5 will). Fear not! Jim has written a nice little sample of the Throws method for NUnit 2.4.x that provides this same experience in his new post Replacing ExpectedException in NUnit.

If you are using NUnit today, I would really suggest you read the post and consider changing the way you test exceptions in your unit tests.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:  
Categories:   Agile Software Development
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed
10

xUnit.net 1.0 RC3 Released Today

Thursday, 10 April 2008 05:23 by Peter Provost

See Brad Wilson's post: http://bradwilson.typepad.com/blog/2008/04/xunitnet-10-rc3.html

Technorati Tags: ,,,

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
12

TDD with PowerShell - Mocking Things

Monday, 12 November 2007 02:04 by Peter Provost

Recently, I’ve been dabbling with doing TDD in PowerShell. I think there may be a TDD Framework brewing in my head, but at this point I haven't done enough to figure out what such a framework would look like. Often I find that the functions I’m writing depend heavily on built-in cmdlets and BCL types and there can be issues mocking them out when the underlying .NET type isn’t easy to mock out. This isn’t so much an issue with PS as it is an issue with .NET, but since PS is very close to the edge of the world (where the code touches the user), it can be hard to mock.

That said, as with most dynamic scripting evnironments, you can mock out a lot of things. Suppose you want to test a function that depends on get-childitem. Because functions evaluate before cmdlets, you can actually replace it by defining a function with that name:

function get-childitem() 
{ 
return @()
} 

Now you have a naked stub get-childitem that returns an empty array. All is good so far. Next you need a gci that returns a single FileInfoObject and for your test you want to have the “archive” bit set on this file. You try to create a new replacement function for get-childitem:

function get-childitem() 
{ 
$fi = new-object System.IO.FileInfo(“bogus.txt”) 
$fi.Attributes = [System.IO.FileAttributes]::Archive 
} 

But at this point you discover that you can’t set the Archive bit, because the file doesn’t exist.

This is actually a common problem we run into when we TDD up against another API that isn’t mock friendly. In an OO language like C#, I will typically wrap it up in another class & interface that I own and then mock out the interface for my code. This is do-able in PS, but a little more complicated because you may have to implement a fair amount of extra code to create and return a PSObject that has the interface you expect to find in your calling code. (This code can be a lot smaller, but less clear if you want… I opted for clarity):

function get-childitem() 
{ 
$fi = new-object PSObject 
$getter = { return [System.IO.FileAttributes]::Archive } 
Add-member –inputObject $fi –memberType ScriptProperty –name Attributes –value $getter $secondValue $setter 
Return $fi
} 

The challenge with this approach is the amount of code it takes to mock out all of the parts that you need. For example, if you need the Mode script property that comes built in to PowerShell for DirectoryInfo and FileInfo, then you will have to add them to your mock. If you also need to support the setter for the Attributes property, then you will need to add that (and possibly a Note member to hold the data).

As with all mocking exercises, this gets complicated when interacting with real things and since PowerShell is really about interacting with real things, it is hard.

Enjoy!

Technorati Tags: , , ,

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
20

xUnit.net - Jim Newkirk's New Unit Testing Framework

Thursday, 20 September 2007 09:01 by Peter Provost

I've been waiting for them to announce this for a while, but it has finally happened. Jim, Brad and co. have finally released and announced their new unit testing framework for .NET. Here's an excerpt from Jim's post (click thru to read the whole thing):

Announcing xUnit.net

In the 5 years since the release of NUnit 2.0, there have been millions of lines of code written using the various unit testing frameworks for .NET. About a year ago it became clear to myself and Brad Wilson that there were some very clear patterns of success (and failure) with the tools we were using for writing tests. Rather than repeating guidance about "do X" or "don't do Y", it seemed like it was the right time to reconsider the framework itself and see if we could codify some of those rules.

Additionally, the .NET framework itself has evolved a lot since its v1 release in early 2002. Being able to leverage some of the new framework features can help us write clearer tests.

Another aspect of change that we wanted to affect was bringing the testing framework more closely in line with the .NET platform. Many of the decisions we made, which we enumerate below, were driven by this desire. We wanted an architecture which is built specifically for programmer testing (specifically Test-Driven Development), which can also be very easily extended to support other kinds of testing (like automated acceptance tests).

Finally, there have been advances in other unit test library implementations that have not really surfaced in the .NET community.

While any one of these reasons would not necessarily have been sufficient to create a new testing framework, the combination of them all made us want to undertake a new project: xUnit.net.

Jim has been chatting about this for years with Brad Wilson, Scott Densmore, Brian Button, myself and many, many others in hallway chats, at conferences and via email and it has finally happened.

I can't wait to see what people think. Congrats Jim and team!

Currently rated 3.0 by 1 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
28

New Unit Testing Features in Orcas

Tuesday, 28 August 2007 05:23 by Peter Provost

A while back Naysawn Naderi has posted a series of write-ups of the upcoming features in Visual Studio Orcas (that I forgot to blog about) that are specifically to address the needs of TDD and developer-oriented testing. I was on the committee of people who helped advise their work in this area and while there is still a lot of work to do, they are doing some good stuff that should help:

  1. Better Execution Times
  2. Run Tests Context Menus
  3. Short cut keys to run tests (WOOT!)
  4. Disable the "test deployment" icki-ness
  5. Support for the Abstract Test Pattern via Test inheritance (boo!)
  6. Click thru to the point of failure

Yes, we all know these things should have been there in V1, but they weren't. And now we're trying to make it better.

Grats to Naysawn and team for helping move the ball along.

Technorati Tags: , ,

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
30

TestDriven.NET 2.0 Has Shipped!

Monday, 30 October 2006 07:15 by Peter Provost

Wow. After years of work and headaches, my good friend Jamie Casdale has just announced the version 2.0 RTM version of TestDriven.NET.

It has always had a great feature set:

  • Right-click and run the tests found in classes, fixtures, projects, solutions, etc.
  • Run in the debugger
  • Run w/ external runner
  • Test failures go to Output window and Task list
  • Double click on test failure and go straight to the failing test code
  • Configurable key bindings for even easier running of tests

And now adds some very cool new things:

  • Code coverage – NCover + Team Coverage
  • Reflector support – 'Go To Reflector' functionality available on the Code, Disassembly, Call Stack, Modules, Project References and Solution Explorer windows.
  • Repeat Test Run – Redo whatever test-run you did last

But I can't really do it justice, so check out Jamie's post. It has better descriptions, screenshots, and more.

Go get it! Come on... you know you want it.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
24

Slides and Code from Code Camp

Monday, 24 October 2005 06:45 by Peter Provost

Yesterday at Seattle Code Camp, I did four presentations, two with Brad Wilson and two by myself. During our talks, we promised to share the slides and code from our demos, so here you go.

  • Monad – The New Microsoft Command Shell
  • Dependency Injection – What, Why and How
    • Powerpoint (58 KB)
    • Sorry, but the code from this one isn’t available.
  • TDD GUI Using MVP (and the pair programming game)
  • Composite User Interface Application Block

I have lots of thank-yous that I want to share. Many thanks to the attendees. The talks were a lot of fun and I love it when the attendees involve themselves and ask lots of questions. Thanks to Ed Jezierski for providing some of the slides I used in the CAB talk and thanks to Adam Barr for sharing his Monad slides with me. Thanks to Chris Kinsman and Jason Mauer for putting on a great event. Finally thanks again to Brad for being a great co-presenter.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
18

Unit Testing Rules

Sunday, 18 September 2005 11:48 by Peter Provost

I was just sent this post by Michael Feathers where he asserts:

A test is not a unit test if:

  • It talks to the database
  • It communicates across the network
  • It touches the file system
  • It can't run at the same time as any of your other unit tests
  • You have to do special things to your environment (such as editing config files) to run it.

Tests that do these things aren't bad. Often they are worth writing, and they can be written in a unit test harness. However, it is important to be able to separate them from true unit tests so that we can keep a set of tests that we can run fast whenever we make our changes.

This is a very interesting set of rules and for the most part I agree with Michael. When I do TDD I try to avoid these things as much as possible. But when I find myself needing to break one of these "rules", I almost always end up doing the same thing.

I create a single minded little class that does that one thing. Then I test it to ensure that it does it. Then I walk away from it.

As an example, consider a business class that needs to pull some information from an XML file on the file system. That is what the customer requirement was. However, I would never even consider putting XML or file system logic in that business component. Instead I'll write a class that talks to the file system and returns some sort of domain model (not XML). I'm now free to test my business component using a mock of this persistence loader, completely in isolation of the file system.

I think Michael does the same thing. He continues:

That might sound a little severe, but it is medicine for a common problem. Generally, unit tests are supposed to be small, they test a method or the interaction of a couple of methods. When you pull the database, sockets, or file system access into your unit tests, they aren’t really about those methods any more; they are about the integration of your code with that other software. If you write code in a way which separates your logic from OS and vendor services, you not only get faster unit tests, you get a ‘binary chop’ that allows you to discover whether the problem is in your logic or in the things are you interfacing with. If all the unit tests pass but the other tests (the ones not using mocks) don’t, you are far closer to isolating the problem.

Frankly, we need both kinds of tests, but these "pure" unit tests are undervalued.

I guess the only part I don't really like is that distinction between other tests and pure unit tests (emphasis mine). I don't think it is safe to ignore these other tests and I don't know what to call them other than unit tests, so I'm hesitant to accept the part of Michael's post where he says, "A test is not a unit test if..."

I would much rather say this: "A unit test should try to avoid..." and then follow it with his five bullets.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
29

Unit Testing Events with Anonymous Delegates in .NET 2.0

Sunday, 29 May 2005 17:52 by Peter Provost

There has been a lot of discussion comparing anonymous delegates to closures and blocks in Ruby, so I’m not going to get into that whole thing…

What I want to talk about for a minute is how cool it is to use anonymous delegates to test that events on your classes fire as expected.

Suppose, for example, that you have a class like this:

public class MyContainerContainer
{
public event EventHandler<ItemAddedEventArgs> ItemAdded;
public void Add( object item )
{
// Store it in an internal list or something, then
// fire the event
if( ItemAdded != null )
ItemAdded( this, new ItemAddedEventArgs(item) );
}
}

Now before anonymous delegates, you would have had to introduce a private method in your test fixture to attach to the ItemAdded event. And as shown here, you probably would have had to introduce a private field to pass data between the event handler method and the test method. (Sure, you could have created a mock class to hold the state and the event handler, but that would have been even more code to read/parse/grok.)

[TestFixture]
public class ContainerMonitorFixture
{
private object addedItem = null;
[Test]
public void AddFiresAddedEventWithCorrectArgs()
{
MyContainer container = new MyContainer();
container.ItemAdded +=
new EventHandler<ItemAddedEventArgs>(this.ItemAdded);
object item = new object();
container.Add( item );
Assert.AreSame( item, this.addedItem );
}
private void ItemAdded( object sender, ItemAddedEventArgs e )
{
addedItem = e.AddedItem;
}
}

With anonymous delegates, you can now write very clear, very clean tests like this (forgive the strange line breaks—I had to add them to make it fit nicely on the page):

[TestFixture]
public class ContainerMonitorFixture
{
[Test]
public void AddFiresAddedEventWithCorrectArgs()
{
object expected = new object();
object actual = null;
MyContainer container = new MyContainer();
container.ItemAdded += delegate( object sender, 
ItemAddedEvent args e )
{
actual = e.AddedItem;
}
container.Add( expected );
Assert.AreSame( expected, actual );
}
}

There are a couple of cool things in this code:

  • The delegate can modify variables in the test method, outside the event handler itself
  • The entire test’s meaning is clearly stated within the test—you don’t have to look in some other method or class to see what’s happening
  • Because the entire test is self encapsulated, it is easier to move/copy/change should you need to do any refactoring to either the class under test or the test fixture itself.

Enjoy!

Now playing: Foo Fighters - Overdrive

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:   ,
Categories:   Technology
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed
26

TDD Webcast on Thursday

Tuesday, 26 April 2005 05:36 by Peter Provost

Brian Button, Scott Densmore, Brad Wilson and myself are putting on a webcast about TDD this Thursday. Here is a link to the webcast if you want to attend.

One thing to note: this was originally scheduled to be a talk by Jim Newkirk about TDD in VSTS, but he is unavailable so we are doing one on TDD in general. So the title and description are not really correct.

The title should be:

Test-Driven Development
A gentle introduction to TDD from a bunch of patterns & practices zealots.

If you are interested in hearing war stories from us, please come and listen in.

UPDATE: Apparently there is some confusion around the time. It is at 11:00am Pacific time. See you then!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:   ,
Categories:   Technology
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed