April 2006 - Posts
I always have a hard time to come up with good names for my unit tests. Dale H. Emery found an article by Brian Button called "TDD Defeats Programmer's Block—Film at 11." In which Brian, according to Dale, uses a certain pattern for test names: stimulus and result in context. Dale examined the test names used in the article to identify the pattern parts.
In my recent article I used “Pay_IncludingSalesBonus” as name for a test. This test determined whether the correct pay amount was being calculated for an employee which was granted to receive a sales bonus. Due to the line length for printing (great excuse) I decided for a shorter version of the actual name. The actual name was (according to the stimulus and result in context pattern).
Context: Sales bonus granted to employee.
Stimulus: Calculate pay amount to pay employee.
Result: Pay amount was calculated including the sales bonus.
I think this pattern is extremely useful when used deliberately. To quote Dale:
Using the context-stimulus-result scheme increases the value of tests as documentation. The resulting names make clear what specifically is being tested and under what specific conditions. This helps the reader to understand quickly what each test does, and what is covered by each set of tests.
Another benefit is that the context-stimulus-result naming scheme encourages you to clarify your thinking about each test. Each unit test establishes some set of starting conditions, or context. Each stimulates the system. Each compares the result to a desired result. In order to name these elements you will have to think about the specifics of each and clarify them well enough that you can describe each in a few words.
If you're having difficulty naming a test using this scheme, that may indicate a problem in your test. Perhaps the test is doing too much work, or your test suite is doing too little. For example, suppose you're testing software to manage bank accounts, and one test is called Withdrawal Test. We can tell from this name that the test tests the withdrawal feature in some way. But we don't know what specific aspects of withdrawals this test is testing.
Is this useful, comments?
Feeling a bit better now, a post straight from my backlog.
For research purpose only I’ve started a little project called NeoDsl. NeoDsl solves the error-prone and complex work to describe your domain model in the Torque XML schema format. The Neo code-generator generates all classes (on top of the Neo Framework) which contain all necessary information as described in the domain model XML file.
Below you’ll find an early screenshot of a custom graphical designer that uses the class diagram notation. Included are templates that use the pubs model created in the designer to generate entity classes and support classes’ source code that plug into the Neo Framework.
Click to enlarge
I doubt that this model has enough value to be really productive with it, since the model closely resembles UML which isn’t any abstracter then the code itself. I agree with Claudio that we need to push our models towards a level of abstraction that is significantly higher than the level at which code statements and classes are written.
The books Refactoring Databases : Evolutionary Database Design by Scott W. Ambler and Pramod J. Sadalage and Streamlined Object Modeling: Patterns, Rules, and Implementation by Jill Nicola, Mark Mayfield and Mike Abney arrived this morning. Great birthday presents :D
We embrace more and more agile practices in our project, the evolutionary database design stays behind. Perhaps the insights in Refactoring Databases will help us. Then lately, while reviewing an upcoming book and my work for one of our clients, I’ve started (re)thinking business rules regarding SO/A and a typical workflow integration scenario. I first need to redo the "Aha"! of object-modeling as Eric Torreborre commented in his customer review.
ps: Eric, Streamlined Object Modeling was tipped on the domain driven design mailing-list.
Today I received my Software Developer Network magazine 89, april 2006 featuring my article “Effectief Werken met Legacy Code & TypeMock.NET” (Dutch). In this article I present strategies for working effectively with legacy code, to pour legacy code in a test harness and how to extend it while preserving original behavior. Sounds interesting?
Since SDN was so kind to send me a couple of extra issue’s, can I persuade you to become an SDN member by sending you a trial copy (Dutch)? This issue will eventually become available here under Magazine/Nummer 89.
Since the weekend I’ve been suffering from fever, terrible muscle aches, sore throat, sneezing and thus been pinned down by this flu thing. Being bored to death I decided to spend some time reading the Vista documentation. While scanning the first draft of Designing with WPF I noticed the do’s and don’ts for custom controls. Takeaways are:
- Don’t use custom controls just for branding.
- Use custom controls for unusual behaviors that aren’t supported by the common controls.
- Don ’t assign nonstandard behaviors to the common controls. Use standard behaviors if you can, and custom controls only if you must.
- Don ’t underestimate the work required to use custom controls correctly.
I’ve helped writing custom controls for a couple of clients just for branding reasons, not the smartest thing to do.
Reduced generated lines of code by 30%
Support for partial classes
Support for generics
Support for nullable types
Neo comes in two parts: The actual framework, i.e. the classes with which the application developer works, and the Visual Studio.NET 2005 plug-in which is needed at build time. The plug-in requires the NeoClass.2005.vtl and NeoSupport.2005.vtl templates in order to generate classes which contain all necessary information; the application developer described in the domain model XML file. Earlier investments in Neo are protected, there are no changes been made to the domain model schema. Savings of 30% are achieved on the generated lines of code through the use of generics.
In Neo the Entity Object world and ADO.NET world are brought together by Composition.
This requires concrete entity classes to wrap the corresponding DataRow, and store the necessary plumbing code in its base class.
public class Author : AuthorBase
protected internal Author(DataRow aRow, ObjectContext aContext)
: base(aRow, aContext)
With partial classes, code can be added to the class without having to recreate the source file.
Visual Studio 2005 uses this approach when creating Windows Forms, Web Service wrapper code, and so on. Neo does generate the concrete entity partial class and an additional user partial class in a separate file.
public partial class Author
The user Author partial class is intended for the application developer for making changes. The final Author entity is the combination of both parts at compile time.
To-many relations are managed and exposed by typed collections (Publisher-to-TitleRelation-to-Title).
The generic ObjectList<T> and ObjectRelation<T> collection classes replace the ObjectCollectionBase and ObjectRelationBase framework classes to provide type safety without having to generate additional relation classes.
Handling null values for value types required the application developer to override HandleNullValueForProperty, and provide default values. This requirement is rendered obsolete by the use of nullable types. A nullable type can represent the normal range of values for its underlying value type, plus an additional null value.
public virtual System.Decimal? Price
HandleNullValueForProperty is not supported in Neo2005 Preview.
In Neo 1.x the following code would throw an InvalidDbNullException exception. Since Royalty is a nullable type the code behaves accordingly.
title.Row["royalty"] = DBNull.Value;
For those who can’t wait to give the Neo2005 a try, drop me a line.
.NET 2.0 support for Neo is coming along. I finished my work on generics and partial classes, and just started working on support for nullable types. This morning I spoke with Dick about all the cool stuff coming in Neo and mentioned the default nullable behaviour of value-type properties. We talked briefly about the performance implications of nullable types, which I was unaware of. I found this proof regarding Performance of nullable types and noticed a particular comment made by Darrell:
Warning! Nullable types considered hazardous to your performance.
Let this be your warning!
During my stay in Cortina I talked briefly with Arjen and Erik about the future of Neo regarding .NET 2.0. Earlier I wrote a post on how to Run Neo on Visual Studio.NET 2005 and .NET 2.0 (binary). I finally found the time to start work on support for .NET 2.0 and submitted a snapshot with the proper solution and project files. It’s available under issue NEO-54 in Jira.
We (my employer Capgemini) are the host for the upcoming Dutch user group (dotNed) meeting. Sander Hoogendoorn will entertain us with a session on the Trinidad development platform. You can sign up here.
One year ago I wrote a post on Setting up Subversion (SVN) which I’ve been using on my notebook ever since. Yesterday my good friend Max accused me of spamming this post by Scott Guthrie in which I tried to express my enthusiasm with iBATIS. Not going that lane again with Subversion. And for the guys at our office… yes you should use the Spring.NET Framework. With that out of my system I want to point out a great tutorial by Miguel Jimenez on setting up Subversion on a Windows Server (2003) and making it available via web. Now my repository isn’t only limited to my notebook anymore!