Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reusing test suites with multiple implementations?

I'm testing with nUnit. I have a suite of tests that run against my IFoo interface; the Test Fixture Setup determines which IFoo implementation to load and test.

I'm trying to figure out how to run the same suite against a list of IFoo implementaions, but don't see any way to test all implementations without manually modifying the Setup.

Has anyone tackled this problem?

like image 419
Chris Avatar asked Sep 29 '09 23:09

Chris


2 Answers

Create a base test class that contains tests shared between IFoo implementations like this:

// note the absence of the TestFixture attribute
public abstract class TestIFooBase
{
   protected IFoo Foo { get; set; }

   [SetUp]
   public abstract void SetUp();

   // all shared tests below    

   [Test]
   public void ItWorks()
   {
      Assert.IsTrue(Foo.ItWorks());
   }
}

Now create a very small derived class for each implementation you want to test:

[TestFixture]
public class TestBarAsIFoo : TestIFooBase
{
   public override void SetUp()
   {
      this.Foo = new Bar();
   }
}

edit: Apparently NUnit also has support for parameterized test fixtures, even generic test fixtures with parameter types are supported. Example from the linked documentation:

[TestFixture(typeof(ArrayList))]
[TestFixture(typeof(List<int>))]
public class IList_Tests<TList> where TList : IList, new()
{
  private IList list;

  [SetUp]
  public void CreateList()
  {
    this.list = new TList();
  }

  [Test]
  public void CanAddToList()
  {
    list.Add(1); list.Add(2); list.Add(3);
    Assert.AreEqual(3, list.Count);
  }
}

This example is a bit simplistic because it has the new() constraint for the types. But you could also use Activator.CreateInstance and pass the constructor arguments for your IFoo implementations from the TestFixture attributes.

like image 180
Wim Coenen Avatar answered Oct 21 '22 19:10

Wim Coenen


One of several ways to accomplish this:

public interface IFoo
{
    string GetName();
}

public class Foo : IFoo
{
    public string GetName()
    {
        return "Foo";
    }
}

public class Bar : IFoo
{
    public string GetName()
    {
        return "Bar";  // will fail
    }
}

public abstract class TestBase
{
    protected abstract IFoo GetFoo();

    [Test]
    public void GetName_Returns_Foo()
    {
        IFoo foo = GetFoo();
        Assert.That(foo.GetName(), Is.EqualTo("Foo"));
    }
}

[TestFixture]
public class FooTests : TestBase
{
    protected override IFoo GetFoo()
    {
        return new Foo();
    }
}

[TestFixture]
public class BarTests : TestBase
{
    protected override IFoo GetFoo()
    {
        return new Bar();
    }
}
like image 1
TrueWill Avatar answered Oct 21 '22 17:10

TrueWill