Recently, I’ve been mulling a concept very close to Test Driven Development (TDD) but with a surprising twist. As those of you who are familiar with the concept of TDD might be aware, TDD does not strictly advocate (in all cases) a test-first methodology, but rather speaks to the testing of functionality as it is being developed.
I’m not going to rehash TDD in this post, but I’d like to discuss a slightly different alternative, I’m calling it Design Driven Testing (DDT). One thing which is not always clear when building some software (particularly workflows and the like) is exactly what the interplay between various entities may be in advance.
Take a basic example in the form of pagination of search results. Given a few variables we can pretty much sketch out what the requirements are for a decent paging experience – total results, page size (number of results per page), the data ordering and the current page index. From this information, it should be possible to build a “virtual” paging experience to test out our design approach – before writing the production code.
Our moving parts are listed above, all we have to do is assemble the various providers and we can simulate (programmatically) a user experience in scrolling through pages of results. The aim of this exercise is to test the design before we’ve gone to the effort of building a production quality implementation (which might not work).
Here’s some pseudo code to help define the principle:
[TestMethod] public void TestPagination() { GenericQuery queryProvider = new GenericQuery(); //a page size of 20 results/per int pageSize = 20; //default it to the first page int currentPage = 1; //mimic user input queryProvider.FilterByName(“a”, true); //(search term, use wildcard) queryProvider.OrderByName(); int totalcount = queryProvider.Count(); int numberOfPages = 1; if(totalCount > pageSize) { numberOfPages = totalCount/pageSize + 1; //determine page count } //currentPage = 2; //uncomment to get the results from the second page // later on – execute the search paging // (note we could loop through the pages here easily) if(numberOfPages == 1 || currentPage == 1) { var results = queryProvider.Search(1, pageSize); //(start from, row count) } else { var results = queryProvider.Search(currentPage -1 * pageSize, pageSize); //(start from, row count) Assert.IsTrue(results != null, “Should have returned some data”); } }
So what we’ve done here is basically a subset of the functionality which would be required to wire up pagination support to a search page. Conceptually this is the basic functionality – the ability to be able to retrieve data based on skipping rows and selecting a subset. The advantage of spending a little bit of time doing this is that when it comes time to implement the actual solution, you already have some faith that the underlying technique and the support classes will work as designed.
Don’t get me wrong, I’m certainly not advocating this as an approach for every single feature being developed – but it can be a very handy roadmap, especially for junior programmers. It’s not going to give you the ongoing benefit that a normal Unit Test will provide (bounds checking, testing for null arguments, etc etc), although as soon as someone alters one of the components, the test will break.
It’s a great way to play around with concepts and also to show how someone might imagine the implementation at play. What do you think?