嵌套在不同类中的TestFixture

时间:2019-11-20 12:22:27

标签: c# automated-tests nunit

我正在尝试创建仅登录和注销一次的Web自动化。由于网站是由不同的产品组成的,因此我需要在不同的类/文件中构建不同的测试集(例如:ReportsTests,AuthenticationTests等)。我完全能够创建一个TestFixture,该登录和退出使用OneTimeSetupOneTimeTearDown,但每堂课都会发生一次。

我要创建的是TestFixture中的TestFixure,以这样的方式登录和注销在第一个TestFixture上发生一次,第二个执行测试集。

到目前为止,我已经知道了:

Setup.cs

using NUnit.Framework;
using System;

namespace TestsSetup
{
    [TestFixture]
    public class TestSetup
    {
        [OneTimeSetUp]
        public void Setup()
        {
            Console.WriteLine("Login in");
        }

        [OneTimeTearDown]
        public void Teardown()
        {
            Console.WriteLine("Login out");
        }
    }
}

TestSuit.cs

using NUnit.Framework;
using NUnit.Framework.Internal;
using System;
using TestsSetup;

namespace TCISuiteSetup
{
    [TestFixture]
    public class CWTestSuite : TestSetup
    {
        [TestFixture(1)]
        public class SuiteSetup
        {
            [OneTimeSetUp]
            public void Setup()
            {
                Console.WriteLine("Nothing happens on this step");
            }

            [OneTimeTearDown]
            public void Teardown()
            {
                Console.WriteLine("Nothing happens on this step");
            }
        }
    }
}

Test1.cs

using NUnit.Framework;
using NUnit.Framework.Internal;
using System;
using TCISuiteSetup;

namespace TCI.Tests
{
    [TestFixture(1)]
    public class UserManagerTests : CWTestSuite.SuiteSetup
    {
        [Test]
        public void Test1()
        {
            Console.WriteLine("Assertion");
            Assert.AreEqual(1, 1);
        }

        [Test]
        public void Test2()
        {
            Console.WriteLine("Assertion");
            Assert.AreEqual(1, 1);
        }
    }
}

test2.cs

using NUnit.Framework;
using NUnit.Framework.Internal;
using System;
using TCISuiteSetup;

namespace TCI.Tests
{
    [TestFixture(1)]
    public class ReportTests : CWTestSuite.SuiteSetup
    {
        [Test]
        public void Test1()
        {
            Console.WriteLine("Assertion");
            Assert.AreEqual(1, 1);
        }

        [Test]
        public void Test2()
        {
            Console.WriteLine("Assertion");
            Assert.AreEqual(1, 1);
        }
    }
}

如果我像这样运行测试,则所有测试都会失败。如果我从(1)中删除了TestFixture(1),它将通过所有内容,但是如果我将[OneTimeSetup]/[OneTimeTearDown]更改为UserManagerTests : TestSuite.SuiteSetup,它不会命中任何UserManager : TestSetup,它只会命中第一个[TestFixture]

我错过了什么吗?

2 个答案:

答案 0 :(得分:0)

dNesting测试夹具类对NUnit毫无意义。几年来,我们一直在谈论使它有意义,但从未对此做任何事情。

因此,就测试装置而言,CWTestSuiteCWTestSuite.SetUpFixture根本没有关系。就像它们是单独定义的,没有嵌套一样。

如果要将一个灯具分组,则NUnit提供SetUpFixture,这是一种定义适用于多个类的一次性设置和拆卸行为的方法。 SetUpFixture是为特定名称空间定义的,并且实际上包装了该名称空间和从属名称空间中定义的所有TestFixtures

例如,如果要将所有TestFixtures放在某个公共命名空间中,则可以在同一个命名空间中添加SetUpFixture,就像这样...

namespace Some.Common.Namespace
{
    [SetUpFixture]
    public class TestSetup
    {
        [OneTimeSetUp]
        public void Setup()
        {
            Console.WriteLine("Login in");
        }

        [OneTimeTearDown]
        public void Teardown()
        {
            Console.WriteLine("Login out");
        }
    }

    public class UserManagerTests
    {
        [Test]
        public void Test1()
        {
            Console.WriteLine("Assertion");
            Assert.AreEqual(1, 1);
        }

        [Test]
        public void Test2()
        {
            Console.WriteLine("Assertion");
            Assert.AreEqual(1, 1);
        }
    }

    public class ReportTests
    {
        [Test]
        public void Test1()
        {
            Console.WriteLine("Assertion");
            Assert.AreEqual(1, 1);
        }

        [Test]
        public void Test2()
        {
            Console.WriteLine("Assertion");
            Assert.AreEqual(1, 1);
        }
    }
}

请注意,在此示例中,我没有使用继承。它不是必需的,如果我用过的话会破坏东西。如果您需要一些通用的初始化逻辑来对名称空间中的某些固定装置而非全部,那么您可以为它们提供一个通用的基类,但该固定类必须与分开。 SetUpFixture,并且最好是抽象的。

作为次要说明,我删除了所有多余的[TestFixture]注释。这就是我推荐的风格。

答案 1 :(得分:0)

我找到了一种方法,但也许它不是最优雅的:

Setup.cs

using NUnit.Framework;
using System;

namespace TestsSetup
{
    [TestFixture]
    public class CWTestSuite : TestSetup
    {
        [TestFixture]
        public class SuiteSetup
        {
            static private bool isLoggedOn;

            [OneTimeSetUp]
            public void TestSuiteSetup()
            {
                if (isLoggedOn == false)
                {
                    Console.WriteLine("Loggin happens here");
                    isLoggedOn = true;
                }
            }
        }
    }

    [SetUpFixture]
    public class TestSetup
    {
        [OneTimeTearDown]
        public void Teardown()
        {
            Console.WriteLine("Login out happens here");
        }

        [TestFixture]
        public class Testing
        {
            [Test]
            public void Test1()
            {
                Console.WriteLine("All tests for this product has been executed");
            }
        }
    }
}

任何符合以下格式的test.cs

using NUnit.Framework;
using NUnit.Framework.Internal;
using System;
using static TestsSetup.CWTestSuite;

namespace TestSetup
{
    [TestFixture]
    public class UserManagerTests : SuiteSetup
    {
        [Test]
        public void Test3()
        {
            Console.WriteLine("Assertion");
            Assert.AreEqual(1, 1);
        }

        [Test]
        public void Test4()
        {
            Console.WriteLine("Assertion");
            Assert.AreEqual(1, 1);
        }
    }
}
  1. 我无法摆脱[TestFixture]中的[TestFixture](Setup.cs /公共类CWTestSuite)。如果我删除了它,它将在一个类中运行测试后击中[OneTimeTearDown]
  2. 我必须在登录步骤上添加一个标志,因为在每组测试的开始都会调用[OneTimeSetUp]
  3. 我发现触发[OneTimeTearDown]的唯一方法是在其后添加[TestFixture]/[Test]。它在最后被调用,它可能只是打印一个console.log,但是它必须存在并且需要被调用。

顺便说一句。这是一种可能的解决方案/解决方法,但根本不建议这样做。如果您想做这样的事情,我建议您使用NUnit + SpecFlow([BeforeTestRun]是您想要的。