On Testing “Trivial Code”
I can’t resist jumping on the band-wagon and telling people that they’re wrong, so here goes… 😀
Mark “Ploeh” Seemann wrote a post on testing trivial code. There have been several responses saying he’s wrong and that you shouldn’t test trivial code. Some of the responses have been a little less graceful than others (and slightly gross and maybe NSFW – an orangutan peeing).
Everyone that has responded so far, is wrong in some way. I’m wrong in some way as well and I’m sure this is going to turn in to another “beating the dead horse” conversation quickly with people pointing fingers and poking eyes. I just want in on the fun while it is here to be had.
Ploeh Is Right, For The Wrong Reasons
I think Mark is right in that we should test most of our “trivial” code (if not all of it). I think he’s very very wrong is saying that we should unit test all of it – especially with the examples that he showed of unit testing a C# auto-property for a date/time field.
Mark is right because this field must add some value to the system. If it doesn’t add some value, it shouldn’t be there. If it does add some value, we should guarantee the value that it adds.
Jimmy Bogard Got It Right
Jimmy wrote a post that I think was unrelated, but happens to fit perfectly in to the conversation. In that post he says:
When should you test?
When it provides value.
When is that?
Ultimately, it depends is the only reasonable answer. But let’s take the example of a date/time auto-property that Mark used in his example, for our purposes and discussion.
The value that a date/time property adds may not be in the business logic that uses it. It may not have anything to do with handling of the date/time in some creative way to make sure other things happen at a certain time. It might be as simple as an invoice date, or perhaps a purchase order # on an invoice. Both of these fields are trivial, but both add value to the idea of an invoice. I wouldn’t unit test these fields if they are only used for display purposes, though. Instead, I would focus the test on the place that the field provides value – the end to end solution.
Mark Rendle Got Part Of It Right, Too
I think Mark Rendle got some of it right in his response, too. He talks about the idea of validation code in the UI to ensure a date can’t be set in the past, if that is what the business needs are.
This leads to the real point in adding value in tests.
Functional Tests, Not Unit Tests
The value that trivial fields used for display purposes adds, is found in the display of the information. In this case the use of an Invoice Date and Purchase Order Number on the invoice that is sent to the person that needs to pay it provides value to both the person sending the invoice and the person receiving the invoice – so test that. Test the display of the information because that’s where the value is found. Write a functional test that runs your invoice generating process and use a simple UI test to ensure the date shows up. This is where a test provides value for trivial code in this case – functional tests, not unit tests.
A unit test around a C# auto-property is a bad idea because it only tests the compiler and runtime as others have pointed out. But a functional test that proves “When I supply a Purchase Order Number, Then the invoice should display the Purchase Order Number” is a valuable, functional, end to end test. After all, If I were a customer of a company and I sent them a PO# for an invoice, I would want that PO# to show up on my invoice. If it didn’t show up, I’d be a little “YOU ONLY HAD ONE JOB TO DO!” upset. If I send you a PO# because I need it on my invoice, you better send the invoice back with the PO# or you’re not getting paid – at least, you are decreasing the chances of getting paid on time.
Value In Trivial Code
There’s no value in testing trivial code? My “BS” alarms are ringing. You want to write unit tests for auto-properties in C#? My “BS” alarms are still ringing loud and clear!
My example of using a functional test to prove the value of a PO# is only an example, and not meant to be the ultimate answer or solution. You need to take the time to understand where the value for your trivial code really is. Once you do that, you’ll understand how to properly scope your tests to prove the value of that trivial code.
If you can articulate the value of that auto-property when you’re talking to a coworker, you can write a correctly scoped test to prove the value. If you can’t provide a description of the value of that trivial code, though… it probably doesn’t need to be there.