Наследование тестовых приспособлений и игнорируемые базовые тестовые приспособления

у меня есть набор базовых тестов, используемых для диагностики множественных реализаций интерфейса. Кстати я modelelled этом создавая основной текст приспособление с атрибутом [игнорировать].

[TestFixture]
[Ignore]
public class BaseTests
{
     // Use your imagination for the actual name
     public virtual ITestableThing GetConcrete()
     {
         return null;
     }

     // All of my unit tests here
}

и затем я пишу подкласс для каждой реализации интерфейса:

public class ConcreteThingTests :  BaseTests
{
    public override ITestableThing GetConcrete()
    {
        return new ConcreteThing();
    }
}

это хорошо работает, так как у меня есть все тесты для всех реализаций в одном месте, а подклассы просто указывают реализацию.

проблема в том, что я должен поставить [Ignore] атрибут в базовом классе, или NUnit попытается запустить тесты (и потерпит неудачу).

Итак, я неправильно реализую наследование тестового приспособления?

2 ответов


обычно вы устанавливаете атрибуты теста в конкретных тестовых классах, а не в базовом классе.

поскольку вы, похоже, тестируете одну и ту же функциональность для нескольких классов, вы можете пропустить всю иерархию тестов и ввести конкретные классы для тестирования в этот тест-baseclass.

для этого с помощью NUnit вы можете использовать атрибут TestCaseSource с методом фабрики классов в качестве параметра. Пример этого можно найти здесь:как пройти объекты в функцию NUnit TestCase?

составляя некоторый код для вашего конкретного случая, это может быть показано ниже:

/// <summary>
/// Earlier known as your BaseTests class
/// </summary>
[TestFixture]
public class TestOfConcreteImplementationsOfInterface
{
    [TestCaseSource("CreateConcretes")]
    [Test]
    public void VerifyImplementations(IWhatever thing)
    {
        int input = 42;
        int result = thing.DoSomething(input);
        Assert.That(result, Is.EqualTo(input));
    }

    /// <summary>
    /// Factory method for the concrete classes.  If you want this in a seperate class, you can do that too using the 
    /// ctor public TestCaseSourceAttribute(Type sourceType, string sourceName);
    /// </summary>
    public IEnumerable<IWhatever> CreateConcretes
    {
        get
        {
            yield return new A();
            yield return new B();
        }
    }
}

public interface IWhatever
{
    int DoSomething(int x);
}

public class A : IWhatever
{
    public int DoSomething(int x)
    {
        return x;
    }
}

public class B : IWhatever
{

    public int DoSomething(int x)
    {
        return x;
    }
}

бегун теста NUnit, похоже, игнорирует базовый класс, если он помечен абстрактно:

public abstract class BaseTests
{
}