June 2007 Entries

SQL Server CE - Great for prototyping and testing

 

Background

Yesterday I put together a simple POC app for my team lead who needed to see Spring.NET + NHibernate in action (no, not the book) for a client.  Even though these days I'm using the Castle stack for most of my IoC/DI and mini-framework needs, it was interesting to see how far Spring.NET has come (probably more on that in future posts...) since I last used it a long time ago. 

I had a very basic scenario I focused on; adding and retrieving employees with a first and last name.  I started out with a basic web app, service and repository.  I just created a simple EmployeeService class that took in an implementation of IEmployeeRepository via its constructor.  I ended up creating 4 different implementations of an IEmployeeRepository, for testing out different scenarios and used Spring.NET to inject the appropriate one into my service. 

I started out with no help from Spring.NET or NHibernate regarding repositories and just created a simple in-memory repository implementation which just stored the data in a private IList<T>.  Simple stuff.  But I didn't want to really jump to a full blown SQL Server 2005 repository just yet.  I wanted something a bit more portable, but still with the ability to store the data in a relational database.

In Comes SQL Server CE

So I've been wanting to try SQL Server CE anyway, so I went ahead and downloaded it.  I created another repository implementation that just used plain ol' ADO.NET using the System.Data.SqlServerCe assembly.  As you can see, it's very easy to set up the SQL Server CE engine...

   1: SqlCeEngine engine = new SqlCeEngine("data source=temp.sdf");
   2: engine.CreateDatabase();

Then I created yet another repository implementation, this time one that leveraged NHibernate, which has built-in support for SQL Server CE.  Instead of setting up a config file for NHibernate, I took a chapter out of Ayende's Rhino Commons and configured NHibernate all from code...

   1: Hashtable nhProperties = new Hashtable();
   2: nhProperties.Add("hibernate.connection.driver_class", "NHibernate.Driver.SqlServerCeDriver");
   3: nhProperties.Add("hibernate.dialect", "NHibernate.Dialect.MsSqlCeDialect");
   4: nhProperties.Add("hibernate.connection.provider", "NHibernate.Connection.DriverConnectionProvider");
   5: nhProperties.Add("hibernate.connection.connection_string",
   6:                  string.Format("Data Source={0};", databaseFileName));
   7: nhProperties.Add("hibernate.show_sql", "true");
   8:  
   9: Configuration configuration = new Configuration();
  10: configuration.Properties = nhProperties;
  11: configuration.AddAssembly("SpringNHibernateApp.Domain");
  12:  
  13: ISessionFactory sessionactory = configuration.BuildSessionFactory();

This all worked great and I was very pleased at how quickly I was able to get all of this up and running.

Unexpected Problem

So all of my integration tests worked like a champ so I go and wire up Spring.NET to use one of my new SQL Server CE enabled repositories and fire up my web app and get a nice little YSOD with this...

"SQL Server Compact Edition is not intended for ASP.NET development"

Seemed a little strange to me, but Steve Lasker tries to explain why.  Luckily, it's easy enough to workaround.  Just place this line of code before any code that starts mucking around with SQL Server CE...

   1: AppDomain.CurrentDomain.SetData("SQLServerCompactEditionUnderWebHosting", true);

Anyway, guess that's it for now. 

ReSharper 3.0 - Like a kid in a candy store again

 

When I first started using ReSharper a couple years ago and with each subsequent release, I've had a lot of fun just exploring all of those "little" features that sometimes go unnoticed, but yet, can greatly increase your productivity in Visual Studio.  With the latest 3.0 release, I'm in that mode again.  I'm finding many more cool "little" features that just make my life easier.  For instance, here's just one example...

Basic namespace/folder maintenance

Being a bit picky about project/code organization, I'm a stickler for good folder structures and keeping the namespaces in sync.  In the past when I've needed to move a class to a new folder/namespace I'd go through the following steps:

  • F6 to show ReSharper's very nice Rename dialog
  • Type in the new namespace for the class
  • Create the folder in the solution explorer
  • Cut and paste the file from the solution explorer into the new folder

Very straightforward and fast.  This is one of those organizational steps that you may think cannot be improved upon.  But just leave it to JetBrains...

Now, thanks to ReSharper 3.0, all I have to do is this:

  • Create the folder in the solution explorer
  • Cut and paste the file from the solution explorer into the new folder
  • F12 to the nice new warning that ReSharper gives me...

resharper30_namespace_filepath_warning

  • Alt-Enter to have ReSharper automatically fix it for me

resharper30_namespace_filepath_correcting

