Archive for April, 2008

Improving tests with Extension Methods

In my constant search for making it easier to write tests for common things in our framework, I believe I was able to clear some things up by using extension methods. Not that this hasn’t been done before, it’s just that I want to document how I got to it so that I can use this post to explain the approach to other people (and maybe help somebody else learning about this).  🙂

The scenario is: we need some clean and easy way to test validity of entities after business rules have been evaluated. One approach would be to write the test like so:

[TestMethod] public void SomeTest() { CustomerEntity entity = new CustomerEntity(); bool entityViolatesRule = false;
// make the checks and assign true/false to the entityViolatesRule variable
Assert.IsTrue(entityViolatesRule, "Some assertion message..."); }

Disclaimer: nope, I don’t name my tests like that. It’s just that the test name isn’t important here!

The test would need whatever logic necessary for checking whether the entity violates a given rule, and then call an assertion for it.

In order to clean that up a little bit, I created a Violates extension method on my Entity class. The extension is only meant to be used by tests. The method takes in a RuleViolationExpectation object, meant to carry the expectations for the violation of a specific rule. An assertion would be called from within that method:

public static class EntityTestExtensions { public static void Violates(this Entity entity, RuleViolationExpectation expectation) { bool entityViolatesRule = false;
// some code that looks at the expectation and checks
// whether the entity meets the expectation... Assert.IsTrue(entityViolatesRule, "Some assertion message..."); } }

 
The RuleViolationExpectation class looks like this:
 
public class RuleViolationExpectation
{
    public Entity Entity { get; set; }
    public Type RuleType { get; set; }
    public string Message { get; set; }
    public ViolationLevel Level { get; set; }
}

The test could now look like this:

[TestMethod]
public void SomeTest()
{
    CustomerEntity entity = new CustomerEntity();

    entity.Violates(new RuleViolationExpectation 
                    { 
                        RuleType = typeof(CustomerNameIsValidRule), 
                        Level = ViolationLevel.Violation, 
                        Message = "Customer name must..." 
                    });
}

I liked that better because I got rid of the Assert, as well as any logic that checks whether the entity violates the rule according to the expectation. Now all the developer has to do is to call the Violates method on the entity, passing in the expectation, and the framework does the rest (verification and assertion).

One thing bothered me, though: the call to the method read sort of funny, kind of like "entity violatates rule violation expectation…". That didn’t really express the intent well: it’s not that the "entity violates a rule violation expectation"…. it’s more like the "entity should violate a specific rule according to the given expectation".

I then rewrote the test based on how I’d like it to read for better comprehension:

[TestMethod]
public void SomeTest()
{
    CustomerEntity entity = new CustomerEntity();

    entity.Violates<CustomerNameIsValidRule>()
          .WithMessage("Customer name must blah blah blah...")
          .OnLevel(ViolationLevel.Violation)
          .Verify();
}

I thought that read much better. It’s more like "entity violates the CustomerNameIsValid rule, with a message like ‘Customer name must blah blah blah…’, and on level Violation, so Verify all of that for me". For the records, the other level option is Warning.

Notice that from the call to Violates on, that’s really just a long chained method call, split up into several lines just to make the code easier to read, without requiring horizontal scrolling.

In order to enable such syntax, I’ve added one more extension method to my EntityTestExtensions class:

public static RuleViolationExpectation Violates<TRule>(this Entity entity)
    where TRule : Rule
{
    RuleViolationExpectation expectation = new RuleViolationExpectation();
    expectation.Entity = entity;
    expectation.RuleType = typeof(TRule);
    return expectation;
}

The method takes the expected rule type as a generic type, instantiates the RuleViolationExpectationViolation class, associates the expectation with the entity, assigns the type of rule to the expectation, and returns it.

Next, I created a RuleViolationExpectationExtensions class, and added extension methods to it, like so:

public static class RuleViolationExpectationExtensions
{
    public static RuleViolationExpectation WithMessage(this RuleViolationExpectation expectation, 
                                                       string message) { expectation.Message = message; return expectation; } public static RuleViolationExpectation OnLevel(this RuleViolationExpectation expectation,
                                                   ViolationLevel level) { expectation.Level = level; return expectation; } public static void Verify(this RuleViolationExpectation expectation) { expectation.Entity.Violates(expectation); } }

Each method extends the RuleViolationExpectation class, and takes in the value for one of the properties we need to assign on the expectation, we assign it, and then returns the expectation back to the caller. Got it? It’s just a bunch of methods acting upon the same object.

The Verify method is the one that works a period (".") at the end of the sentence, by telling the framework we’re done setting up the expectation, and it’s time to verify the entity against the expectation. The method just leverages the Violates method that we already have on the entity; the one that takes in the RuleViolationExpectation object.

The actual implementation I’ve done for this in our framework is more complex and complete; the expectation class has a couple more properties that we need to check for, and it also has logic that validates the expectation so to make sure the developer has provided everything the framework needs in order to verify the entity against the expectation. If there’s piece missing, the framework call an assertion and tells the developer what’s missing.

Also, I’ve created a CodeRush template that makes it REALLY easy for developer to write the code and not miss any piece. The way it works is: I put the name of my entity variable into the clipboard and then type rve (Rule Violation Expectation, but I’ll probably change this), and I get this:

clip_image001

All the developer then needs to do is to fill in the expectations, hitting enter to go through the "fields" (orange highlighted areas) in the code:

clip_image001[7]

Moving along with a test-first approach, I’m already thinking that the developer can write the test first for the rules evaluation verification, and then I’ll write a plug-in that will read the call to "Violates…" and generate the business rule, where the dev then only needs to write the actual business logic. In case the test hasn’t been created first, I can also have a plug-in that’ll look at an existing business rule and then create the test based on it.

I believe such approach has very little friction even for developer who aren’t not entirely comfortable with TDD and test-first. What do you think?

Advertisements

1 Comment

Putting LINQ queries together, one piece at a time

Last week, good pal Rod Paddock asked me an interesting question about LINQ, and I think this may be useful to others (not that the answer may not already be out there somewhere, of course…).

The main scenario was that different queries had to be run depending on some options. The from and select parts of the query where pretty much the same; the parts that varied were the where and orderby ones. Here’s some code to illustrate a simplified scenario:

 

Collection<string> months = new Collection<string> { "January", "February", 
    "March", "April", "May", "June", "July", "August", "September", "October", 
    "November", "December" };

IEnumerable<string> query = null;

int? minNumberOfLetters = 5;

if (minNumberOfLetters.HasValue)
{
    query = from m in months
            where m.Length >= minNumberOfLetters
            select m;
}
else
{
    query = from m in months
            where m.Length >= minNumberOfLetters
            select m;
}

bool shouldOrderByLength = true;

if (shouldOrderByLength)
{
    query = from m in months
            where m.Length >= minNumberOfLetters
            orderby m.Length
            select m;
}

foreach (var item in query)
{
    Console.WriteLine(item);
}

The code should query only months whose name length is equals to or greater than minNumberOfLetter (in the sample above, that’d be 5), unless that variable holds a null, in which case all months should be returned. Also, the query should be ordered by the length of months names, in case shouldOrderByLength is true (obvioulsy, both minNumberOfLetter and shouldOrderByLenght wouldn’t be hard-coded, but instead, read from user input or whatever…).

The main problem with such code is that there’s a lot of redundancy in the queries. What if, for instance, instead of doing select m, we wanted to do select m.ToUpper()? We’d need to make that change in multiple places.

Queries can be broken up into smaller pieces. Queries don’t get executed until they’re iterated over, either by using in a foreach block, or calling ToList() on it (which uses a foreach internally…). That means we can tweak with them until right before the iteration happens.

So, we can refactor the previous code where we first declare the part that doesn’t vary in the query:

var query = from m in months select m;

Remember, the query above does NOT get executed just yet; we are just defining it, but not executing it (think of it as building a SQL query by concatenating strings, and eventually executing the query against the database).

Then we can add the where clause to the query if appropriate:

if (minNumberOfLetters.HasValue)
{
    query = query.Where((string m) => m.Length >= minNumberOfLetters);
}

Same with the orderby clause:

if (shouldOrderByLength)
{
    query = query.OrderBy((string m) => m.Length);
}

Whenever we’re done building the query, then we can iterate over it as needed.

Another cool thing we can do: say we need to order the query according to some specific logic; for example, if some variable is true we want to order the query by the month’s name, otherwise we want .to order it by the name’s length. That could be done something like this:

 

Func<string, object> orderBy = null;

if (orderByName)
{
    orderBy = (string m) => m;
}
else
{
    orderBy = (string m) => m.Length;
}

query = query.OrderBy(orderBy);

Basically, we declare a Func<string, object> variable that is going to hold the expression for ordering. In the if-block we assign a lambda expression to the variable accordingly. Finally, we add the call to OrderBy to the query, passing in the expression.

Here’s the complete final code, in case you want to mess with it:

 

Collection<string> months = new Collection<string> { "January", "February", "March", 
"April", "May", "June", "July", "August", "September", "October",
"November", "December" }; var query = from m in months select m; int? minNumberOfLetters = 5; if (minNumberOfLetters.HasValue) { query = query.Where((string m) => m.Length >= minNumberOfLetters); } bool shouldOrderByLength = true; if (shouldOrderByLength) { query = query.OrderBy((string m) => m.Length); } bool orderByName = true; Func<string, object> orderBy = null; if (orderByName) { orderBy = (string m) => m; } else { orderBy = (string m) => m.Length; } if (orderBy != null) { query = query.OrderBy(orderBy); } foreach (var item in query) { Console.WriteLine(item); }

1 Comment

Ok, ok, I’m signing up for this Twitter thing…

Markus has been harassing me about to get into these Facebook and Twitter things. I’ve signed up for Facebook a few weeks ago (even though I don’t waste my time with those little applications they have there…). Now he’s been on my tail saying I have to do this Twitter thing, which I have seen people talking a lot about it, but I still can’t really see why I’d want to use it.   🙂

I’ve decided to give it a go… let’s see… I’ll either get hooked, or just not use it for too long.  It seems to me like a new spin to the whole Big Brother thing. 🙂

Well, anyways, I’m there: http://twitter.com/ClaudioLassala

4 Comments

At the MVP Summit this week

I’m out to Seattle for the MVP Summit 2008 the whole week. Always fun to be here. It’s great to get together with all these people, from all over the world, that I got to know over the Internet throughout the years.

It’s just very cool to hang out with people from so many different countries, coming from very different cultures, speaking very different languages, but at this point they’re all focused into discussing the things they passionately work with.

Leave a comment

Failed assertion throws an exception…

Hmm, this is something I did not know: when a testing framework’s Assert method fails, an exception gets thrown. We don’t actually see that exception, because the framework catches it. We usually don’t see it because tests normally look like this:

[Test]
public void SomeTest()
{
    Assert.IsTrue(false, "whatever");
}

However, say the test was written like this:

[Test]
public void Test()
{
    try
    {
        Assert.IsTrue(false, "whatever");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.GetType().FullName);
    }
}

We get the following printed on the Output window:

NUnit.Framework.AssertionException

So why would somebody ever write a test like the one above, you may ask, right? Well, like I mentioned the other day, I wrote a framework for integration tests that has a bunch of assertions for some things so that the developer doesn’t have to write those over and over again. Even though those things are hidden from the developer, I try to capture as much information as possible, and if any assertion fails, I give all the details to the developer so that he know exactly what failed during the integration.

When running a specific test here, I noticed that I was getting some extra information that shouldn’t really be there, and that was because one assertion was failing and was getting trapped by a try/catch somewhere, and after some digging I actually realized this behavior of assertions throwing "AssertionException"’s.

Leave a comment

The whole testing thing…

I keep hearing how developers say it’s kind of hard to get their minds around this testing thing, so I was then thinking to myself: “how did I get into this, by the way?

It was at DevTeach 2003 when I first heard about unit testing. Scott Bellware was presenting a session about it. I decided to sit in and see what that was all about. Scott showed NUnit, and how to write some unit tests (sorry, that’s as much I can remember so many years later…).

questions[5]Right after seeing that session, I decided to start writing some tests for some new code I was writing. At the time, I was writing the test after I wrote the production code, still trying to figure that NUnit thing. I was pretty pleased by having automated tests for some of my code.

Late in 2005, the same Scott came to Houston to present a full-day TDD workshop.  Again, that was kind of long ago, and my memory is fuzzy. I remember Scott touched on dependencies, mock objects, how Test-Driven Development (TDD) helps keeping track whether the implementation is going on or off track, etc. I guess that was when I’ve heard of using TDD more as a design methodology than as a testing methodology, but I’m sure I didn’t quite *get* the idea back then.

Around that same time, I was working on a project here where we’ve decided we wanted developers to write more tests. We were using NUnit, and writing “integration” tests, not “unit” tests (as I came to realize later). We were writing tests to make sure the data put into our business entities were being saved and retrieved correctly to and from the database.

Right before starting off a new project (early in 2006), I looked back and noticed that a lot of redundant code was being written for those tests (instantiate entity, stick test values to its properties, save it, reload it, check to make sure the values saved are the ones expected, delete it, and have assertions all around to make sure things were working).

Decided to make that easier, I wrote a testing framework that’d do all that boring and repetitive work for the developers. For each business entity, the developer would create a test fixture class, make it inherit from a baseclass from my framework, override a method to provide test data to be pushed onto the entity, and give the baseclass the type of entity under test. The framework would then take care of doing all the heavy lifting and report any problems to the developer by means of assertions with as much detailed information possible (which property has failed, in which process, why, what could be causing it, etc.).

We had also noticed how much of a pain it was to create some specific test data that a given entity needed in order for it to be properly tested. I’ve then added some helper methods to my test framework that allowed the developer to pretty much ask for “5 entities of type Customer for tests”, or something like that, and the framework would take care of creating those, giving it back to the developer (who could also tweak with the test entities, of course), and then cleaning it up afterwards.

The framework worked well, and the great thing about it was that it was pretty easy to get some good code coverage with those tests. However, at the time I *thought* we were doing unit tests, but we were actually doing integration tests. It finally downed on me that we should also be able to test things in isolation. That is, if what we need to test is a business rule, we shouldn’t need a live connection to the database, or even a data access layer for that matter. “A-ha, so that’s what those mock objects are all about, then”, I thought to myself.

With that in mind, I decided to improve our testing framework so to make it easier for our developers to write unit tests for our business rules, so that they didn’t have to worry about the dependencies we have in our middle-tier framework in order to do so. After I’ve done some research on mock frameworks, I’ve decided to go with TypeMock, which I wrap up in my own special framework for testing our middle-tier components.

I’m currently working on rewriting some pieces of our testing framework in order to make use of some of the new features in C# 3.0 (such as object and collection initializers, lambda expressions, extension methods, etc.). This allowed me to clean up my API’s a lot (or so I think).

Everything I’ve mentioned so far has definitely improved my skills with doing TDD as a “testing” methodology, trying to make sure our code has some tests around it. That is something that most developers have a better time understanding and trying to do it, so that’s certainly valid.

Doing TDD as a “design” methodology is something eventually I got the idea and decided to start practicing it. This is definitely much harder for developers to get used to, because it really requires a different approach to writing software; different from what they’ve been doing for so many years now. However, like it’s been said over and over again by other people, when you really stick with TDD, then you start feeling bad about any code you write that you didn’t design beforehand, test-first.

By no means am I saying that I have mastered TDD (far from that), but I’m just certain that the code I wrote test-first is of much higher quality. Not only I believe my design is more solid (both because of the thought I’ve put through the design, but also because of the side-effect of getting the implementation under test), but I find it’s much easier to explain something to another developer by showing her the tests first, and then digging into the implementation.

I have been reading a lot of books, articles, websites, blog posts, other people’s code, etc., trying to improve my approach to TDD (which always entertains me by getting blown away by some code other people write). This has been great, and I plan to continue doing so.

I’ll probably have some more posts coming this way on the subject, as I get my mind around this thing.  🙂

3 Comments

Consider creating a custom collection

It’s happened to me a few times when I create a property of a type List<T> or Collection<T>, where T is something simple such as a string or an int, and then later I regret I’ve done so. For instance, the other day I had the following scenario (I’ve changed things around in order to make it a little simpler for this post):

I have some class that had a Parameter property of type Collection<string>:

public class SomeClass
{
    private Collection<string> m_Parameters = new Collection<string>();
    public Collection<string> Parameters
    {
        get { return m_Parameters; }
        set { m_Parameters = value; }
    }

