Extreme JS

JS Greenwood's WebLog on architecture, .NET, processes, and life...

November 2004 - Posts

XPStoryStudio site up: www.xpstorystudio.com

Having registered the site a couple of weeks ago, I've got round to putting together and uploading a couple of web-pages for XPStoryStudio, in preparation for it's release in the very near future.  All that's left to do is put some installation documentation together and generate the finished installer package.  In addition to posting major news about its release, etc. here, all the details will be published on XPStoryStudio's site:

www.xpstorystudio.com

Posted: Nov 28 2004, 08:36 PM by jsgreenwood | with 1 comment(s)
Filed under:
When TDD Goes Bad #1

Although Test Driven Development (TDD) is one of the greatest steps forwards in software engineering, especially when combined with modern languages and testing frameworks (i.e. xUnit), there's a definite anti-pattern lurking in there - Test Oriented Development.

At its most basic level level, writing tests is done for one reason and one reason only.  It's not about ensuring you meet requirements, it's not to have a repeatable means of knowing the code functions properly after changes, and it's not to aid design.  The key reason for writing tests is the same as everything else in software development - to make the company commisioning the software more profitable.  So, the justification for TDD is based upon the premise that, in the long run, writing tests will save the company money on down time, effort in re-workings, and so on - but these are just implementation details of the underlying principle.  Now, although most developers that do TDD understand the long-term payback view of the approach, I'd question how many actually consider the value of each test or set of tests that are being developed.

Using an agile methodology, tying the (acceptance) tests to the stories is fairly simple, seemingly giving visibility of the value of tests.  But, given that many verbal tests are quite open ended, how do you know how much testing is enough?  The test may be stated as "When I enter the correct data, but there is a connectivity issue, I will see error message X".  A verbally described test such as this can have a hundred different programmatic tests implemented - simulating standard firewall issues, XML-firewall issues, web servers being down, latency in connections, time-outs, corruption of data, etc.  There is no immediately visible answer to "how much testing is enough?" in such a scenario.  This is even worse with unit tests, where they aren't likely to be defined formally (verbally) at all, and are largely up to how meticulous a developer is.

Added to the lack of metric is the fact that the developer is concentrating on testing before "coding" - the primary function is hence the development of tests, leading to a situation of "test-oriented development".  This is where the production of tests becomes the overriding concern and output of a team, with the development of required functionality being secondary.  When this occurs, the design, quality, and scope of the tests all become greater than that of the system actaully being created.  As the development of tests follows the law of diminishing returns principle, beyond a point, each additional test you write for a certain circumstance adds only more and more marginal increases in quality.  Eventually, you will reach a point where there will never be a point in the lifetime of the system where the development of the tests achieves ROI.  Basically, the development of tests becomes counter-productive to the aims of the business.  This is compounded by the Heisinger's Uncertainty Principle-like facet of TDD - it's alteration of the design of the code it's testing.  But that's a subject for another post in the next few days...

Avoiding test-oriented development can be quite difficult - changing a developer's mindset to take on TDD is difficult enough to start with, trying to then amend that to temper the creation of tests goes back on that principle to some extent.  My current thinking on this is that, along with acceptance tests and development tasks, a separate list of requirements needs creating for each story - a list of required unit tests.  Rather than just estimate the effort required to complete a story point in its entirety, the effort required for each unit test (and its value in pound-notes/dollar-bills) should also be calculated to some extent. Each test is then subject to the same cost-benefit analysis and prioritisation as stories at a higher level.  The task of doing this should also help developers to consider the reason for creating a test; how realistic/contrived the situation it's testing is, how better the effort could be expended, and finally, help remind them what they're actually trying to achieve at a less programmatic level.  If this seems like too much effort, then an alternative may be to look at the ratio of time that is to be spent on writing tests to that of the production code itself for a given story-point to ensure that the focus isn't shifting from the system to the tests.

Posted: Nov 26 2004, 12:58 AM by jsgreenwood | with 22 comment(s)
Filed under:
Coordinating Enterprise Website Development in .NET

