取消测试后清理

本文关键字:测试 取消 | 更新日期: 2023-09-27 17:55:16

我目前正在通过Visual Studio运行测试。在运行所有测试之前,我会自动创建一定数量的具有已知凭据的用户,并在运行结束时删除这些用户。但是,有时我需要中途取消测试。在这些情况下,测试永远不会有机会清理,这意味着测试运行中会留下虚假的用户信息,并可能导致下一次测试运行崩溃(当它尝试将用户信息添加到数据库中时)。即使测试被取消,是否有强制Visual Studio/mstest运行清理方法?

我知道一种选择是进行测试检查并确保用户信息不存在,以及是否确实在创建新用户之前将其删除。但这仍然不能解决取消测试运行留下不需要的测试数据的问题。

更新:

很抱歉沟通不畅,但是在测试开始时清理数据不是一种选择。我对这个问题给出了一个非常简单的观点,但简单地说,我没有简单的方法来确保在测试开始时不存在测试数据。所有清理都必须在测试结束时进行。

取消测试后清理

这是不可能的。您最好找到一个替代解决方案,例如使用单独的数据库进行测试,并在每次测试运行之前清理所有数据,使用固定的测试用户集或使用一些标志标记测试数据。查看 Jimmy Bogard 的文章《在集成测试中隔离数据库数据》。

没有内置方法可以更改 MSTest 默认行为。理论上,您可以编写利用TestExecution.OnTestStopping事件的 MSTest 扩展,但这不是一个简单的过程,它需要更改注册表。而且,很多人抱怨它不起作用。

还有MSTest V2,这是MSTest的新版本,具有新的扩展点。但看起来你不能用这个点改变取消行为,只能写属性装饰器。请参阅扩展 MSTest v2。

不能使用AppDomain.CurrentDomain.ProcessExitProcess.GetCurrentProcess().Exited事件,因为取消似乎会终止测试运行过程。

NUnit目前也不支持此功能。请参阅相关的 NUnit 测试适配器在 VS 上运行拆卸 取消测试运行问题。

我不是在测试结束时调用清理函数,而是在每次测试开始时调用我的函数,以解决这个确切的问题。

在创建数据之前也执行清理,这将确保您无论发生什么都没有剩余数据。当然,这只有在运行安装程序之前可以识别任何剩余数据时才有可能。

这个想法是在测试开始之前初始化事务。为了将数据保存在数据库中,必须提交事务,但不会从不提交事务。它在测试停止的情况下起作用,在成功或失败的情况下完成测试。

在集成测试中,我们使用这样的东西(使用 NUnit)(它真正的生产代码)

public class RollbackAttribute : TestAttribute, ITestAction
{
    private TransactionScope _transaction;
    public void BeforeTest(ITest test)
    {
        _transaction = new TransactionScope();
    }
    public void AfterTest(ITest test)
    {
        _transaction.Dispose();
    }
    public ActionTargets Targets => ActionTargets.Test;
}
[TestFixture]
public class SomeTestClass
{
    [Rollback] //No need [Test] because Rollback is inherit it.
    public void SomeTestMethod()
    {
    }
}

在 MsTest 上,您可以制作类似的东西,但在这种情况下,您应该从基类继承,我希望它有效。例如:

public class RollbackTestBase
{
    private TransactionScope _transaction;
    [TestInitialize]
    public virtual void Setup()
    {
        _transaction = new TransactionScope();
    }

    [TestCleanup]
    public virtual void TearDown()
    {
        _transaction.Dispose();
    }
}
[TestClass]
public class IntegrationTest : RollbackTestBase
{
    [TestMethod]
    public void TestDataBase()
    {
        Assert.IsTrue(true);
    }
    [TestInitialize]
    public virtual void Init()
    {
    }
    [TestCleanup]
    public virtual void CleanUp()
    {
    }
}

在 ATP 中分配资源时,我们需要考虑 2 种情况(资源可能是创建用户、与数据库的连接)。他们是

  • 每次测试后创建和删除资源。
  • 一组测试后创建和删除资源。

每次测试后创建和删除资源:

如果我们想在执行测试之前创建特定对象的实例,并希望在执行该测试后清理分配给该对象的内存,那么我们使用 NUnit 的Test SetUpTest TearDown属性。在您的情况下,对象是创建用户数量。

[SetUp]:使用Test SetUp属性修饰的函数包含在执行任何测试之前执行的代码段。

[TearDown]:用测试拆卸属性修饰的函数包含在任何测试执行后执行的代码段

实现:

[TestClass]
    public class UnitTest1
    {
        [SetUp]
        public void SetUP()
        {
            // Creating Users with proper credentials
        }
        [TestMethod]
        public void TestMethod1()
        {
            //Write your ATP
        }
        [TearDown]
        public void TearDown()
        {
            //Clean up
        }
    }

一组测试后创建和删除资源:

现在,如果我们想为一组测试创建一个对象的实例,并希望在执行所有测试后清理内存,那么[TestFixtureSetUp][TestFixureTearDown]分别初始化对象和清理内存。同样,在您的情况下,对象可以是创建一组用户。

[TestFixtureSetUp] :用TestFixtureSetUp修饰的函数将在执行一组测试之前执行一次。

[TestFixtureTearDown] :用TestFixtureTearDown修饰的函数将在执行一组测试执行一次。

实现

[TestFixture]
public class Tests
{
        [TestFixtureSetUp]
        public void Setup()
        {
           //Create users with credentials
        }
        [Test]
        public void _Test1()
        {
          //Test_1
        }
        [Test]
        public void _Test2()
        {
         //Test2
         }
        [TestFixtureTearDown]
        public void CleanUp()
        {
            //Cleanup; Here you need to add code to Delete all users
        }
}

注意:我建议您,如果您尝试为特定ATP创建和删除用户,请使用SetUpTearDown。如果您正在尝试对一堆ATP进行相同的尝试,我建议您使用TestFixtureSetUpTestFixtureTearDown

"如果您的测试通过或失败,将执行设置和拆卸功能"

引用:

  • @Shuvra的回答。

  • Nunit:设置,拆卸,设置固定装置,拆卸夹具

我认为您应该在测试之前打开交易,创建数据并完成测试测试。但不要提交事务。这将确保测试根本不会影响您的数据库。

更新:更简单的方法是使用 docker 容器。可以从映像运行容器,并在测试完成后删除该容器。这绝对应该降低测试的复杂性。

Visual Studio使用NUNIT,因此,您可以使用TearDownAttribute。它应该在测试后运行,即使测试被取消。您可以编写一个函数来清理数据。

请阅读此处的参考文档:http://nunit.org/docs/2.2/teardown.html

只是为了清除更多关于NUNIT标准的信息。请按照测试类中的步骤操作:

[TestFixture]
public class _TestClass
{
        [TestFixtureSetUp]
        public void Setup()
        {
           //Clearup can be here before start of the tests. But not Recommended
        }
        [Test]
        public void _Test1()
        {
        }
        [Test]
        public void _Test2()
        {
        }
        [TestFixtureTearDown]
        public void CleanUp()
        {
            //I will recommend to clean up after all the tests complete
        }
}

参考: http://nunit.org/docs/2.5/fixtureTeardown.html

使用所谓的"数据库模拟"来解决这个问题的更好方法。在这种情况下,您将使用不同的数据库(或虚假的虚拟数据库)运行测试。

本文介绍如何在 C#
中实现它https://msdn.microsoft.com/en-us/library/ff650441.aspx

您应该开始事务,而不是将记录提交到数据库。因此,会话结束时,您的所有更改将自动回滚。