重用多个实现的测试套件?

时间:2009-09-29 23:46:18

标签: unit-testing nunit

我正在使用nUnit进行测试。我有一套针对我的IFoo接口运行的测试;测试夹具设置确定要加载和测试的IFoo实现。

我正在试图弄清楚如何针对IFoo实现列表运行相同的套件,但是没有任何方法来测试所有实现而无需手动修改安装程序。

有没有人解决过这个问题?

2 个答案:

答案 0 :(得分:11)

创建一个基础测试类,其中包含IFoo实现之间共享的测试,如下所示:

// 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());
   }
}

现在为要测试的每个实现创建一个非常小的派生类:

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

编辑:显然NUnit也支持parameterized test fixtures,甚至支持带参数类型的通用测试夹具。链接文档中的示例:

[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);
  }
}

这个例子有点简单,因为它对类型有new()约束。但您也可以使用Activator.CreateInstance并从IFoo属性传递TestFixture实现的构造函数参数。

答案 1 :(得分:1)

实现此目标的几种方法之一:

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();
    }
}