Thursday, November 23, 2006

Tuesday, November 14, 2006

Language Design Books

{

Joel Spolsky is so popular that I'm sure upon his mention of "Compilers: Principles, Techniques, and Tools" - the so called "Dragon Book" - interest and sales must have shifted a little.

In this week's Software Development Times Larry O'Brien clarifies with a few resources including Modern Compiler Design, and Programming Language Pragmatics.

Because I'm not classically trained, I find myself with significant gaps in areas like this (compiler construction, algorithms, etc... ), so a reading list is a good thing to have. Of course, the list is the easy part and the finding of time to read and study is what is difficult.

}

Thursday, November 09, 2006

Falsification and Unit Testing

{

Did I ever post that unit testing is hard?

It's hard. I'd love to see it in action at other shops since we've got so much to learn. But let's tally the score of the moment:

It's about 10 minutes to midnight and I've been working my way through someone else's code. This code is a piece of a separate assembly that does validation of a whole bunch of business rules before a person can process a loan application. Each rule is fairly simple, along the lines of "if a person is not older than 18, they must have a cosigner" but there happen to be a lot of rules. I designed the rules to be in a separate assembly because the client changes these frequently, so it will be easy to update with a new DLL instead of reinstalling the application.

Our application is modeled as an object with a series of other objects and lists attached. An application has a borrower. A borrower has an employment history. And so it goes - which makes for a fluid, transactional save or validation by simply passing the application object around.

But I'm looking at a lot of validation at this late hour and finding a systemic issue. The person who wrote the code made an assumption with respect to Lists attached to objects that makes our validation code ineffectual. Here's a sample:

25 if (targetApplication.Coborrowers.Count > 0 && targetApplication.Coborrowers[0].Citizenship == String.Empty)
26 {
27 result.IsValid = false;
28 result.Message = "First Cosigner Citizenship is required for Approved Status.";
29 }
30 }
31 return result;

See the bug? If there are no coborrowers the rule (citizenship must be set) is never evaluated.

But even more so, here's the rub: I had the developer write unit tests for each and every validation rule they put out as a method. I thought a night like tonight: midnight, fatigue, and a crapload of code to fix for a promised build, would be avoided as a result.

The large picture here has to do with the way the unit test was designed to verify the functionality of the validation rule. Because the problem was approached as gingerly, I think the unit tests weren't liable to find a more subtle bug like this. Instead, the unit test probably attempted to validate a coborrower with a citizenship, asserting true, and a coborrower without citizenship, asserting false. No thought was given as to whether a coborrower may not exist.

Perhaps, in programming, we need to focus more on falsification in our unit tests - attempts to break the code or find ways it will assert what's expected under the wrong conditions. But that's all theory right now and I've got a decision to make: stay up late and try to keep my word or heading to bed and fixing the code under the right conditions... the purists will say that a rushed fix is bad, especially since I didn't write the first iteration and won't have time to update the unit tests (I know, I know: bad). But I have to live in a world of realisms where the pain of a broken promise is greater than the pain of a rushed, patchworked fix. Time to get the Mt. Dew out of the fridge...

}

Saturday, November 04, 2006

Configuration API Confession, Repentance