The key thing about this is that I don't have to actually type the namespace anymore.  May seem small, but many of these "little" features combined with each other can make you much more productive in your development efforts.

Off to discover some more candy...  :)

Minor change (bug?) in file templates feature of ReSharper 3.0

 

Notice anything wrong with this?

resharper30_file_template_incorrect

That "File Template 5" is suppose to say "Class" instead.  I recently upgraded to ReSharper 3.0 from 2.5, and of course brought along all of my ReSharper template libraries that I've built up.  One of the things I did for my file templates when I created them was put accessibility shortcuts into the names using ampersands (&) like...

resharper30_file_template_with_ampersand

That way I always knew that, for example, doing an Alt-R-N-C would create me a new class and Alt-R-N-I would create me a new interface, etc.  But ReSharper 3.0 doesn't seem to like those ampersands anymore.  So removing them from the file template name fixes the problem and what ReSharper will now do, that it didn't do in the past, is automatically assign accessibility shortcuts to the file templates in your quick access list.

resharper30_file_template_without_ampersand

resharper30_file_template_new_behavior

In the end, I'm not sure whether this is a bug or feature, but nevertheless, something to keep in mind if you're a heavy user of the keyboard and the file templating features of ReSharper.

Preliminary thoughts on TDD with MSTest in Orcas

 

Naysawn, the PM for MSTest, asked that I take a look at the new unit testing features of Orcas, after he read my thoughts on the (sad) current state of MSTest.  Unfortunately, I haven't yet had a chance to actually fire up the Orcas VPC to play with it, but Naysawn wrote up a couple of posts describing some of the new features coming to MSTest in Orcas.  So I figured I'd post some initial feedback on his posts as it relates to TDD...

From Naysawn's First Post (with my comments below each item):

1 – Better Execution Times

Definitely a long time coming.  Speed is a big thing to us serious TDD practitioners.  Rapid feedback loops are key to staying productive using TDD.

2 – Run Tests

Hmm, sounds an awful lot like another tool of which I'm a huge fan; Jamie's TestDriven.NET.  Of course Microsoft doesn't seem to be too much of a fan, but I'm not even getting into that mess in this post.  Bottom line is that I've been using TestDriven.NET with Ctrl-T bound to the exact same commands Naysawn is talking about.  So of course having this feature in MSTest is a good thing.

3 – Short Cut Keys to Run Tests

Being a serious keyboard junkie, this of course would be pretty important to me.  Nuff said...

4 – Disable Deployment

This one is a biggie for me and probably would be one of my biggest complaints about the current implementation of MSTest.  It not only tremendously slows down the testing process in general, but for unsuspecting developers (hmm, as opposed to suspicious developers?  :P  ), it can take up a huge amount of space over time.  During some past engagements when trying to mentor TDD to folks using VSTS/MSTest, a couple months went by and they were wondering why they were running low on hard drive space.  For a decent size application, doing a test run every 5-10 minutes, 5 days a week for a couple months can eat up a ton of space.  Shadow copying is a decent idea and I understand what they were trying to accomplish, but at the very least, an option should exist to disable it.

5 – Inheritance of Tests

This is another important one for me.  I've run into quite a few situations where test inheritance really leads to more maintainable tests and can cut down on the set up and customization of a suite of similar test fixtures.  For instance, DB integration tests, where you need to refresh the database between tests, but you also need to override certain steps for customization of individual test fixtures.  Of course favoring composition over inheritance is still preferrable, even in unit test code, but sometimes a simple base test class is simply all you need.

6 – Directly go to the Point of Failure

I actually really like the sound of this one (even though ReSharper has had something very similar for a while now).  Just so long as I don't have to move my hands all the way over to my mouse to jump to the stack trace.  It sounds like a keyboard shortcut could be wired up for that though, so sounds good to me.   

From Naysawn's Second Post (with my comments below each item):

Gaining Access to Private Code under test

I can't say I'm all that excited about this one because a) it starts sliding down that slippery slope of generating unit tests (more on that next) and b) frankly, I tend to not keep too many private methods around.  Some of you may gasp at that, but I like to look for opportunities to extract logic out of private methods into separate public/internal classes hidden behind an interface that can be injected into the class under test.  I won't get too much into that right now, but let's just say it can really make code more extensible.  I like how Scott Bellware phrased it in his Seams, Not Components post.  In the end, I guess having the ability to test private methods may have a small place, but ideally your classes and methods would be small enough to be driven and tested through its public interface using private methods as minor support if needed (i.e. readability, etc.).

