ASP.NET MVC not good for TDD?


Two days ago, Stephen Walther wrote a blog entry on his ASP.NET MVC site about how MVC is not conducive to TDD, as it does not properly support incremental design. If you missed Stephen’s blog entry, it is here. I disagree that MVC is an impedement to [test driven] design, based on what I think a reader might take away from Stephen’s blog entry.
 
Before getting into where I disagree with what a reader might take away from Stephen’s blog entry, I think I should start on what I agree with him on. MVC, when used from the controller down, does offer poor support for TDD, if you put the emphasis on Driven. If you start with a controller, it is difficult to work out an incremental design, as you end up having to take pretty large steps to refactor through some of the increments. Tiny steps are the key to proper refactoring.
 
Added comment 4/14/009: I am not sure if it was clear that I was talking about how readers might perceive Stephen (and how a friend, in particular, construed the article). I am not stating that Stephen was stating that MVC did not work for TDD, only that it was designed more for TAD (Test After Development) rather than TDD (Test Driven Development). Stephen’s comment made me realize what I had writen might not be clear enough.
 
What I disagree with in how I think the reader will perceive the discussion is it does not have to be this way. The entire issue can be avoided if one rethinks what an application is. That is the purpose of this blog entry.
 

Apps are not UI

I went to the Microsoft MVP Summit last month (If you are not aware what a Microsoft MVP is, click on Microsoft MVP for more information). As an experiment I asked what types of applications people were buliding. Here are the typical answers I got.
 
Windows Forms
Web Services
ASP.NET
ASP.NET MVC
WPF
Silverlight
C#
VB.NET
F#
 
Notice a trend? Most of the "app types" above are describing the UI technology, the rest are describing languages. None of the answers describe the application. Let’s take this a step further. Here are some ad titles I found on Dice this morning:
 
Senior WPF Developer
Silverlight Developer
Senior Software Engineer, WPF
Silverlight / WPF Web/UI Developer
 
One thing to notice here is eaach of these jobs are listed by recruiting companies, although I have seen some by actual companies. In reality, these companies want a .NET developer with {UI technology} experience, either mandatory or preferred, depending on the technology.
 
If we take it a step farther, and look at MSDN, we see that many of the developer centers are focused around UI technologies. I am least worried about this, as we, as developers/architects have to learn new technologies. What is worrysome is the world is buying into the concept that UI technology describes the type of application.
 
RULE #1: UI != Techology (or UI <> Technology for the VB devs)
 
This may seem minor, but focusing so heavily on UI has deeply impacted our designs. In general, it forces a top down design. And, when viewed from the top down, we start to see some TDD issues, like Stephen described.
 

Microsoft’s New Technologies

This is not a primer on new technology, and by new, I am talking everything in the past 8 years or so (since .NET Framework 1.0).
 
The majority of the focus has been on using technology to relieve us of our bad habits. In traditional ASP, we placed our code in the ASP file. A few developers learned some encapsulation of code by making include files with their ASP "libraries". Even fewer made the leap to encapsulating logic in VB COM libraries. There were plenty of reasons for not moving to truly layered (or 3-tier/n-tier solutions) including the famous DLL Hell. As an aside, specifying the GUID for the library and classes and using MTS made it so you could drop new library versions without DLL Hell, but it was not a practical solution for everyone.
 
Then came ASP.NET and we had SoC (Separation of Concerns). Well, soft of. What we really had was separation of tags and code, and with the first books on the market, you would not know we had gone this far. The earliest ASP.NET code looked something like this:
 

<% for (int i=0;i<collection.Length; i++) { %>
<tr>
<td>
<%= collection[i].Field1 %>
</td>
</tr>
<% } %>

 
Looks a lot like ASP with curly braces, right?
 
So, ASP.NET did not solve the SoC issue at all. But WPF did … or did it? Perhaps ASP.NET MVC? How many samples have you seen where the data access sits in the controller? Case closed.
 
Rule #2: You can’t solve process problems with technology.
 

