If, like me, you're slowly getting into test-driven development, it becomes apparent that there are several ways to create a class library and a set of tests that challenge it in Visual Studio. Then it becomes obvious that the best way to do it and not leave test code in your releases is to create something like this where the tests are in a separate project.
To speed up the creation of solutions like these, I've created two templates to plug into Visual Studio to do it for you. There's one for testing with MbUnit 2.3 RTM and one for NUnit2.2.9. Download the one you want to your VS2005 Project Templates folder and then create a new project. You'll see the options to use the templates automagically.
Let me know how you get on and if you'd change them in some way.
Download all the test and program code generated by the end of this article here.
With a selection of schemas tested and a set of CodeDom tests established for the checks we're most likely to need in part 2, let's turn our attention to the tweaks we want to make to the generated CodeNamespace members. Here's my initial list - we could well add to it later on providing more tests are written to cover the additional code.
- Change the field \ property names from elementField\Element to element\Element
- Change the type of a field \ property
- Change the name of a type
- Change the way dates are serialized.
- Change the way boolean values are serialized.
In this post, we'll build the code that makes the first these changes.
Download code covering all the tests and code so far from this series here.
In the last episode, we started building our alternate to xsd.exe and wrote a set of five tests that made sure the converter worked against the smallest possible schema. We also learnt about building basic schemas programmatically. Next up, we'll look at some more basic pieces of a schema and start working in the CodeNamespace area.
So let's lay out what we want our application to do.
- Convert any number of given, connected schema files to a set of C# classes
- Allow us to tweak aspects of the generated classes to suit our needs elsewhere - for example, change field, property and class names to our own naming conventions or the way something is serialized.
- Save the generated classes into a given file.
- Present some sort of UI that allows us to specify what tweaks should be made.
- Save those settings for reuse later on.
With that in mind, let's bear in mind the mantra of 'code little, think, code a little more' and write some tests. The heart of our app is a two stage process.
- Convert schema to namespace
- Tweak namespace
So let's start on stage one and write some tests.
Quite a few people have been writing about their exploits with Test-Driven Development over the past few weeks and months. Oren Ellenbogen has been writing several articles on the basics of TDD, Ron Jeffries has been TDD'ing a sudoku solver, and Scott Hanselman, Phil Haack and Roy Osherove continue to add more thoughts of their own to the subject. Roy has even started a blog on writing a book about test-driven development.
Given my attention deficient aptitude for getting distracted by something else before getting started on a project, Oren's description of TDD as 'Code little, think, code little' seems good for me. And with the repeat test run feature now up and running in Jamie Cansdale's TestDriven.NET 2.0, using nUnit in VS2005 is even easier than before.
I haven't seen anyone work with XML in a TDD blogging series yet, so I'm going to TD-develop a .NET 2.0 app which extends the schema-to-class functionality in xsd.exe. I've picked this for a number of reasons.
- I've already had a go at this in the past but didn't get very far
- TDD also functions as a great way to learn new technologies \ algorithms bit by bit. (Ron's Sudoku solver being a case in point)
- The default behaviour in xsd.exe changed a little between .NEt 1.x and .NET 2.x which means that documentation on this kind of app such as this well thumbed doc provided by Dan Cazzulino on MSDN may be out of date now and TDD will help pick up the differences as we go along.
- I've encountered a bug or two with the XmlSerializer in .NET 2.0 that requires tweaking the class file which xsd.exe generates and it would be useful to do this automatically rather than as a postfix.
I'm going to use the first few tests to
- Set up a nice testing framework for testing boundary conditions as we encounter them.
- Get to grips with the internals of the XmlSchema and CodeNamespace classes that we might not already have.
We can also bear in mind the simple condition that in these initial tests, our code should return the same as if we used xsd.exe on a schema file, so we can generate tests from that as well. Now some might invoke the first acronym of TDD - YAGNI - or 'You ain't gonna need it', which may be true here, but as we're also going to learn how schemas and code namespaces map to each other in the process, I'm happy to make the trade off.
Right then, onto the first test...