跳过通用测试中特定类型的测试方法 class

Skip test method for specific type in generic test class

我正在尝试对项目的一部分进行单元测试;我正在使用 NUnit。目标单元处理多种类型的对象,所有对象都扩展了一个基类型。我创建了一个通用测试 class,我在上面设置了所需的测试类型:

[TestFixture(typeof(SomeType))]
[TestFixture(typeof(SomeOtherType))]
class MyTestClass<T> where T : SomeBaseType, new()
{

     [Test]
     public void DoThisTest()
     {
         var sut = CreateSut();
         var target = CreateTarget();

         Assert.IsTrue(sut.Process(target));
     }  

     [Test]
     public void DoThatTest()
     {
         var sut = CreateSut();
         var target = CreateInvalidTarget();

         Assert.IsFalse(sut.IsValid(target));
     }  

     //...
}

这会使用 TestFixture 为每个类型集创建一组所有测试。不管出于什么原因,我有一个测试只在特定类型的上下文中才有意义。这意味着我需要要么 1) 在所有其他类型上使用 Assert.Ignore(),要么 2) 为那些 "special" 测试用例创建一个不同的测试 class。

是否有一种方法可以从外部(属性?)选择退出测试并指定该特定测试在某些情况下不得 "implemented"?我想 "combine" 1) & 2) 这样所有测试用例都在相同的 file/class 中,但对于 TestFixture 设置的某些值,某些测试仅 rendered/implemented/run。

这不是您要找的东西,但我认为这是一个非常接近的解决方案。您可以在主测试夹具中指定嵌套的 classes 并用不同的 TestFixture 属性装饰它们以限制什么是 运行。这可能最好用一个例子来解释。因此,给定这些数据类型:

public interface ICompetitor {
    string GetFinalPosition();
}


public class Winner : ICompetitor{
    public string GetFinalPosition() {
        return "Won";
    }
}

public class Loser : ICompetitor {
    public string GetFinalPosition() {
        return "Lost";
    }
}

我可以定义这些 TestFixtures:

[TestFixture(typeof(Winner))]
[TestFixture(typeof(Loser))]
public class CompetitorTests<T> where T : ICompetitor, new()
{
    static private T CreateSut() {
        return new T();
    }

    [Test]
    public void EverybodyHasPosition() {
        Assert.IsNotNullOrEmpty(CreateSut().GetFinalPosition());
    }

    [TestFixture(typeof(Winner))]
    public class WinnerTests {
        [Test]
        public void TestWon() {
            Assert.AreEqual("Won", CompetitorTests<T>.CreateSut().GetFinalPosition());
        }
    }

    [TestFixture(typeof(Loser))]
    public class LoserTests {
        [Test]
        public void TestLost() {
            Assert.AreEqual("Lost", CompetitorTests<T>.CreateSut().GetFinalPosition());
        }
    }
}

EverybodyHasPosition 测试是 运行 两次(一次用于 Winner,一次用于 Loser classes)。而 TestWon 对于 Winner 只有 运行 class 而 TestLost 对于 Loser 只有 运行 class.这并不理想,因为您只能访问外部 class 的静态成员,并且每个 fixture 负责它自己的 setup/teardown.

不过,您可以通过使用基数 class 来解决这个问题。因此,状态共享版本可能看起来更像这样(注意每个 TestFixture 继承自 CompetitorTestsState):

public class CompetitorTestsState<T> where T : ICompetitor, new()  {
    protected T SUT { get; private set; }

    [SetUp]
    public void Setup() {
        SUT = CreateSut();
    }

    private T CreateSut() {
        return new T();
    }
}

[TestFixture(typeof(Winner))]
[TestFixture(typeof(Loser))]
public class CompetitorTests<T> : CompetitorTestsState<T> where T : ICompetitor, new() {
    [Test]
    public void EverybodyHasPosition() {
        Assert.IsNotNullOrEmpty(SUT.GetFinalPosition());
    }

    [TestFixture(typeof(Winner))]
    public class WinnerTests : CompetitorTestsState<T>{
        [Test]
        public void TestWon() {
            Assert.AreEqual("Won", SUT.GetFinalPosition());
        }
    }

    [TestFixture(typeof(Loser))]
    public class LoserTests : CompetitorTestsState<T>{
        [Test]
        public void TestLost() {
            Assert.AreEqual("Lost", SUT.GetFinalPosition());
        }
    }
}