Paradigm Shift

Since an application is not the UI, my first efforts at testing should not be on the UI layer. Instead, I should be focused on behavior. If I properly design an application, I should be able to switch out WPF, Silverlight, ASP.NET, ASP.NET AJAX, ASP.NET MVC, Windows Forms or even web services (ASMX or WCF) as a "user interface". Some may argue that WCF and web services do not belong here, as people do not use them, but a separate application is a user (if you are not sure, look at UML diagrams).

If my application is not my UI, I should start on my business libraries first. I should focus on the behavior underneath the hood. I should also focus on my models and ensure they are solid and fully tested. Does this mean I should not test my contollers? Not at all, but the controllers get tested in another increment in the evolution of the application.

To sum the last two paragraphs, if we focus on the real application, which is not the UI, we can incrementally test ALL of the Microsoft UI technologies without breaking the rules of good TDD. But it requires thinking of apps in terms other than the UI.

In my last two applications, I have start with the models. This is not a 100% rule, as there are apps I have worked on recently where behavior was the starting point and I worked on the business libraries first. But whether I focused on business or domain models first, I am able to easily increment my design through tests. This does not mean the UI is a second thought, as UI is very important to many clients. it does mean that UI does not drive the behavior decisions.

The most recent app I finished has 13 lines of code, other than the autogenerated stuff, in the UI layer. The UI is a console application, but I could just as easily create a windows service, windows forms app, WPF application, etc. without many changes in the lines of code. On a previous application, I had to move a windows forms application I built to the web. It took less than a day to reskin the application with ASP.NET (would have considered MVC, but there was a slight learning curve for the person who would maintain the application).

How long would it take you to rebuild your application from Windows Forms to ASP.NET or vice versa? If more than a few days after initial graphic design, you probably have too much business and/or data code in your UI layer.

Summary

I could go on, but I will have to save this for another day.

The point of this blog entry is to highlight one of the major impedements to good application design: Thinking of applications in terms of user interface technology. If this UI focus led to better user experiences, I might consider it a potentially good trade off, but it doesn’t. I see bad user interfaces from people who are "experts" in {your favorite UI technology here}. In fact, since the app is the UI technology, and not a "skin" on top of an app, I would argue that you are more likely to have bad user experiences with this focus. That is also a topic for another day.

We have an arsenal of great tools today. We have to learn to use the tools for the proper job. Silverlight is a great UI technology and can create a wonderful, and pretty, user experience. But Silverlight is not an application building technology. As an analogy, imagine using a hammer to put screws in the wall or a screwdriver to pound in nails.

Someday soon, I will follow up with some "random thoughts" on UI and how it is properly used, but I have used up my time for today.

Peace and Grace,
Greg

Advertisements

3 Responses to ASP.NET MVC not good for TDD?

  1. Stephen says:

    Greg, Interesting article! Great points about UI.I should emphasize that I did not mean to suggest or imply that ASP.NET MVC is not a great framework for Test-Driven Development. The goal of my blog post was to clarify that Test-After Development is not the same as Test-Driven Development. Test-Driven Development has the additional requirement of needing to support incremental design.I’ve been building a sample applications using the ASP.NET MVC framework — and I am taking a Test-Driven, incremental design approach. So far, I’ve been happy with my progress (the sample application is contained the final part of my ASP.NET MVC Unleashed book). — best, Stephen Walther

  2. Vladimir says:

    Greg,Thanks for the nice post. I think, for many people application still is something like UI, database, and calls to database made from UI 😦 MS and book authors were guilty in this too: how many examples and books immediately show how to write a complete application in "24 hours" by connecting to a database from ASP/code-behind, etc. and obtaining a dataset? Business logic then were something melted into table design and if statements…

  3. Gregory says:

    Stephen:I hope I did not come across as disagreeing with you. At the time I wrote my first book on .NET, yours was the only other book that actually seemed to realize there was something called code behind. I tried hard to frame it that the reader might get the wrong idea.Peace and Grace,Greg

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: