Visual studio 2008 为什么在同一测试项目程序集中要调用[AssemblyInitialize]和[AssemblyCleanup]两次?

Visual studio 2008 为什么在同一测试项目程序集中要调用[AssemblyInitialize]和[AssemblyCleanup]两次?,visual-studio-2008,unit-testing,mstest,integration-testing,Visual Studio 2008,Unit Testing,Mstest,Integration Testing,我认为这些属性的全部目的是每个程序集只运行一次。我有一个简单的类,如下所示: [TestClass] public class AssemblyIntegrationTestSetup { public AssemblyIntegrationTestSetup() { } public TestContext TestContext { get; set; } [AssemblyInitialize] public static void SetupIntegr

我认为这些属性的全部目的是每个程序集只运行一次。我有一个简单的类,如下所示:

[TestClass]
public class AssemblyIntegrationTestSetup
{
    public AssemblyIntegrationTestSetup() { }
    public TestContext TestContext { get; set; }

    [AssemblyInitialize]
    public static void SetupIntegrationTests(TestContext context)
    {
         WindowsServiceService.Instance.StartService("Distributed Transaction Coordinator");
    }

    [AssemblyCleanup]
    public static void TeardownIntegrationTests()
    {
          WindowsServiceService.Instance.StopService("Distributed Transaction Coordinator");
    }

}
但是,当我运行测试套件时,程序集级别的初始化和清理方法会执行两次。以下是有关我的环境的详细信息:

  • 所有测试类都在同一项目/程序集中
  • 我使用名称空间分隔集成和单元测试
  • 对于集成测试,我使用MSTextExtensions来允许回滚数据库事务
  • 我还在启动/停止MS SQL Server DTC服务,这是回滚功能所必需的。我希望在每次测试套件运行时都这样做一次(我发现最好的折衷办法是使用程序集级属性)。代码可以工作,但执行两次
  • 如果有必要的话,我在一些测试中也使用了MicrosoftMoles框架
  • 观察到的行为类似于:

    AssemblyInitialize         
    
    Class1.TestInitialize
    Class1.TestMethod1
    Class1.TestCleanup
    
    AssemblyInitalize         <-- //This shouldn't be happening right?
    
    Class2.TestInitialize
    Class2.TestMethod1
    Class2.TestCleanup
    
    Class2.TestInitialize
    Class2.TestMethod2
    Class2.TestCleanup
    
    Class5.TestInitialize
    Class5.TestMethod1
    Class5.TestCleanup
    
    Class7.TestInitialize
    Class7.TestMethod1
    Class7.TestCleanup
    
    //More random bouncing around then...
    
    AssemblyCleanup 
    AssemblyCleanup           <-- //This shouldn't be happening right?
    
    AssemblyInitialize
    第一类:测试初始化
    类别1.测试方法1
    类别1.测试清理
    
    MSDN库文章中的AssemblyInitialize:

    重要

    此属性不应在上使用 ASP.NET单元测试,即任何测试 具有[HostType(“ASP.NET”)]属性。 因为IIS是无状态的 和ASP.NET,一种用 此属性可能被称为“更多” 每次测试运行不超过一次


    在TestRunner中可以调整的旋钮很少。我会用一个计数器来解决这个问题:

    private int InitCount;
    
    [AssemblyInitialize]
    public static void SetupIntegrationTests(TestContext context)
    {
         if (InitCount++ == 0) {
             WindowsServiceService.Instance.StartService("Distributed Transaction Coordinator");
         }
    }
    
    [AssemblyCleanup]
    public static void TeardownIntegrationTests()
    {
          if (--InitCount == 0) {
              WindowsServiceService.Instance.StopService("Distributed Transaction Coordinator");
          }
    }
    

    好吧,根据最初的问题日期,这个答案晚了八千万年,但是

    我发现,如果测试代理(QTAgent32.exe)在整个序列完成之前崩溃或死亡,则会再次调用AssemblyInitialize(可能还有ClassInitialize和TestInitialize)。例如,将其放入[AssemblyCleanup]函数中,您将看到出现以下行为:

    Process p = AutotestShared.RunProcess("cmd", "/c taskkill /t /f /im QTAgent32.exe", true);
    p.WaitForExit();
    

    因此,这个故事的寓意是:检查您的清理功能,看看是否有任何崩溃/损坏。清理期间的失败不会显示在测试报告中,因为通过/失败断言已经完成。但是它引起的问题可能会以其他方式出现。

    在我的例子中,是QTAgent32.exe进程的错误行为导致[AssemblyInitialize]被执行两次。重新启动生成并执行代码的主机为我解决了这个问题。

    我在文档中看到了这一点,但不知道这是否确实是原因。我在MSDN的Pex&Moles论坛上有一篇关于HostType属性的单独帖子:。我不相信这是个问题,因为那篇文章是关于ASP.NET和IIS的。另外,据我所知,Moles女士不允许您将HostType属性添加到AssemblyInitialize/Cleanup方法中。但是其他的呢?这就是我要问的。