Jul
08
2008
0

ReSharper Tip of the Day: Run Unit Tests in a Folder

In reference to my previous post about collectively running unit tests, I thought I would offer this ReSharper tip.

ReSharper’s unit test runner is just plain awesome. Why MSTests don’t work like that by default astounds me…and is enough reason for me not to use them (although there are several more). One option you have for aggregating which tests you want to run in a single session is to right click on the folder that contains their source, right click and either Run or Debug them.

I’m looking for a way to run unit tests in all open documents, but haven’t found that one yet.

clip_image002

Written by Mark in: ReSharper Tip of the Day | Tags: ,
Jul
04
2008
0

What Am I Testing

I’ve been spending the better part of two days doing this same process over and over. It doesn’t feel like I’m testing anything of value.

I am not doing it in the C# 3.0ish way, but it is better to explain it that way. I have a class and a façade (MyFacade) that I want to extend and test.

class Foo {
     public string Name { get; set; }
}

class MyFacade {
     public IMyDependency Depend { get; set; }
}

interface IMyDependency {
     IList<Foo> GetAllFoos();
}

So I write my test first like a good boy person should. I know my façade should give me back a list of the Name properties from the Foo objects it knows about.

[TestFixture]
public class MyFacadeTests {
    [Test]
    public void GetFooNames_ReturnsOnlyName() {
        FakeDependancy fake = new FakeDependency();
        MyFacade m = new MyFacade() { Depend = fake };
        Assert.That(m.GetFooNames(), Is.EquivalentTo(fake.FakeFoos.Select(x => x.Name)));
    }
}

I need that FakeDependency, so I go ahead and create that. This would be a like my repository that will allow me to initialize the fake data.
class FakeDependency : IMyDependency {

    // My local fake repository
    public IList<Foo> FakeFoos = new List<Foo>{
                new Foo{ Name="A"},
                new Foo{ Name="B"},
                new Foo{ Name="B"}};

    public IList<Foo> GetAllFoos() {
        return FakeFoos;
    }
}

OK. So now that I have that, I add my GetFooNames stub to MyFacade.

class MyFacade {
    public IMyDependency Depend { get; set; }

    public IList<string> GetFooNames()
    {
        return null;
    }
}

Run my test. It fails. Good. Now to implement that method….uhh I just copy my assert statement:

fake.FakeFoos.Select(x => x.Name)

…replace “fake.FakeFoos” with “Depend.GetAllFoos()” and I get:

class MyFacade {
    public IMyDependency Depend { get; set; }

    public IEnumerable<string> GetFooNames() {
        return Depend.GetAllFoos().Select(x => x.Name);
    }
}

Build it. Run it. It passes. What did I really test since I just copied the assert statement into the implementation body and changed the source? Did I test anything? That my copy code does the same thing in two places? Am I wasting time?
I rolled it around with a friend and decided to take out the select in the assert statement and replace it with a declarative list so it would look like this:

Assert.That(m.GetFooNames(), Is.EquivalentTo(new[]{"A","B","C"}));

That make me feel a little less “copy and pastey”, but now I have to know my fake is setup to give me three letters for the names. Let’s add a little bit to the fake to make it easier to configure. I am hesitant to do this since I don’t want to add code to my test classes, but I think in the end it is more readable than a more raw configuration.
So I added this to my test class:

public FakeDependency With(int i)
{
    FakeFoos.Clear();
    for (int j = 0; j < i; j++)
    {
        FakeFoos.Add(new Foo());
    }
    return this;
}

public FakeDependency Named(string name)
{
    for (int i = 0; i < FakeFoos.Count; i++)
    {
        // We want them to be 1 based and not zero based
        FakeFoos[i].Name = string.Format("{0} {1}", name, i + 1);
    }
    return this;
}

And use it in my test like this:

[Test]
public void GetFooNames_ReturnsOnlyName() {
    FakeDependency fake = new FakeDependency().With(3).Named("Fake");
    MyFacade m = new MyFacade() { Depend = fake };
    Assert.That(m.GetFooNames(), Is.EquivalentTo(new[]{"Fake 1","Fake 2","Fake 3"}));
}