{

The beauty of blogs, in particular this one: I can flaunt my ignorance on any given area. A few nights ago I thought I'd update my current development project to have its connection string maintained in a config file so that it could be changed without a recompile in a single location.

I knew this was the approach we'd eventually take having used it like breathing on all of my previous .NET projects (which were ASP.NET). But Windows Forms applications are slightly different and I ran into the brick wall of not grokking the structure Microsoft uses for configuration.

The big problem in my understanding was that I wanted to have my configuration read in a separate library, thinking I'd reuse the pattern on any future project where I wanted to do something similar. So I created a library project and knowing a little but not enough created a config file manually to use. Knowing a little but not enough (or not updated?) I named my configuration file ConfigHelper.dll.config because this is a well known convention in .NET. I also manually copied this file to the \bin folder and even considered adding a "post build event" to the Visual Studio 2005 project to do this. And when it didn't work and my attempts to read the config file weren't successful, I became very frustrated and even took the time to write it up. Luckily no one besides A the jedi master reads this blog so my voice of ignorance got drown in the black hole that is blogger. No matter: this blog is for me, like a "captains log" to chart my experiences and thoughts.

I realized a while back that I knew just enough from the past few years programming ASP.NET to make ignorant mistakes and convoluted work-around solutions so I've been reading Brian Noyes's Data Binding with Windows Forms 2.0 on Safari trying to grok the whole picture as Microsoft intends it.

So here is the skinny, as embarrasing as it is for me to explain how wrong I had it:

1. In your project, create an App.config file. In Visual Studio 2005 this is the "Application Configuration File" option.
2. Make entries as you like in the configuration file.
3. Compiling your application will produce a MyAssembly.exe.config or MyLibrary.dll.config file in the \bin directory.
4. Libraries aren't meant to read from their own configuration files. Hence attempting to read an entry even if you've manually copied over your MyLibrary.dll.config file will result in an empty string once retrieved. BUT!
5. BUT! BUT! The library is designed to read values from the configuration file of the executable. So if you place the following line in your library:
string foo = ConfigurationManager.AppSettings["bar"];
Your library is looking for the "bar" value in the configuration file of your application.

To my own credit, a lot of the time when I find myself fighting with something I usually know deep down that it's a struggle to understand what the framework designer intended and not something that is "stupid." In this case, what the framework designers intended is quite elegant because when you have, like us, many different libraries that all need to pull something common (connection string is probably most obvious) it can be based on the configuration of the application and managed in a single location.

Okay, now that I got the memo, I can move on.

}

Thursday, November 02, 2006

Configuration API Convoluted?

{

I'm having an evening when I can't believe what is wrong with me because something that should be trivial is giving me hell.

Our application has had connection strings littered all over the place - okay, 8 to be exact and I know this because of my frequent usage of "replace in files" to toggle connection strings. But we're at a point when this needs to be centralized and mutable without doing a new build.

In my head this is simple: slap a config file into the project and off I go. Some kind of one liner along the lines of:

ConfLib.CONNECTION = ConfigurationSettings.AppSettings["Connect"];

Simple, right? I do it with web applications all the time.

The first issue is that ConfigurationSettings, which the old school .NET folks are used to, is deprecated. The message tells you to use ConfigurationManager but neglects to mention that a physical reference to System.Configuration.dll (in the GAC) is needed. This isn't a big issue and 2 minutes later I've referenced it, and rewritten my line of code as:

ConfLib.CONNECTION = ConfigurationManager.AppSettings["Connect"];

Not quite. I'm now in the habit of doing unit tests so I realize that Visual Studio 2005 copies your libraries to a new directory when it does unit tests. I look at the "post build event" options and wonder if it's worth the hassle. So instead I ditch the unit test and return to the main solution, manually copy the *.config file into my application's directory and try.

No dice.

Maybe ConfigurationManager is too nebulous? So I try the following:

Configuration conf = ConfigurationManager.OpenExeConfiguration("ConfigHelper.dll");

Which, when I run it in the debugger seems to pull my keys out of the config file but gives me an access violation when I try:

ConfLib.CONNECTION = conf.AppSettings["Connect"];

This is quite some time later and I'm pretty annoyed because I must have absolutely not gotten the memo or configuration is bloated. Almost to prove to myself how simple this should be, I create a file called Settings.xml and put in a couple of elements and write the following:

XmlDocument configDoc = new XmlDocument();
configDoc.Load(Path.Combine(Directory.GetCurrentDirectory(), "Settings.xml"));
ConfLib.CONNECTION = configDoc.SelectSingleNode("//Database/text()").Value;
ConfLib.VERSION = configDoc.SelectSingleNode("//Version/text()").Value;

That simple.

Granted I am WELL AWARE that the Configuration API has lots of goodies stuffed into it but should that make the process of pulling it out of a configuration file so convoluted? Things that are designed well work for the simple things as easily as they solve the complex.

My configuration files always have the same pattern: I create a class that is designed to read the xml file with static variables for each configuration value. I use a static initializer to read these from the file and have a single static variable I reference when the app is loaded. I've worked on a lot of stuff that benefits from this but almost always configuration stuff seems to boil down to a simple name/value pair you can leverage.

I could have made an indexer and had the pulling look like the AppSettings collection on the ConfigurationManager but I dislike the fact that the compiler doesn't catch errors related to misspelled key names.

Oh well, I'll leave it in its current state. Maybe I'll get the memo tomorrow but I doubt it.

}