Модульное тестирование наследования - PullRequest
11 голосов
/ 12 февраля 2009

У меня вопрос по модульному тестированию. Допустим, у меня есть несколько классов, которые наследуют поведение от родительского класса. Я не хочу проверять все дочерние классы на это поведение. Вместо этого я бы протестировал родительский класс. Однако я также должен предоставить тест, подтверждающий, что поведение доступно в дочерних классах. Вы думаете, что-то вроде Assert.IsTrue (новый ChildClass () - это ParentClass) имеет смысл?

Ответы [ 7 ]

9 голосов
/ 12 февраля 2009

Если вы используете современную среду модульного тестирования, я не понимаю утверждения

Я не хочу проверять все дочерние классы на это поведение.

Ваши модульные тесты (написанные для экземпляра родительского класса) должны работать без изменений, если вы вручите им экземпляр дочернего класса, при условии , что ваш дочерний класс не имеет переопределяет некоторые аспекты поведения родителя таким образом, что нарушает контракт на унаследованные методы. И это именно то, что вам нужно тестировать, не так ли?

Если вас беспокоит время, необходимое для запуска тестов, я бы перепроверил, чтобы убедиться, что ваши тесты разбиты на разделы так, что вы можете выборочно запускать тесты в зависимости от того, над чем вы активно работаете (но по-прежнему периодически запускайте полный портфель для обнаружения непреднамеренных зависимостей.)

8 голосов
/ 12 февраля 2009

Я думаю, что написание теста на наследование - пустая трата времени. Компилятор проверит, доступны ли методы базового класса, если вы попытаетесь их использовать, предполагая, что вы не перехватываете с intellisense. Вероятно, я бы протестировал поведение в одном дочернем классе, а затем только в каждом дочернем классе, который изменяет поведение (или какое-либо состояние, от которого зависит поведение).

7 голосов
/ 11 января 2011

заставляет ваши тесты наследоваться от теста базового класса, что-то [очень] примерно так.

public class MyBaseClass
{
    public virtual void DoStuff() { }
    public virtual void DoOtherStuff() { }
}

public class MySubClass : MyBaseClass
{
    public override void DoOtherStuff()
    {
        // different to to base
    }
}

public abstract class TestOfBaseClass
{
    protected abstract MyBaseClass classUnderTest { get; }

    [TestMethod]
    public void TestDoStuff()
    {
        classUnderTest.DoStuff();
        Assert.StuffWasDone();
    }
}

[TestClass]
public class WhenSubclassDoesStuff : TestOfBaseClass
{
    protected override MyBaseClass classUnderTest
    {
        get { return new MySubClass(); }
    }

    [TestMethod]
    public void ShoudDoOtherStuff()
    {
        classUnderTest.DoOtherStuff();
        Assert.OtherStuffDone();
    }
}

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

или, может быть, посмотрите на что-то вроде https://github.com/gregoryyoung/grensesnitt

5 голосов
/ 12 февраля 2009

Вы не хотите проверять тип объекта, , если не выходит из нетипизированного фабричного метода. В противном случае вы пишете модульный тест на компиляторе C #, а это не то, что вы хотите.

1 голос
/ 09 июня 2015

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

тогда у вас должен быть Class TestCar, который наследуется от Class TestVehicle

Выполнение этой тестовой машины автоматически наследует правильные тесты для всех тестов транспортных средств. Это означает, что если функция переопределена в автомобиле, она, скорее всего, прервет тест, подчеркнув, что в автомобиле необходим переопределенный тест для поддержки нового поведения, тест не сломан, тогда переопределение было, вероятно, излишним

например

class Vehicle
{
    public virtual bool LicenceRequired
    {
        get{throw new NotImplmentedException()
    }
}
class Bicycle:Vehicle
{
    public override bool LicenceRequired
    {
        get{return false;}
    }
}
class Car:Vehicle
{
    public override bool LicenceRequired
    {
        get{return true;}
    }
}
class TestVehicle
{
    public virtual Void LicenceRequiredTest()
    {
        Try
        {
            LicenceRequired
            Assert.Fail();
        }
        Catch(){}
    }
}
class TestBicycle:TestVehicle
{
    public override void LicenceRequiredTest()
    {
        Assert.IsFalse(LicenceRequired);
    }
}
class TestCar:TestVehicle
{
    public override void LicenceRequiredTest()
    {
        Assert.IsTrue(LicenceRequired);
    }
}

ПРИМЕЧАНИЕ: Наследование следует использовать только при тестировании унаследованных объектов, а не только потому, что вы хотите выполнить один и тот же тест на 10 не связанных объектах. если вы хотите сделать это, я бы предложил статический вспомогательный класс

1 голос
/ 12 февраля 2009

Компилятор C # позаботится о такой проверке.

Если вам нравится, вы можете написать что-то вроде:

ParentClass childClass = new ChildClass()
var testOutput = childClass.ParentMethod();
Assert.IsNotNull(testOutput);
0 голосов
/ 12 февраля 2009

Существует два подхода, которые можно использовать для проверки поведения базового класса:

  1. Создайте реализацию-заглушку базового класса и выполните модульное тестирование заглушки. Только тестируйте общедоступные методы. Бессмысленно проверять ваши закрытые и защищенные методы, так как они будут использоваться публичными методами, которые вы должны тестировать в своих подклассах. Этот подход не гарантирует, что ваши реализации базового класса не отслеживают поведение неправильно.
  2. Создайте тестовый суперкласс для ваших модульных тестов, который использует методы базового класса. Всякий раз, когда вы тестируете подкласс вашего базового класса, пусть ваш тестовый класс наследуется от вашего суперкласса. Такой подход гарантирует, что вы случайно не изменили поведение базового класса, но ограничивает гибкость вашего теста.

Не беспокойтесь, чтобы убедиться, что наследование действительно работает (вся вещь Assert.IsTrue(new ChildClass() is ParentClass)). Вы должны только проверить поведение. Это структурная особенность платформы .Net (наследование), и вы должны верить, что она работает, иначе вы окажетесь в нисходящей спирали проверки возможностей инфраструктуры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...