Dec 3 2011

SQL Server Date Comparison

In SQL Server, the dates are stored as datetime. For instance, 12/31/2011 will be stored as 12/31/2011 00:00:00. If the time part is filled out, which by default it is, then you’ll see a time like 12/31/2011 13:01:33.

This throws a wrench in comparing dates without the time. Many people do a conversion to a varchar to both sides of the compare like so: convert(varchar(10), MyDateTimeField, 101)DateDiff(day, MyFirstDateTimeField, MySecondDateTimeField) < 0

In my opinion, the code is cleaner, and I believe/hope that this internal method is optimized for this comparison.


Jul 3 2011

An Argument for Test Driven Development

The concept of Test Driven Development (TDD) can seem foreign to many managers and even developers.  The conventional thinking has been to test your code once it’s working and when you think it’s complete. TDD states that tests must be written before you start to develop and let the tests guide your development.

This was odd to me at first.  How do you test something that isn’t there? I figured this fad would die soon.

I was wrong, not only about its life-span, but its facility. Tests should check if your code does what it was *intended* to do, not what it ended up doing. Hence, tests should be written before you code, when all you have are intentions.

This is a paradigm shifter.  There are subtle but important differences between testing what your code does right now and testing against what it was supposed to do .  Tests are questions, the results are the answers.  When you write tests after you code, you tend to test if the code performs as coded.  You’ll find yourself adjusting the test to fit the result, in other words, you’ll be adjusting the question to fit the answer.  TDD forces you to think about all the important questions before writing code.

  • What is the purpose of this function?
  • What are the input parameters?
  • What should it return?
  • How will the rest of my code use this or call this?
  • Are there any edge cases?

Writing Better Code
When you start to write tests for a class, you have to instantiate the class and make calls to the methods and attributes.  This forces you to look at the potential final product from the consumer’s view. By making these calls, you start to think about how you would like other pieces of your own logic to interact with this class.  This is the perfect time to make such decisions because you’re not clouded with existing logic that forces you into making the convenient decision, not always the best decision.

For instance, let’s say you have an object representing a train. You may have a method named *nextStop* that returns the next stop on the train.  You may ask yourself, should this method return

  1. a string value of the stop name
  2. an integer representation (i.e. an id)
  3. a Station object representing the next stop

You now have to think about how you plan on using this method?  Will it be used in a display field somewhere, or will it be used for look-ups and possible calculations?  You may think your code should look something like this to get the string representation of the next stop:

> Train.getStopName(my_train.nextStop())

This would also indicate that you need a method called getStopName and this method may have to be static.  This kind of information is ascertained simply by thinking about the syntax of your text.
Or maybe nextStop returns a Station object, which would allow you to do more analysis of the station.  It may also allow you to chain your requests, like this:

> my_train.nextStop().nextStop()

It all depends how you think the train object should be working.  The key here is that you’re asking all these questions before writing the code, allowing you to think about practical design and usability before getting muddled knee deep in logic.

You Reap What You Sow
When unit tests are written properly and thouroughly, another advantage becomes apparent.  It is far easier for a new developer to understand how to use the code, its intent and expected results by reading the tests than by reading documentation. Tests are actual working code and can serve the purpose of sample code.  By reading through unit tests, the new developer gets acquainted with how the author expects the logic to be called and the expected behavior.

When time comes to upgrade and offer new features and make existing code quicker, unit tests offer peace of mind.  While making changes, you can rest assured that the code still works and that your changes didn’t have unintended consequences in unintended areas of your application.  Since unit tests check the output per given input, you’ll see tests break if any discrepancy occurs after code changes.
You also get better information on where the issue lies.  Without tests, you often find that an error in one part of your code is being caused by an obscure call to another, seemingly unrelated, part of your code library.  With unit tests, the tests are executed and break on error where the unexpected behavior starts.  This lets you focus on fixing the bug rather than spending time tracking it down.

Tips

For all this to work as advertised, there are certain guidelines that should be followed.

  1. Make your tests granular. Your test should test one behavior of one method.
  2. Each method should have a set of tests, each testing different aspects (ie. different input value types).  For instance, if your method takes two integer parameters, you’ll probably want to have a test for positive numbers, negative numbers, zero, null entries, respectively.
  3. When asserting if the result is correct, have very detailed fail messages when it doesn’t work.  Make the method name detailed, even if it’s long.  This will pay dividends when you’re running tests and looking for bugs.
  4. In a given test, test only one method.  Be specific. A test class should be limited to the class or library.  Each class or library should have it’s own test class.  If you start to test other parts of your code, your tests will become less useful when breaks happen because you won’t be able to quickly tell where the error is occuring.

Jul 3 2011

Database vs Code

There’s a debate in most of the places I’ve seen between where to place a certain piece of logic.  When that logic interacts with data, some say it should be put in the database, preferably in a stored procedure.  Others believe it belongs with code, where the business logic should live.  The answer is really preference (since both ways will get the job done) but I believe the choice should be thought through to weigh what the repercussions might be choosing one over the other. I would like to share the guidelines I follow.

I believe the database and everything in it should deal with insertion, retrieval, and deletion.  Joins and groups are included in this.  The database was made for this and is usually  the most efficient at these kinds of tasks.
Any sort of data massaging or manipulation should reside in code.  I put any sort of manipulation of data under the category of business logic, and for me, business logic *must* reside in code.

Take, for instance, the quantity of a security you’re holding.  In your database let’s say you have a positive number in that field.  For certain reports, you need to show that number as a negative.  The data that is retrieved should be pure data, as it is in the database, and let the code do any translation it needs to.

Following this rule throughout makes the database logic (script/stored procedure) easily reusable because whoever employs it (or any other stored procedure) knows what to expect.  No guesses have to be made if the data has been pre-prepped to show a negative value or not.

You hold the logic to manipulate the data in your code, so if one of the reports now needs to show this number as a positive, you can change it in the code where it needs to and not have to worry about that change affecting other consumers.

Code offers itself to very easy version controlling, with annotation and history.  Testing can be done to prove the results, and those tests can become part of your testing suite.  This can’t be done (easily, if at all) if the logic is on the database.

Often, the claim is made that keeping this kind of logic in code is slower than keeping it in the database.  I argue that the slowdown, if any, is neglible.  However, the gain is tremendous since now you’ve made your database scripts more predictable, and made the manipulation very explicit.  If any change is required, the time saved by not having changes affect other consumers and the ability to test easily offsets the processing time saved by doing the procedure in the database.