Generating Unit Tests

Repeat after me.  If I'm generating my unit tests, I'm not practicing Test-First Development.  Hope that's not too harsh, but no matter how you slice it, you can't claim to be driving your code design through tests, if you're generating your unit tests from existing code.  Sure, I've heard folks say they like to stub out their interfaces/classes first and then generate their unit tests stubs from that.  IMO, you're tackling too much of the problem at once with that approach.  If you're really trying to leverage TDD to help you design your code, then a lot of the time, you don't even know what your interfaces/classes are going to look like until you see them from the client's perspective.  And that is best done from within a unit test where you can express exactly how you want clients of your code to use the public API.  It can't be stated enough that TDD is supposed to be primarily a design tool.

Support for Device Projects

Having never done any work on embedded devices, can't say much about this one.  Although it is nice to know that it will be supported.

Automatic Cleanup of Test Results and Their Associated Deployments

I pretty much covered this in the #4 item above regarding the ability to disable deployments.  Again, nice to see some flexibility come to this area of the product.

I definitely think this is a pretty large leap forward for MSTest and I'm happy to see Naysawn and the developer teams at Microsoft reaching out to the community more and more, and even more important, actually incorporating our feedback into the products.  Big kudos for that...

With that said, as Jay Flowers points out, you'd be hard pressed to find anything better than MbUnit + TestDriven.NET + ReSharper right now.  And frankly, I don't really see that situation changing much even after Orcas is released.  However, for those great many of organizations that have chosen or will end up choosing VSTS/MSTest (mostly for the wrong reasons, in my experience), these new features will bring them a little bit closer to the current ideal tools for TDD.

Yet another reason to practice TDD

 

Things have been a little slow on the blog lately because this week is the start of a new job/company for me.  I'm still getting a feel for things and of course one of the first things I'm trying to get folks interested in is TDD.  I have a usual list of advantages and points that I use for getting across to folks the benefits of practicing TDD.  Most of which center around the fact that TDD is primarily a design tool, and the fact that you get a nice set of automated regression tests is just a nice side effect.  TDD is not about testing!

But today, after looking at some existing code, I thought of another example that does explain one way in which the "Test" part of TDD is very beneficial.

(For you fellow experienced TDD practitioners, this will be very obvious to you.  So this is mainly for those who are still struggling with "why do I need TDD/Unit Testing?"...)

Non TDD/Unit Testing Approach

Let's assume for a sec that you're not using TDD, and not even TAD (Test-After Development).  A typical set of steps to write a piece of code might be:

  1. Look at the requirements/use case/user story to figure out what feature needs to be implemented
  2. Use a modeling tool (or even better, a whiteboard) to design what you're getting ready to code
  3. Write the code as you think it should be (hopefully not generated, but that's a whole 'nother discussion)
  4. Perform a series of manual steps to verify that your code works
  5. Repeat 2 & 3 until your manual testing steps have verified the code works as you expect

Now, ask yourself a few questions:

  1. "What is my confidence level that changes to this code by me won't introduce bugs?"
  2. "What is my confidence level that changes to this code by others won't introduce bugs?"
  3. "How long is it going to take to test future changes in this code?"

Chances are, you may have a fairly high confidence level that you won't introduce bugs since you wrote the code initially (although that is faulty logic as well).  But what if someone else needs to make changes to that code?  You're probably not all that confident now.  Because you know that in order to verify this piece code, you had to run a series of manual steps (probably in different variations) to verify it works as expected.  And if you didn't document those manual steps for anyone else, well, you can see where I'm going with this.

But let's just say you have been a good little developer and you have documented the manual steps needed to verify that a particular piece of code works.  The time it's going to take to go through those manual steps multiple times is probably not going to be very fast, and will soon become very tedious.  And how often do you think folks are going to try and improve their design with refactoring if they have to run through a series of tedious manual steps just to verify they didn't break anything?!?  Probably never!

TAD (Test-After Development) / Standard Unit Testing Approach

Contrast that with an approach where you would write unit tests after you implemented the code to automate the steps needed to verify its result. 

  1. Look at the requirements/use case/user story to figure out what feature needs to be implemented
  2. Use a modeling tool (or even better, a whiteboard) to design what you're getting ready to code
  3. Write the code as you think it should be (hopefully not generated, but that's a whole 'nother discussion)
  4. Write unit test(s) that verify the code works as you expect
  5. Fix your code if necessary and re-run your (hopefully fast) unit tests until everything is verified