    public SomeClass()
    {
        this.Parameters("A");
        this.Parameters("B");
        this.Parameters("C");
    }
}

It used to work great when all I needed was a list of parameters there:

SomeClass foo = new SomeClass();
foreach (string parameter in foo.Parameters)
{
    Console.WriteLine(parameter);
}

However, in order to support something new feature, I also needed to store the old and new values for the parameter. Hmpf. Now, instead of a Collection of strings, I need a collection of something else. I then created a Parameter class, with the specific properties I needed:

public class Parameter
{
    public string ParameterName { get; private set; }
    public object OldValue { get; private set; }
    public object NewValue { get; private set; }

    public Parameter(string parameterName, object oldValue, object newValue)
    {
        ParameterName = parameterName;
        OldValue = oldValue;
        NewValue = newValue;
    }
}

Nothing too fancy. At this point I can change my Collection<string> to Collection<Parameter>. Obviously, I’ll also have to change any code that works with that collection, since the generic type for the collection has changed:

SomeClass foo = new SomeClass();
 foreach (Parameter parameter in foo.Parameters)
 {
     Console.WriteLine(parameter.ParameterName);
     Console.WriteLine(parameter.OldValue);
     Console.WriteLine(parameter.NewValue);
 }

If I had gone with a richer type to begin with, I wouldn’t have to change any caller of that collection; if I needed more information, all I’d have to do was to add more properties to the Parameter class. In this one case, making the change wasn’t such a big deal because my property was exposed only within the assembly; if it was exposed as a public property, than that’d be a major breaking change because I’d have no clue as to who else would be using it in other assemblies.

That makes me think whenever I’m declaring a Collection or List of something, I should put a little more thought into whether it’s likely that I’ll need some extra information associated with it, and if so, I should create a special type for it.

Also, it turns out that what I really needed was some sort of dictionary, because I wanted to look up items by a given key (in this case, the parameter’s name). The Collection<T> doesn’t give me that behavior, but the KeyedCollection<TKey, TItem>  does, so I created a ParameterCollection like so:

public class ParameterCollection : KeyedCollection<string, Parameter>
{
    protected override string GetKeyForItem(Parameter item)
    {
        return item.ParameterName;
    }
}

The class uses a string as the key (which is the ParameterName), and the Parameter as the value. So my SomeClass class ended up like this:

public class SomeClass
{
    private ParamaterCollection m_Parameters = new ParamaterCollection();
    public ParamaterCollection Parameters
    {
        get { return m_Parameters; }
        set { m_Parameters = value; }
    }

    public SomeClass()
    {
        this.Parameters.Add(new Parameter("A", "A old value", "A new value"));
        this.Parameters.Add(new Parameter("B", "B old value", "B new value"));
        this.Parameters.Add(new Parameter("C", "C old value", "C new value"));
    }
}

And besides using a regular foreach, I can also access the elements like this:

Console.WriteLine(foo.Parameters["A"].OldValue);
Console.WriteLine(foo.Parameters["B"].OldValue);

5 Comments