Everyone != You
Archive for July 2012
Test Driven Development – A Real world example
Test Driven Development (TDD to its friends) is a well-blogged topic. There are many examples of TDD around the blogosphere, crossing a multitude of technological frontiers. What follows is my own, slightly tongue-in-cheek overview of what TDD is.
Methodology
TDD is essentially a process that states the acceptable criteria of something before building it. In code, this is typically the output of a method, but there are loosely analogous real world examples. It could be argued that examinations are tests that classify candidates as acceptable or unacceptable. A candidate with a perfect score is equivalent in this case to a method which satisfies all its unit tests. And anything with driven in its name is just begging for a car analogy. So instead of talking about either of those things, I’m going to build the Death Star.
The first thing we need to do is describe the Death Star. What should it look like? What should it do? What are its essential features? We describe it with a series of questions. Anything we subsequently build which can give satisfactory answers to those questions is to all intents and purposes the Death Star.
These questions are unit tests. They test a single scenario for a particular method. Methods can have more than one unit test depending on their complexity, but where possible it is best to break complex methods into smaller, more easily testable components.
Below are two basic requirements of the Death Star, along with the unit tests which would need writing before implementation.
That’s no moon
How big should the Death Star be? The only acceptable answer here is as big as a moon. Our test should be to measure the diameter of our object, in Imperial Moons.
Fully operational
The Death Star should be fully operational. We can test this by attempting to destroy Alderaan.
Implementation
When the unit tests are first written, they will fail because we have no implementation. The next step is to build the Death Star itself, in such a way that it satisfies each test.
One immediate problem that presents itself is the requirement for it to be fully operational. The test involves destroying Alderaan, something which we can only do once. To get around this, we require a mock Alderaan, which we can create in our unit test with the intention of using it to test the Death Star’s destructive function. This removes the test’s dependency on an external resource, and the same approach is taken when testing methods dependent on, say, database operations.
Stay on target
Although TDD can give developers confidence that the code they write will satisfy requirements and can be refactored with confidence, it does not guarantee that the final code is problem-free. It can only test what has been anticipated.
However if the input and output of each method is covered by tests, we can be confident that the system as a whole will work as designed. In out Death Star example, the reactor core would also have unit tests, as would all the components it interacts with. The situation where an unexpected input (such as a proton torpedo) causes an unexpected output, which is then input into the next component until a chain reaction destroys the whole system would never arise with good test coverage.
Conclusion
I hope this brief overview of TDD demonstrates that as a methodology it isn’t that difficult a concept. The actual implementation of unit tests themselves is a much wider topic however, with a rich selection of frameworks to choose from. As primarily a C# developer, I have no serious complaints about NUnit, which is more or less the de facto standard now, although Microsoft does ship Visual Studio with its own unit testing framework, which may work well enough for yourself.
Conditional method attributes
Sometimes I like to include some code which will only run when complied in Debug config. This is simple enough, just add some preprocessor commands like so:
#if DEBUG //Do some debug-only stuff here. #endif
However this always looks a bit ugly to me. A much tidier way of achieving the same is to use conditional method attribute like so:
[Conditional("DEBUG")] private void DoSomething() { //Do some debug-only stuff here. }
The only catch with this is that the method must return void. This is necessary to allow it to be included/excluded depending on the compilation config used. It can be worked around by using reference parameters on the method itself.
Anyway, here’s a photo of a skiing penguin.
System.ServiceModel.Activision
.NET Framework 4
Contains the types and enumerations required to fritter teenage years away in front of a flickering CRT.
Methods
Name | Description | |
---|---|---|
Wakawakawaka | Implements IWaka to move Pac Man around screen. Also see System.ServiceModel.Muppets.CreateFozzie() | |
InsertCoin | Allows player to continue. Warning: Execution will terminate if there are not enough resources. | |
FeedWizard | The wizard needs food badly. | |
DoHomework | Method not implemented yet. |
Properties
Name | Description | |
---|---|---|
Lives | Gets or sets the number of lives remaining. The default is 3. | |
Bedtime | Gets or sets the user’s current bedtime. Get will increment the current value by 1 hour. |
RESTful WCF services without .svc file and with very little configuration
WCF is, on the whole, pretty neat. It’s a doddle to decorate methods with UriTemplates and specify DataMembers. Building the actual meat of a web service is made very easy by the wealth of functionality available in WCF4, and this is the bit I usually happily chip together whenever I need to write a RESTful web service.
Then I get to the part where I have to add the service’s endpoint to web.config. It’s usually been several months since I last did it. I look it up on google, but the results don’t quite seem to apply to me. I open up an old project where I last did this ridiculous dance, but evidently I’m missing something because the damned thing still won’t work. The problem is most likely a subtly mis-set attribute. Or may web.config is just a monster which will eat us all.
With that in mind, I was recently delighted to find this blog post by Steve Michelotti. It’s a little old, but the knowledge within was new to me, so it may be new to you too.
In a nutshell, it leverages the WebServiceHostFactory class to allow a ServiceRoute to your WCF service to be defined. The advantages of this are two-fold:
- No service-specific entries are needed in web.config
- The WCF service can be defined in a plain C# class rather than a .svc file.
Steve covers this in much more detail in his blog post, so what follows is a quick summary of the steps required to get a service up and running:
- Define your service in a C# class (implementing an interface is recommended but not required).
- Decorate your class with
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
This is required for the service to operate over HTTP.
- A teensy bit of web.config tweaking is required. This is the other half of the configuration above.
- Add a reference to System.ServiceModel.Activation. This is not to be confused with System.ServiceModel.Activision.
- To add the ServiceRoute, add a line similar to the one below to Application_Start in Global.asax.cs:
RouteTable.Routes.Add(new ServiceRoute("Services", new WebServiceHostFactory(), typeof(Your_Service_Class)));
Where Your_Service_Class is the name of the class you previously wrote for your service. Leaving the first parameter of ServiceRoute blank results in all requests to the service being relative to the site route. Services in the example above is the route prefix of your service url. You can leave it blank, but I prefer to specify a path to keep my services tidily organised. You should decorate your service methods with a suitable UriTemplate, eg
[WebGet(UriTemplate = "MyService", ResponseFormat = WebMessageFormat.Json)]
In the above case the service can be called via a browser on http://my_hostname/services/myservice
That’s it! I can now get on with the meaty business of writing code instead of wrestling with the beast that is web.config.
In the meantime, here are some goats in a tree.
Web.Config is a monster which will eat us all
Just like I remember when all this was fields, I remember when web.config was just a small hamlet of xml blocks. Then I started working on the project in earnest and it grew into a textual sprawl. I’d get lost amongst its sections, scrolling this way and that before frantically hitting CTRL-F like a lost tourist trying to hail a taxi.
One day I expect to arrive at work and find web.config sitting at my desk.
“What’s going on?” I’d ask.
“Oh,” my colleagues would say, “web.config got so complex that it achieved sentience. The only way we could keep it in the building was to give it your job.”
Web.config would smile a broad, hungry smile. And then it would eat us all.
Things which have emerged from my radiator
The previous tenants of my flat had a couple of children. This is of little consequence, except a month or so after moving in, I noticed something poking out from the bottom of the living room radiator:
I was a little surprised at first. Upon removing it completely it was revealed to a brightly-coloured fireman. Maybe there’s a similarly brightly-coloured fire engine in there too, I briefly wondered. Then I thought of something better to do, like check FaceBook.
I thought no more of the matter, although for some reason I couldn’t bring myself to throw the fireman away. However a few months ago the radiator yielded another gift:
This time it was a wooden number 2. It was painted green and had two small cows on it, presumably as part of a farmyard-themed set of numbers. I put it under the coffee table with the astronaut, but otherwise forgot about it, until last week, when the business end of a teaspoon poked out from the bottom of the radiator. This one took a little persuading to remove it from said radiator:
I put it with the other three items which have so far emerged. I wonder what, if anything is still in there, waiting for the hot/cold expansion/contraction cycle to pass it through the radiator’s vanes? I could get a stick and actively clean the thing out but this way is more fun. Should anything else I appear I’ll be sure to update this post. Anything less would be a dereliction of duty.