Now this is definitely "better than nothing", as they say.  But you'll probably find that writing simple unit tests for code that's already been written, turns out to not be so simple in a lot of cases.  The reason behind this is that the code probably wasn't written with testability in mind and is tightly coupled with the rest of the system.  This usually equates to really complex set up code needed for your unit tests to run correctly.  And at that point your tests are probably nothing short of an end to end integration test.  Integration tests definitely have their place, but not during code design.

But this is at least better in the fact that you have a set of automated tests that can be run (hopefully at any time) to verify that any changes to this code are still verified.

TDD (Test-Driven Design/Development) Approach

As you can probably guess, this is the approach I prefer for all of my development. 

  1. Look at the requirements/use case/user story to figure out what feature needs to be implemented
  2. Use a whiteboard (if necessary) to get a very rough idea of the interaction the new code will need with the rest of the system
  3. Write a unit test (think executable specification), mocking out any dependencies, if necessary
  4. Get the test to compile and pass
  5. Refactor to remove duplication and improve design
  6. Repeat 3-5 until the feature is implemented

I usually find that making changes to code that was implemented using TDD is a joy.  The tests are likely to run very fast, since they're only testing a small block of code without hitting a database or some service and the code's coupling to other parts of the system is probably pretty low.  Now my confidence level in making changes is very high, because I have that safety net of executable specifications that verify the feature is working as expected.  And even better, they are repeatable and can be run at any time.

Conclusion

Use those CPU cycles for what they're good at... automation!  One of the biggest time savers is automating as much of your tedious work as possible.  Testing and deployment are prime candidates for automation.

(I realize that my duplication of the list of steps in each section of this post, with slight modifications, clearly violates the DRY principle.  Perhaps I could have introduced the Template Method pattern to consolidate the common items or a sprinkle of the Strategy pat...  ok, I'm getting carried away...  hehe...)

<kill processName="peskyLittleProcess" />

 

For a second time now, I've found myself needing to kill processes in my automated build scripts, so that was enough for me to automate it and wrap it up in a custom NAnt task.  The first time I needed it, I just embedded the C# code inside a NAnt script block, but using it as "real" NAnt task is much nicer.  And, perhaps I overlooked it, but I did not see a task in the set of NAnt or NAntContrib tasks to do this kind of simple operation and Google didn't turn up anything either.  So I just banged it out real quick...

Here's how it can be used:

   1: <loadtasks assembly="pathToToolsFolder\joeyDotNet.Commons.dll" />
   2: <kill processName="w3wp" />

 

And for those that are interested, here's the code for the task, although it's really quite simple: 

   1: /// <summary>
   2: /// Looks for processes with specified name and kills them
   3: /// </summary>
   4: [TaskName("kill")]
   5: public class KillTask : Task
   6: {
   7:     private string processName;
   8:  
   9:     [TaskAttribute("processName", Required = true), StringValidator(AllowEmpty = false)]
  10:     public string ProcessName
  11:     {
  12:         get { return processName; }
  13:         set { processName = value; }
  14:     }
  15:  
  16:     protected override void ExecuteTask()
  17:     {
  18:         Log(Level.Info, "Looking for processes named {0}...", processName);
  19:         foreach (Process process in Process.GetProcessesByName(processName))
  20:         {
  21:             Log(Level.Info, "Found process named {0}, killing...", processName);
  22:             process.Kill();
  23:         }
  24:     }
  25: }

 

Disclaimer:  I take no responsibility for what happens if try to pass in a process name like "System" or "winlogon" or "explorer".   So please use wisely...  :)

As usual, you can grab the source code yourself from the repository.

I Thought These Days Were Over...

 

movielink_noff

I mean, come on Movielink.  Isn't it clear by now that IE is not the only kid on the block anymore?  Is your html markup and css *that* bad that you won't even *attempt* to display it in Firefox?  Maybe a tiny kudos for at least telling people about the IE Tab extension, which is also very handy when doing intranet-based IE-only development.  

Otherwise, a major "thumbs down" on this obvious lack of even attempting to adhere to web standards.

What does maintainability mean to you?

 

Sometimes in my discussions with other developers, we have to agree to disagree on certain things.  One recent topic was that of maintainability, in regards to the size of classes/methods and project structures. 

I find it curious that some developers believe a single 4000 line class with single methods being hundreds of lines long is actually more maintainable than say, 40 classes with ~100 lines each and methods around 7-10 lines long.  Of course this is just a vague example, but you get my point.  Being pretty open to other ideas/views, I just simply can't bring myself to understand this (even though long ago that's how I used to think!). 

