【问题标题】:Multiple ClassCleanup Attributes per Test Class每个测试类的多个 ClassCleanup 属性
【发布时间】:2016-04-21 20:55:28
【问题描述】:

情况:我的一些集成测试类共享一种在数据库中设置场景的通用方法,因此我提供了一个抽象基类。在所有测试运行后,它还会在最后进行完整的数据清理:

public abstract class IntegrationTests
{
    ...
    protected static void Cleanup() { ... }
}

我的继承类需要调用基本方法以确保我的基本清理代码运行:

[TestClass]
public class FooIntegrationTests : IntegrationTests
{
    ...

    [ClassCleanup]
    public static void FooCleanup()
    {
        ...
        Cleanup();
    }
}

问题:根据MSDN“[o]只有一个类中的一个方法可以用[ClassCleanup]属性修饰”,所以我不能从基类中修饰Cleanup方法即使我这样做了,该方法也不会被调用。

问题:我想要一个解决方案

  • 始终从基类运行Cleanup 方法,而不在继承的类中实现任何内容,和
  • 始终从继承的测试类运行自定义清理方法(如果有)。

我不喜欢强制继承的测试类显式调用基类,因为我必须记住实现它。我更喜欢更优雅但更简单(!)的技术。有什么想法吗?

注意:为我的基本功能提供一个由所有测试类共享的单例不起作用,因为我在多个测试代理上并行运行测试,所有测试代理都连接到同一个数据库实例。

【问题讨论】:

  • ClassCleanup 属性只能分配给静态方法。 virtual 和 override 关键字只能用于实例方法。
  • 啊,对,我在考虑通常的设置/拆卸。道歉。
  • 静态方法/类破坏了正常的继承规则。所以不,我不确定除了从继承类中调用 Cleanup 之外,您还能做些什么。

标签: c# inheritance integration-testing mstest


【解决方案1】:

根据我从 cmets 的回答,调用 ClassCleanup 不再起作用。

我在工作中一直这样做。您所要做的就是将基类也作为测试类,并在那里“花费”您的清理和拆卸属性。如果您需要在派生类中进行清理/拆卸,只需创建一个虚拟方法,您可以在需要时对其进行覆盖:

[TestClass]
public abstract class BaseIntegrationTest
{
    [TestInitialize]
    public void BeforeEach() {
        // Stuff that should happen before each unit test

        BaseTestInitialize();
    }

    [TestCleanup]
    public void AfterEach(){
        // Stuff that should happen after each unit test

        BaseTestCleanup();
    }

    public virtual void BaseTestInitialize() { }
    public virtual void BaseTestCleanup() { }
}

使用此构造,您在集成测试中所要做的就是重写 BaseTestCleanup():

[TestClass]
public class DerivedTestClass : BaseIngetrationTest
{
    public override void BaseTestCleanup()
    {
        // Derived cleanup
        base.BaseTestCleanup();
    }


    [TestMethod]
    public void SomeMethod_SomeCriteria_SomeResult()
    {
        // Arrange

        // Act

        // Assert
    }
}

【讨论】:

  • 如果您需要为每个测试进行初始化和/或清理,这是一个好主意。不幸的是,这种方法会导致 集成 测试出现严重的性能问题:设置和清理数据场景非常繁重,每个类运行数十或数百次的成本太高。
  • 我通常用 testcategory 标记我的集成测试,所以它们只在晚上运行,当然当有人使用它们时运行。在我的持续集成中,我从不做任何类型的 IO(包括磁盘)的测试。
  • 我们也是这样做的:集成测试每天只运行两次,并且根据要求运行。但是,数据设置可能会花费数秒时间 - 测试套件会运行数小时,我们必须为每个测试重新创建和删除场景。
  • 我同意,但这在很大程度上取决于产品。我目前在大约 14 秒内运行了大约 6000 个单元测试。集成测试运行大约需要 20 分钟。它们都使用基类初始化器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多