I’m a lot happier with that than copying the same code from the test to the implementation classes.

Written by Mark in: Unit Testing | Tags:
Jun
30
2008
0

Unit Tests Everywhere

 

Recently I’ve been able to extend my unit test code coverage as I’ve been introducing more features into our code base. I know this is something that should always be done, but for whatever reason, that’s not the case. What I’ve come to notice is our current method of organizing our unit test makes adding new features and test for new features awkward.

Currently our unit tests align perfectly with the class they test. So for example, if we have a class:

namespace MyCompany.Domain{
     public class Foo{}
}

We have, or should have, a test fixture in a separate assembly that looks like this:

using MyCompany.Domain;
using NUnit.Framework;
namespace MyCompany.Domain.Tests{
    [TestFixture]
    public class FooTests{}
}

This is probably a pretty typical strategy for organization. It is intuitive where to find tests for a type. Were I’m loosing my taste for this method is as the solution grows to several assemblies or layers, adding new unit tests for a specific feature becomes a scattered mess of changes. If I need to add a new field, I add new tests in the UI.Tests, the Domain.Tests, Repository.Tests, Core.Tests, etc.  Makes sense though right? You have to pass that new field through all the layers. I’m ok with the number of tests I need to write, but I don’t like having to go to eight different places to run them when I want to test my feature. It would be nice to align them them to the feature, or tag them in such a way I could find them easily. It could be that we are over layered and that is the real problem. We could be an onion.

Shrek: Example? Okay, er… ogres… are… like onions. 
Donkey: [sniffs onion] They stink? 
Shrek: Yes…NO! 
Donkey: Or they make you cry. 
Shrek: No! 
Donkey: Oh, you leave them out in the sun and they turn brown and start sproutin’ little white hairs.

We are definitely an onion….or an ogre, but that’s a whole different analogy.

There is a nice article in CoDe Magazine by Scott Bellware that talks about BDD. Most of it I didn’t see as valuable to my every day activities until he started talking about SpecUnit .Net. It was, in theory, what I’ve been looking for. Align my tests with my features/defects/requirements / whatever. SpecUnit .Net does some nice human readable report generation that I don’t need, but why would I need a new tool when I could just categorize my tests in folders that line up with my real world problems.

That gets me close, but there is no way to run the entire category without using the command line. Still doable, but not as nice as ReSharper’s unit test runner. It would be nice to get a Run all tests in this category from the context menu, but I’m not sure if that would be easy to do across the different frameworks. Again it would be nice to save my unit test session so I don’t loose it every time I close the IDE.

While we’re dreaming, Maybe we could invert the relationship and make the class under test and attribute and the tests themselves could align directly with the requirements. Something like this for example:

[Test][TypeUnderTest(typeof(Foo))] public void Correctly_Calculates_Bar(){
    //...
}

 

Or we could even get fancy with generics:

[Test<Foo>]
public void Correctly_Calculates_Bar(){
    //...
}

The IDE, ReSharper or someone could let me run all the tests for Foo if I wanted. 

After Josh’s comments I thought I would add a couple screen shots of using the Category attribute to group the tests as needed. You can apply the Category attribute to the method or to the TestFixture.

    [TestFixture]
    public class MyClassTests {

        [Category("Add the ability to do work")]
        [Test] public void DoWork_WithNoArgs_DoesWork(){  }

        [Category("Add the ability to do additional work ")]
        [Category("Add the ability to do work")]
        [Test]
        public void DoWork_WithAllArgs_DoesWork() {   }
    }

 

You can select Categories from the unit test runner’s Group by: combo box.

image

It then will group your tests by their category. I did find the UI a bit buggy. At first it wasn’t applying the grouping, but after a couple attempts they started to show up.

image

Thanks again Josh. That will keep me content for the time being. Now if I could only inspect the entire solution for tests in the category I would really happy.

Written by Mark in: Unit Testing | Tags: ,

Powered by WordPress | Kredit | TheBuckmaker