Chances are that a single class consisting of thousands of lines of code is in major violation of the Single Responsibility Principle (SRP) and, with no unit tests, makes future changes without introducing bugs near impossible. 

Interestingly, I also find that developers who prefer the "put everything in Logic.cs" approach (Yes, I've actually seen this exact filename in a production system), seem to rely very heavily on the debugger.  That's really a shame, because there are much better and faster techniques available to discover bugs and understand how a particular class works.

Take unit testing, for example.  Yes, I'm just talking about plain old state-based unit testing, even if you don't understand the huge benefits of TDD/BDD (which is a bigger shame).  But even unit tests alone can help break your reliance on the debugger.  One of the best things you can do when finding/fixing bugs is write a failing unit test that exposes the bug.  It's so much faster to run a simple unit test than to step through a debugger, especially when your classes are gigantic.  And, when's the last time your debugger acted as a regression test for you?  (I'll take your silence as "never"...)

Another interesting observation I've had about large classes and methods is that they rarely have automated tests for them.  This seems very strange to me.  My confidence level in code like this, without automated tests, is extremely low.  Nevertheless, I've occasionally had to work with systems like this.  And I usually start by writing just a few unit tests and work from there.  But that won't last long until you realize you've got some serious refactoring to do because the code is so tightly coupled to everything else.  This can make writing simple unit tests very hard.

The usual complaint I hear about keeping classes/methods small is Class/Method Explosion.  Indeed, you probably will have many more classes (and hopefully interfaces) and methods, but with proper naming and location, you can pretty easily understand the flow of logic.  And with unit tests that have descriptive names, it becomes that much easier. 

Simple Example:  If you had to change the calculation of a gold customer's discount, wouldn't it be much easier to find in a GoldCustomerDiscountSpecification rather than on line 1238 of the OrderService class?  Oh, and did you remember to change it on line 854 in the CustomerService class as well?  (I rest my case...)

I'm not even going to talk about SProcs that are a 1000 lines long, which sadly, I've also seen in production systems.  Eeek!

So I guess I'd just encourage folks to look for ways to separate responsibilities in your code and use unit tests (and even better TDD) to aid you in your efforts.  And free yourself from the debugger!

Castle MonoRail - Response To Comments/Ramblings

 

Billy has decided to move forward with using MonoRail on one of his current projects.  As I was writing the comment on his post to respond to some other folks' comments, I decided it was getting too long and perhaps I should must make it a post on its own.

Billy stated that his main concern for moving to MonoRail is losing support for 3rd party control suites like telerik.  To which a commenter said:

"You don't have to abandon third-party controls like telerik - just use the WebFormsViewEngine."

One of the issues with using the WebFormsViewEngine, AFAIK, is that you lose the true MVC-ness of what MonoRail is trying to accomplish for you. The whole idea behind MVC, is that the Controller is the first point of contact for a request, not the View. But when using web forms, you really can't do that in a nice way (as Ayende points out), since the web form (i.e. ASPX) has to be the first point of contact. Then the View has to implement a special IControllerAware interface and delegate requests back to the controller. And then... we're back to MVP again. 

Of course, MVP is a good pattern in its own right.  I've successfully used it for years of, dare I say, "classic" web forms development in ASP.NET.  But I find the separation and flexibility of a true MVC framework like MonoRail, solves the problem in a much simpler way.  Sure you don't have the bloat, ah hem, *features* like page lifecycles and viewstate.  But I still think not having to worry about that kind of stuff is a good thing.

I've now used Castle MonoRail in 2 projects and the bottom line for me is that frameworks like MonoRail (and RoR, even though I've yet to have had the pleasure of using it) are making web development fun *and* productive again.  I haven't really missed the "server controls" aspect of web forms much at all. 

In fact, MonoRail better allows me to develop my presentation/UI layer in the same fashion as I already develop everything else underneath.  By using an incremental approach, I can build what I need in a simple fashion and harvest reusable components as necessary. 

I've experienced the pain of having to utilize 3rd party ASP.NET controls and it's definitely not all chocolates and roses.  Often, in the time you can spend hunting down some nasty bug/behavior in a 3rd party control (that probably does more than you need in the first place) you could've leveraged something simpler, even your own solution if needed. 

Now I'm most definitely not advocating NIH, but if you can be more productive and deliver more early business value by creating your own solution or extending an existing framework/component, then I would just consider that to be good judgement.

Anyway, I could probably go on and on, but guess that's enough for now.

Oh, almost forgot the <you MUST go download ReSharper right now, even the 3.0 Beta> statement...  :P