【问题标题】:Using Nunit with TestCaseSource - running multiple times changes results将 Nunit 与 TestCaseSource 一起使用 - 多次运行会改变结果
【发布时间】:2014-03-12 01:50:29
【问题描述】:

我正在使用 Nunit 为 C# 项目编写单元测试。

我正在尝试使用 TestCaseSource 属性使用不同的数据多次运行单个测试。

我在其他地方执行此操作没有任何问题,但现在我发现我第一次运行测试时,代码通过了。下一次,就不行了。使用一些Console.WriteLine 语句,我可以看到测试数据每次都不一样。

用于生成数据的方法是测试类内部的,不是静态的,它会为每个测试从头开始生成所有必需的依赖项。

--

我有一个假类,它包含一个值队列,以便在调用给定函数时返回。为每个测试创建一个新类。

但是,如果第一次运行测试,它会耗尽队列,下次运行时,找不到数据。这肯定应该每次都重新生成吗?

--

就好像每次运行测试时 Nunit 都没有调用 TestCaseSource 属性指定的方法——仅在项目首次加载时。

这是预期的吗?有解决办法吗?

编辑:

好的,下面是一个非常基本的示例:

[TestFixture]
public class Tests
{
    public interface IEntry
    {
        object Read();
    }

    [TestCaseSource("TestData")]
    public void Test(Mock<IEntry> entry)
    {
        object o = entry.Object.Read();
        object o2 = entry.Object.Read();
    }

    public System.Collections.IEnumerable TestData()
    {
        var entry = new Mock<IEntry>();

        int call = 0;

        entry.Setup(x => x.Read()).Returns(() =>
        {
            Console.WriteLine(call);
            return null;
        }).Callback(() =>
        {
            call++;
        });

        yield return new TestCaseData(entry);
    }
}

如果您在 Nunit 中查看测试输出,它应该始终显示 0,然后显示 1。在这种情况下,每次运行测试时,它都会递增。 IE。第二轮:2和3,第三轮:4和5等

如果您将TestData 代码移动到Test,则每次都会返回正确的值。

【问题讨论】:

  • 你能告诉我们你的代码吗?
  • 我添加了一个使用 Moq 的简单示例,它演示了相同的问题。

标签: c# nunit


【解决方案1】:

我假设您使用的是 NUnit GUI 运行器?

您所看到的是(我相信,我无法在 NUnit 源代码中轻松找到确认)是对测试运行器的优化。它不会在每次测试运行时重新创建 TestCaseSource 属性提供的值,而是仅在被测程序集更改时才这样做。

如果您更改代码以删除 Moq 依赖项,则更清晰一些:

[TestFixture]
public class SampleTests
{
    [TestCaseSource("TestData")]
    public void Test(CallTracker callTracker)
    {
        callTracker.Call++;
        callTracker.Call++;
    }

    public IEnumerable TestData()
    {
        yield return new TestCaseData(new CallTracker());
    }

    public class CallTracker
    {
        int call;

        public int Call
        {
            get
            {
                return call;
            }
            set
            {
                call = value;
                Console.WriteLine(call);
            }
        }
    }
}

这会产生与您的代码相同的行为。每当评估 TestCaseSource 时,就会重新创建 CallTracker,但由于调用次数不断增加,因此测试运行程序必须重新执行相同的实例(我假设是性能原因)。

Resharper 在 Visual Studio 中的测试运行程序没有表现出这种行为;它总是显示12 重复运行而无需重新编译。这可能就是开始运行测试比 NUnit GUI 运行器慢的原因。同样,NUnit 控制台也不会出现这种行为,因为它总是冷启动。

【讨论】:

    猜你喜欢
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多