One of the favourite Enterprise development strategies for .NET websites I've come up with is that of splitting the website into logical areas along functional- (and naturally change-) boundaries; having separate areas of the site developed as separate ASP.NET controls.  I'm not talking small-scale controls like "Address entry" here, I'm talking entire 5+ page application processes as a single control (that might itself comprise further controls).  This model works well for all kinds of large organisations - an online e-commerce site could have separate basket, checkout-process, and product-search controls, for instance, each of which would be aligned against a set of services that they're consuming (in an SOA).  The current enterprise-in-question is a bank, which fits this model better than most other sites I've come across due to the sheer amount of functionality necessary on the website, and its diversity.  Application forms alone constitue a raft of controls:

  • Mortgage applications
  • Credit card applications
  • Personal loan applications
  • Motor insurance applications
  • Etc.

My view on coordinating this has been, for some time, to have separate teams working on each "control", basically becoming product teams that deliver a black-box control to one overall "site" team.  It is then this team's responsibility for plugging all of the controls into the main site, maintaining all the links between areas, etc.  There are several benefits to implementing an enterprise-class site this way:

  • It gives a simple way of logically breaking-down/grouping a large number of development staff
  • It supports concurrent development on multiple parts of the site.  Because the controls don't know about each other, there's no risk of them linking to one another and dependencies being created.  This allows for varying rates of change in different areas, and doesn't predicate large-scale upgrades when a new version of some base functionality becomes available
  • It provides a black-box component that allows for alternative internal implementations, for instance migrating from an HTML based UI to a Macromedia Flash one, and eventually to a Longhorn one.
  • It matches a model of having multiple levels of continuous integration, rather than having a single-level uber-integration that becomes unwieldy

That's the good news - a paradigm for developing enterprise websites that theoretically has few drawbacks.  Moving on to the implementation is where the bad news begins...

In .NET, these controls could either be developed as user controls (.ascx files), or as custom controls (.cs files).  The advantage of the former is the speed of development, and close integration with UI designers - developers can work in "HTML view".  The latter involves writing all content as controls.  A short example of this is as follows:

Web control implementation:
  <h1>Hello World</h1>
  <asp:TextBox id=txt runat=server />

Custom control implementation:
  Literal literal = new Literal();
  literal.Text = "<h1>Hello World</h1>";
  Page.Controls.Add(literal);
  TextBox txt = new TextBox();
  txt.Id = "txt";
  Page.Controls.Add(txt);

Although possible, developing a graphically compelling site using the second method is torturous, so I've discounted it as an option.  I also don't want control teams to deliver an editable ASCX control to the site team - it would be prone to editing, etc. and not as much of a "boxed product".  There is an alternative, however.  Whenever .NET renders a web page that makes use of a user control, it converts the first code example into the second internally.  In Visual Studio .NET 2002 and Visual Studio .NET 2003, this process is largely invisible, and only happens when the page is requested.  Visual Studio .NET 2005 ("Whidbey") changes this, though, allowing for pre-compilation of websites into Assemblies (DLLs).

So, my long-term plan was to have each team develop a control in a separate VS.NET 2005 project, pre-compile the output when they're ready to release, and then just hand the Assembly over to the "site" team to use just like any other class library.  Having spent many, many hours over the last week poking and prodding the aspnet_compiler.exe tool, rewriting it from scratch, attempting reflection on the System.Web.Compilation namespace, and even disassembling most of the System.Web assembly, I'm getting close to giving up.  Rather than creating one sensibly named assembly for the whole project, the compiler creates multiple randomly named assemblies - usually one for each control/page (although it sometimes puts several together).  After recreating the aspnet_compiler tool from scratch, and extending it to sift through these files, pull out just the assemblies, give them new file names based on the controls they contain, etc. I thought I was getting somewhere.  Now the problem is that if one of these controls uses another from the same project, it will be given a reference to the random 8-letter assembly name (and matching internal module name).  I've yet to see if any internal assembly hacking can rectify this.

None of this would be necessary if Microsoft hadn't specifically made the majority of the System.Web.Compilation namespace private/internal, presumably in an attempt to make it difficult for other people to develop competing tools, etc.  The most infuriating part of this is that, in theory, you can access all of the System.* functionality through reflection, whether its supposedly private or publicly visible.  Additionally, tools like Salamander and Reflector make it possible to decompile vast swathes of the system classes back into C#.  So Microsoft aren't really "protecting" anything, they're just making it painful to come up with enterprise class solutions.

The point to this post?

  • Here's a model for enterprise web-site development that works, even if it DOES mean handing over controls that aren't totally black-boxed.
  • If anyone is a System.Web.Compilation guru and fancies helping out on creating a tool to enable this, please mail me
  • If anyone thinks that Microsoft should make it easier to compile source code, please mail them
More Posts