NUnit не подчиняется атрибуту наследования - PullRequest
11 голосов
/ 24 февраля 2010

У меня проблема с NUnit - интересно, есть ли у кого-нибудь идеи.

Мы используем NUnit 2.5.3.9345 и C # 3.5.

Возьмите следующий код:

public class UnitTestBase
{
    [TestFixtureSetUp]
    public void SetUpTestFixture()
    {
        //Do something in base
    }
}

[TestFixture]
public class SomeTestClass : UnitTestBase
{
    [TestFixtureSetUp]
    public void FixtureSetUp()
    {
        //Do something in test class
    }

    [Test]
    public void SomeTest()
    {
        //Some assertion
    }
}

Согласно документации , если я запускаю SomeTestClass.SomeTest(), UnitTestBase.SetUpTestFixture() должен быть вызван до SomeTestClass.FixtureSetUp().

Это не так - базовый метод будет вызван, только если я не предоставлю [TestFixtureSetUp] метод в производном классе.

Есть идеи, пожалуйста? Я действительно озадачен!

Спасибо.

Ответы [ 5 ]

2 голосов
/ 24 февраля 2010

У меня нет проблемы. Я проверил результат со следующим:

Производный тест

[TestFixture]
public class DerivedTest : TestBase
{

    [TestFixtureSetUp]
    public void FixtureSetup()
    {

        File.AppendAllText("Out.txt", string.Format("TestFixtureSetUp From DerivedTest{0}", Environment.NewLine));
    }

    [TestFixtureTearDown]
    public void FixtureTearDown()
    {
        File.AppendAllText("Out.txt", string.Format("TestFixtureTearDown Down From DerivedTest{0}", Environment.NewLine));
    }

    [SetUp]
    public void Setup()
    {
        File.AppendAllText("Out.txt", string.Format("Setup From DerivedTest{0}", Environment.NewLine));
    }
    [TearDown]
    public void Down()
    {
        File.AppendAllText("Out.txt", string.Format("TearDown From DerivedTest{0}", Environment.NewLine));
    }

    [Test]
    public void DoATest()
    {
        File.AppendAllText("Out.txt", string.Format("Did a Test{0}", Environment.NewLine));
    }
}

TestBase

public class TestBase
{

    [TestFixtureSetUp]
    public void BaseTestFixtureSetUp()
    {
        File.AppendAllText("Out.txt", string.Format("TestFixtureSetUp From TestBase{0}", Environment.NewLine));
    }

    [TestFixtureTearDown]
    public void BaseTestFixtureTearDown()
    {
        File.AppendAllText("Out.txt", string.Format("TestFixtureTearDown From TestBase{0}", Environment.NewLine));
    }

    [SetUp]
    public void BaseSetup()
    {
        File.AppendAllText("Out.txt", string.Format("Setup From TestBase{0}", Environment.NewLine));
    }

    [TearDown]
    public void TearDown()
    {
        File.AppendAllText("Out.txt", string.Format("TearDown From TestBase{0}", Environment.NewLine));
    }
}

Это дает следующий вывод:

TestFixtureSetUp From TestBase
TestFixtureSetUp From DerivedTest
Setup From TestBase
Setup From DerivedTest
Did a Test
TearDown From DerivedTest
TearDown From TestBase
TestFixtureTearDown Down From DerivedTest
TestFixtureTearDown From TestBase

Я смог протестировать вывод с помощью ReSharper 5 beta и Nunit GUI v 2.5.3.9345 (32-bit)

Редактировать Во время работы тестовый прогон в ReSharper 4.5 не работал должным образом, однако при запуске встроенного тестового проекта в x86 и x64 с соответствующим NUnit.exe / NUnit-86.exe выдали действительный вывод.

1 голос
/ 24 февраля 2010

Обходной путь / другой способ сделать это:

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

public class UnitTestBase
{
    protected abstract void PerFixtureSetUp();

    [TestFixtureSetUp]
    public void SetUpTestFixture()
    {
        PerFixtureSetUp();
    }
}

[TestFixture]
public class SomeTestClass : UnitTestBase
{
    protected override void PerFixtureSetUp()
    {

    }

    [Test]
    public void SomeTest()
    {
        //Some assertion
    }
}

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

Моя проблема с опорой на атрибуты состоит в том, что, поскольку эти типы создаются и вызываются посредством отражения в средстве выполнения без связи между методами, (без полиморфизма) сложнее рассуждать о порядке их вызова. Использование стандартных языковых функций помогает немного упростить это.

0 голосов
/ 24 февраля 2010

С чем вы проводите свои тесты? Поведение, которое вы испытываете, не связано с NUnit (каркасом), а с бегуном, которого вы используете. Используете ли вы интегрированный тестер Resharper?

0 голосов
/ 24 февраля 2010

Да, я играл с этим последние полчаса, и это определенно ошибка. Я попытался добавить TestFixture ко всем классам, а также с различными комбинациями. Я также попробовал статические и методы экземпляра. Кажется, просто не хочется играть красиво! : - (

В любом случае, лучший обходной путь, который я могу найти, - это поместить код TestFixtureSetUp в конструкторы вашего тестового класса и базового класса. По крайней мере, тогда вы можете быть уверены в наследовании, и это станет более понятным для других читателей вашего кода, которые, возможно, не знают внутреннюю работу NUnit: -)

0 голосов
/ 24 февраля 2010

Вы пытались дать базовому классу атрибут [TestFixture]? Я не знаю, что это все исправит, но, похоже, стоит попробовать ... идея в том, что NUnit может игнорировать атрибуты базового класса, если это не TestFixture.

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