【问题标题】:NUnit TestCaseSource null on first runNUnit TestCaseSource 首次运行时为空
【发布时间】:2021-09-24 09:48:44
【问题描述】:

使用 NUnit 和 Unity 我有一个用于测试的基类:

    [TestFixture]
    public class TestBase
    {
        private string m_filePath = "UnitTest\\response.json";

        protected static Event m_current;
        protected static Event m_expired;

        protected LoginResponse m_response;

        public static IEnumerable<TestCaseData> TestRunning
        {
            get
            {
                yield return new TestCaseData(m_expired, false);
                yield return new TestCaseData(m_current, true);
            }
        }

        [OneTimeSetUp]
        public virtual void SetUp()
        {
            string path = System.IO.Path.Combine(Application.dataPath, m_filePath);
            string txt = File.ReadAllText(path);
            m_response = JsonFx.Json.JsonReader.Deserialize<LoginResponse>(txt);

            m_expired = m_response.events[0];
            m_current = m_response.events[1];
        }

        protected class LoginResponse
        {
            public List<Event> events;
        }
    }

然后,我在使用 TestRunning 集合的子类中有一个 TestCaseSource,它会在重新编译后首次运行测试时失败。如果我再次运行测试,它们就会通过。 第一个对象在测试中为 null。

子类没有设置,所以它不会阻止调用。

【问题讨论】:

    标签: unit-testing unity3d nunit


    【解决方案1】:

    根据@Charlie 的回答,这里需要的修改解决了我的问题:

    public class TestBase
    {
        private string m_filePath = "UnitTest\\response.json";
    
        protected static Event m_current;
        protected static Event m_expired;
    
        protected static LoginResponse m_response;
    
        public static IEnumerable<TestCaseData> TestRunning
        {
            get
            {
                if(m_response == null)
                {
                    SetUpTest();
                }
                yield return new TestCaseData(m_expired, false);
                yield return new TestCaseData(m_current, true);
            }
        }
    
        [OneTimeSetUp]
        public virtual void SetUp()
        {
            SetUpTest();
        }
    
        protected class LoginResponse
        {
            public List<Event> events;
        }
        
        private static void SetUpTest()
        {
            string path = System.IO.Path.Combine(Application.dataPath, m_filePath);
            string txt = File.ReadAllText(path);
            m_response = JsonFx.Json.JsonReader.Deserialize<LoginResponse>(txt);
    
            m_expired = m_response.events[0];
            m_current = m_response.events[1];
        }
    }
    

    【讨论】:

      【解决方案2】:

      有多种方法可以解释 NUnit 在测试中执行各种操作的顺序,并具有不同的详细程度。这是可能的最高级别...

      1. 与发现测试有关的所有操作。这包括查找和解释所有提供数据的属性,包括[TestCase][TestCaseSource][Values] 等。

      2. 与执行已发现的测试有关的所有操作。这包括执行所有OneTimeSetupSetUp 方法、测试方法本身以及任何TearDownOneTimeTearDown 方法。

      在第 2 组中,关于首先执行哪些特定操作的规则相当复杂,但即使是最早的操作(例如基类 OneTimeSetUp 方法)也不会在第 1 组中的操作完成之前执行。

      这种严格排序的原因是第 1 组中的属性不仅仅为正在运行的测试提供数据以供使用。他们还确定找到了多少测试。也就是说,具有五组值的TestCaseSource 会创建五个测试,一个具有 100 组的值会创建 100 个测试。

      一旦你理解了这一点,解决方案就很简单了。您的 TestCaseSource 必须实际读取 json 文件并根据在那里找到的内容创建案例。这意味着您的源可能需要是一个方法而不是一个简单的集合。

      【讨论】:

      • 根据您的解释,我能够修复它。流程很有意义,因为测试用例在运行之前显示在检查器中,我只是没想到。非常感谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多