【问题标题】:NUnit not obeying attribute inheritanceNUnit 不服从属性继承
【发布时间】:2010-02-23 22:38:51
【问题描述】:

我有一个关于 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
    }
}

根据documentation,如果我运行SomeTestClass.SomeTest()UnitTestBase.SetUpTestFixture()应该在SomeTestClass.FixtureSetUp()之前被调用。

情况并非如此 - 仅当我未在派生类中提供 [TestFixtureSetUp] 方法时才会调用基方法。

有什么想法吗?我是不是真的很困惑!

谢谢。

【问题讨论】:

标签: c# unit-testing nunit


【解决方案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));
    }
}

测试库

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 位)测试输出

编辑 在工作时,ReSharper 4.5 中的测试运行器无法正常运行,但是在 x86 和 x64 中使用相应的 NUnit.exe/NUnit-86.exe 运行构建的测试项目会产生有效的输出。

【讨论】:

  • 您是否使用过 ReSharper 5?
  • 是的,我在家里使用 beta 5。
  • 将此标记为答案 - 看起来像 ReSharper 和 TeamCity 问题 - 迫切需要更新我们的 ReSharper(一旦 5 发布)和 TeamCity NUnit 插件,以便我可以充分利用此功能。
【解决方案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
    }
}

任何时候我有理由使用继承的固定装置或测试上下文,这种方式已经足够好用了。 :)

我依赖属性的问题是,由于这些类型是通过运行器中的反射创建和调用的,方法之间没有关系,(没有多态性)很难推断它们被调用的顺序。使用标准语言功能有助于稍微简化这一点。

【讨论】:

  • 我确实认为这是处理这种情况的好方法,是的 - 我只是非常喜欢使用 NUnit 的内置功能。排序不是太大的问题,只要我只在基类中定义每个方法之一,在派生类中定义每个方法 - 这样就可以保证排序(前提是在设置过程中没有抛出异常/拆解)
【解决方案3】:

您是否尝试过为基类赋予 [TestFixture] 属性?我不知道这会解决它,但它似乎值得一试......这个想法是 NUnit 可能会忽略基类上的属性,如果它不是 TestFixture。

【讨论】:

  • 是的,与我们在基类上没有 [TestFixture] 的行为相同。如果我从派生类方法中删除 [TestFixtureSetUp] 属性,则调用基类。
【解决方案4】:

是的,过去半小时我一直在玩这个,这绝对是一个错误。我已经尝试将 TestFixture 添加到所有类以及具有不同的组合。我也尝试过静态和实例方法。就是不想好好玩啊! :-(

无论如何,我能找到的最佳解决方法是将 TestFixtureSetUp 代码放在测试类和基类的构造函数中。至少这样您就可以对继承充满信心,并且对于您的代码的其他可能不了解 NUnit 内部工作原理的读者来说更清楚:-)

【讨论】:

  • 顺便说一句,我在 NUnit v2.5.0.9122 上尝试过它,它也不适用于这个版本,所以这不是最近引入的东西。
  • 在 NUnit Windows 应用程序中尝试过并使用 Resharper 运行器,但均未成功。 :-(
  • 我刚刚从 Marks answer 运行了确切的代码,它只输出派生类的测试输出,没有来自基类的输出。我现在开始抓住稻草,但我刚刚注意到他正在运行 32 位。我正在运行 64 位。这可能是导致不同结果的差异吗?
  • 也许您可以尝试在 x86 中构建并尝试使用 nunit-x86 gui 运行程序来查看 64 位版本是否导致问题。
  • 不,刚刚在 32 位机器上尝试过,遇到了同样的问题。 :-(
【解决方案5】:

你用什么来运行你的测试?您遇到的行为与 NUnit(框架)无关,而是与您正在使用的跑步者有关。你在使用 Resharper 集成测试运行器吗?

【讨论】:

  • 我已经尝试过 NUnit GUI 和 Resharper 运行器,结果相同。
  • 如果您将 TestFixtureTearDown 放在基础或派生或两者上,这会改变什么吗?
  • 似乎使用 NUnit 2.5.3 GUI 可行,而 ReSharper 5 beta 2 可行。 ReSharper 4.5.1 似乎是问题所在,以及我们构建的 TeamCity (5.0.10669)
猜你喜欢
  • 2014-02-03
  • 1970-01-01
  • 2023-03-16
  • 2016-02-15
  • 1970-01-01
  • 2017-08-10
  • 2019-06-12
  • 2023-03-12
  • 2013-09-02
相关资源
最近更新 更多