NUnit не подчиняется наследованию атрибута
У меня проблема с NUnit - интересно, есть ли у кого-нибудь идеи.
Мы используем NUnit 2.5.3.9345 и С# 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]
в производном классе.
Любые идеи, пожалуйста? Я действительно озадачен!
Спасибо.
Ответы
Ответ 1
У меня нет проблемы. Я проверил результат со следующим:
Производный тест
[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 и Nunit GUI v 2.5.3.9345 (32-разрядный)
Edit
Во время работы тестовый бегун в ReSharper 4.5 работал некорректно, однако запускал встроенный тестовый проект в x86 и x64 с соответствующим выходом NUnit.exe/NUnit-86.exe.
Ответ 2
Обходной путь/другой способ сделать это:
Вместо того, чтобы полагаться на поведение, которое не сразу понятно, сделайте что-то подобное, вместо этого используйте шаблон шаблона шаблона, чтобы сделать упорядочение явным, используя обычные языковые функции:
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
}
}
В любое время, когда у меня были причины использовать унаследованные приборы или тестовые контексты, этот способ работал достаточно хорошо.:)
Моя проблема с атрибутами заключается в том, что, поскольку эти типы создаются и вызывается через отражение в бегуне без какой-либо связи между методами (без полиморфизма), сложнее рассуждать о порядке, в котором они вызваны. Использование стандартных функций языка немного упрощает это.
Ответ 3
Вы пытались присвоить базовому классу атрибут [TestFixture]? Я не знаю, что это исправит, но похоже, что стоит попробовать... идея в том, что NUnit может игнорировать атрибуты базового класса, если это не TestFixture.
Ответ 4
Да, я играл с этим последние полчаса, и это определенно ошибка. Я пробовал добавлять TestFixture ко всем классам, а также иметь разные комбинации. Я также пробовал статические методы и методы экземпляра. Кажется, он просто не хочет играть красиво!: - (
Во всяком случае, наилучшим обходным решением, которое я смог найти, является поместить код TestFixtureSetUp в конструкторы вашего тестового класса и базового класса. По крайней мере, тогда вы можете быть уверены в наследовании, и это более понятно другим читателям вашего кода, которые, возможно, не знают внутренней работы NUnit: -)
Ответ 5
С чем вы работаете? Поведение, которое вы испытываете, не связано с NUnit (фреймворком), а не с бегуном, которым вы пользуетесь. Используете ли вы встроенный testrunner для Resharper?