SetupFixture 方法未按预期顺序执行

问题描述 投票:0回答:1

描述:

[SetupFixture] 类方法 [OneTimeSetup] 和 [OneTimeTearDown] 未按预期执行。它们似乎被完全跳过或以错误的顺序执行,而不是在命名空间中的所有测试之前和之后运行一次。

背景场景:

我正在开发一个自动化测试项目,我的目标是使用 [SetupFixture] 类方法 [OneTimeSetup] 和 [OneTimeTearDown] 在全局级别初始化和刷新范围报告。目标是在测试 > 节点格式的单个报告中覆盖多个 [TestFixture] 类。为了了解这些注释的运作方式,我创建了此示例设置来测试这些属性的行为。

此外,我正在寻找一种在每个 [TestFixture] 启动之前执行方法的方法,类似于 [Setup] 对于 [Test] 方法的工作方式,但在夹具级别。我没有在代码中添加相应的逻辑,但如果有人能提出一种方法,那就太好了。

代码示例:

ExtentReportManager.cs

namespace SamplePractice.TestCases
{
    [SetUpFixture]
    public class ExtentReportManager
    {

        public ExtentReportManager() { }

        [OneTimeSetUp]
        public void OneTimeSetUp()
        {
            Console.WriteLine("Global One Time SetUp executing");
        }

        [OneTimeTearDown]
        public void OneTimeTearDown()
        {
            Console.WriteLine("Global One Time Tear Down executing");
        }
    }
}

BaseClass.cs

namespace SamplePractice.TestBase
{
    public class BaseClass
    {
        [SetUp]
        public void Init()
        {
            Console.WriteLine("Setup Executing");
        }

        [TearDown]
        public void Cleanup()
        {
            Console.WriteLine("Tear Down Executing");
        }
    }
}

测试用例:

using SamplePractice.TestBase;

namespace SamplePractice.TestCases
{
    [TestFixture, Order(1)]
    public class Class1 : BaseClass
    {
        [Test, Order(1)]
        public void Class1Test1()
        {
            Console.WriteLine("Class1 Test 1 executing");
        }

        [Test, Order(2)]
        public void Class1Test2()
        {
            Console.WriteLine("Class1 Test 2 executing");
        }
    }
}

using SamplePractice.TestBase;

namespace SamplePractice.TestCases
{
    [TestFixture, Order(2)]
    public class Class2 : BaseClass
    {
        [Test, Order(1)]
        public void Class2Test1()
        {
            Console.WriteLine("Class 2 Test 1 executing");
        }

        [Test, Order(2)]
        public void Class2Test2()
        {
            Console.WriteLine("Class 2 Test 2 executing");
        }
    }
}

我尝试的步骤:

  1. Ensured ExtentReportManager 是一个具有默认构造函数的公共类。
  2. 将 ExtentReportManager 放置在程序集命名空间中以定位整个程序集
  3. 验证运行器配置的 NUnit 版本 (3.14.0)。
  4. 使用 Visual Studio 测试运行器和 NUnit 控制台 (nunit3-console) 运行测试。

Visual Studio 测试运行器的输出:

Setup Executing
Class1 Test 1 executing
Tear Down Executing

Setup Executing
Class1 Test 2 executing
Tear Down Executing

Setup Executing
Class 2 Test 1 executing
Tear Down Executing

Setup Executing
Class 2 Test 2 executing
Tear Down Executing

NUnit 控制台的输出:

Setup Executing
Class1 Test 1 executing
Tear Down Executing
Setup Executing
Class1 Test 2 executing
Tear Down Executing
Setup Executing
Class 2 Test 1 executing
Tear Down Executing
Setup Executing
Class 2 Test 2 executing
Tear Down Executing
Global One Time SetUp executing
Global One Time Tear Down executing

预期输出:

Global One Time SetUp executing
Setup Executing
Class1 Test 1 executing
Tear Down Executing
Setup Executing
Class1 Test 2 executing
Tear Down Executing
Setup Executing
Class 2 Test 1 executing
Tear Down Executing
Setup Executing
Class 2 Test 2 executing
Tear Down Executing
Global One Time Tear Down executing

问题:

  1. 为什么 Visual Studio 测试运行器和 NUnit 控制台之间的输出存在差异?为什么[SetUpFixture]中的[OneTimeSetup]和[OneTimeTearDown]方法没有按预期执行?
  2. 如何在每个 [TestFixture] 启动之前执行一个方法,类似于 [Test] 方法的 [SetUp],但在夹具级别。

我尝试的步骤:

  1. Ensured ExtentReportManager 是一个具有默认构造函数的公共类。
  2. 将 ExtentReportManager 放置在程序集命名空间中以定位整个程序集
  3. 验证运行器配置的 NUnit 版本 (3.14.0)。
  4. 使用 Visual Studio 测试运行器和 NUnit 控制台 (nunit3-console) 运行测试。

预期输出:

Global One Time SetUp executing Setup Executing Class1 Test 1 executing Tear Down Executing Setup Executing Class1 Test 2 executing Tear Down Executing Setup Executing Class 2 Test 1 executing Tear Down Executing Setup Executing Class 2 Test 2 executing Tear Down Executing Global One Time Tear Down executing

c# .net-4.0 nunit visual-studio-2022 nunit-console
1个回答
0
投票

这是一个有趣的事情。看起来 OneTimeSetUp/TearDown 实际上运行正常,但

Console.Out
缓冲区未按正确的顺序合并。

考虑以下因素:

namespace SamplePractice.TestCases;

[SetUpFixture]
public class OneTime()
{
  public static string Status = "";

  [OneTimeSetUp]
  public void OneTimeSetUp()
  {
    Status = "ONE TIME SETUP ALREADY RUN";
    Console.WriteLine($"{DateTime.Now.TimeOfDay} Global One Time SetUp executing");
  }

  [OneTimeTearDown]
  public void OneTimeTearDown()
  {
    Console.WriteLine($"{DateTime.Now.TimeOfDay} Global One Time Tear Down executing");
  }
}

请注意,当

Status
运行时,
OneTimeSetUp
会发生变化。还有时间戳记录,这将有助于我们稍后查看输出。

namespace SamplePractice.TestCases;
public class BaseClass
{
  [SetUp]
  public void Init() => Console.WriteLine($"{DateTime.Now.TimeOfDay} Setup Executing");

  [TearDown]
  public void Cleanup() => Console.WriteLine($"{DateTime.Now.TimeOfDay} Tear Down Executing");
}

[TestFixture]
public class Class1 : BaseClass
{
  [Test]
  public void Class1Test1() => Console.WriteLine(
    $"{DateTime.Now.TimeOfDay} Test 1 executing {OneTime.Status}");
}

VS 测试运行程序输出以下内容:

17:05:16.0569102 Setup Executing
17:05:16.0572182 Test 1 executing ONE TIME SETUP ALREADY RUN
17:05:16.0575411 Tear Down Executing

nunit-console

17:13:21.2253622 Setup Executing
17:13:21.2257681 Test 1 executing ONE TIME SETUP ALREADY RUN
17:13:21.2260992 Tear Down Executing
17:13:21.2200130 Global One Time SetUp executing
17:13:21.2290333 Global One Time Tear Down executing

我们可以看到,尽管在一种情况下 OneTime 输出被吞没,而在另一种情况下它们是无序的 - 但它们显然被执行了。

时间戳证实,虽然 OneTime 内容是最后打印的,但它们实际上是按正确的顺序运行的。

© www.soinside.com 2019 - 2024. All rights reserved.