You know what they say about assuming
I had an experience I thought was worth sharing. As much as we all try to write reusable code, we still end up riding the Copy-Paste express more often than we care to admit. (Come on, admit it… you know you do it…) Of course, it helps if you do this with code that actually works…
The Copy-Paste Express
Several months ago, I wrote an application that required a custom Validation Rule for IP Address format validation. It worked great, and that project was the inspiration for my post on Custom Validation Rules. Now, 2 months later, I want the same functionality in a new application. While the ValidationRule class itself is reusable, the XAML code to implement it is not, so to add it to the new application, I copied the XAML over for the IPAddressTextBox. Much to my dismay, when I executed the program the validation did not work.
Knowing that Application 1 worked as desired, I pored over the code and logic, line by line, and they were the same. Since the XAML was a straight copy, they even used the same field and template names. I was pulling my hair out, so I finally went back and read my post, comparing it to the code I had in place. I was able then to find that some of the validation code was missing from the XAML. Now I was really confused: the code on both applications was missing the same critical piece, so how could Application 1 possibly work?
If you don’t see it coming yet, it turns out that Application 1 no longer worked either. I was testing the installed application and not the current copy of the code: when I ran it from Visual Studio, I experienced the same issue. It took me a while to figure out what happened, but in this case my reliance on Blend was the culprit. At some point I used Blend to update the Binding (I don’t remember why). Normally this wouldn’t be a problem, but Custom Validation rules have to be inserted into the XAML manually. By using Blend to update the binding, Blend removed all my custom validation logic.
The lesson here, of course, is not to make assumptions, but more importantly you need to test all changes to an application. In this case, testing the IPAddressTextBox and the Custom Validation had been completed a long time ago, and since the functionality was never intended to be changed, it was never tested after it was complete. And the working copies in the field were correct, so the bug would never have been reported, at least not until another release. Even then, this particular piece of the software is typically only used once when the user configures the application, so even subsequent releases of current installs would never have revealed the issue. Instead, it would have only shown up on a new install or a reconfiguration. Even worse, since this is purely for validation to prevent the user from entering erroneous data, a new user would never realize the functionality was missing: instead, they would just be able to enter any value for an IP Address. So who knows how long this bad code would have been out there, me all the while assuming it worked.
I’m still floundering in the Unit testing area, and I honestly don’t know if Unit testing would have caught this error or not since it was a GUI issue. It does indicate to me that I need to get a better grasp on all things testing: what if this had been a similar but far more serious bug? It also tells me I need to find more ways to get off the Copy-Paste Express. While we’ll never get away from it completely, if I had taken the time to develop a custom control for IPAddressTextBox that implemented the validation, I never would have had this issue. In any case, it really is the little issues that can teach you the most.