跳过通用测试中特定类型的测试方法 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());
}
}
}
我正在尝试对项目的一部分进行单元测试;我正在使用 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());
}
}
}