65.9K
CodeProject 正在变化。 阅读更多。
Home

测试驱动开发 - 自动化 COM+ 管理任务

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (7投票s)

2006年3月16日

CPOL

6分钟阅读

viewsIcon

33704

downloadIcon

261

一种用于自动化 COM+ 管理任务的测试驱动开发方法。

引言

测试驱动开发(TDD)是 XP 的核心编程实践之一。TDD 完全颠覆了传统的开发方式。不是先编写功能代码,然后事后编写测试代码,而是先编写测试代码,再编写功能代码。TDD 围绕三个基本活动展开:编写测试、编写通过测试的代码、重构代码使其更灵活、更易于理解。TDD 采用一种不同的、极端的方法来确保我们始终对所有代码进行测试。

本文介绍了一种用于库项目的测试驱动开发方法,该方法可以自动化 COM+ 管理任务。

COM+ 管理任务库提供了以下功能

  • 添加 COM+ 应用程序
  • 删除现有 COM+ 应用程序
  • 启动现有 COM+ 应用程序
  • 关闭现有 COM+ 应用程序

本文涵盖了 NUnit 客户端应用程序开发(测试代码)以及重构库代码以通过 NUnit 测试。本文不涵盖库的用户界面。

COM+ 管理库的测试驱动开发

以下是 COM+ 管理任务的测试驱动开发步骤

步骤 1

创建客户端应用程序并提供一个测试方法来测试上述库功能之一。从测试“添加 COM+ 应用程序”功能开始。

构建应用程序。我们将收到构建错误,因为没有对库应用程序的引用(事实上,库应用程序尚未开发)。

第二步

创建 COMPlusAdministration 库应用程序,并为“添加 COM+ 应用程序”功能提供骨架代码。

步骤 3

在提供对库应用程序的引用后,再次构建客户端。

步骤 4

运行 NUnit 来测试客户端应用程序中的 Test 方法。这将失败,因为库中没有“添加 COM+ 应用程序”功能的完整实现。

步骤 5

在 COMPlusAdministration 库应用程序中实现“添加 COM+ 应用程序”功能的完整代码。

步骤 6

再次运行 NUnit 测试,以确保“添加 COM+ 应用程序”功能的测试通过。

步骤 7

在添加新的测试方法(在客户端应用程序中)以测试其他库功能(如启动应用程序、删除应用程序和关闭应用程序)后,重复上述步骤。

让我们详细看看上述步骤。

客户端应用程序(步骤 1)

对于此测试驱动开发,我们的客户端应用程序是一个基于 Windows 的应用程序。

首先创建一个新的 Windows 应用程序项目,并将其命名为 NUnitClient。

Sample screenshot

当 NUnit 打开客户端应用程序时,它会查找带有 TestFixture 属性的类。TestFixture 属性指示 NUnit 查找带有 Test 属性的方法并运行这些方法。(有关 TestFixtureTest 属性的更多详细信息,请参阅 NUnit 文档。

为了运行 NUnit,我们必须在客户端应用程序中添加一个带有 TestFixture 属性的类。使用“项目”->“添加新项”向项目中添加 NUnitClient.cs 文件。打开 NUnitClient.cs 文件,并为 NUnitClient 类添加 [TestFixture] 属性。

[TestFixture]
public class NUintClient
{
   public NUintClient()
   {
   }
}

NUnitClient 类添加一个带有 [Test] 属性的 CreateApplication 方法。我们使用此方法来测试 COMPlusAdministration 库应用程序的创建 COM+ 应用程序功能。

[TestFixture]
public class NUintClient
{
    public NUintClient()
   {
   }
   
   [Test]
   public void CreateApplication()
   {
       COMPlusAdmin objCOMPlusAdmin = new COMPlusAdmin();
      
       string strReturn = objCOMPlusAdmin.CreateApplication("EventOverlay", 
                          "EventOverlay  Application");
     
      Assert.AreEqual("CreateApplication Success",strReturn);
   }
}

由于 TestFixtureTest 属性是 NUnit 的一部分,我们需要添加对 NUnit Components 的引用以避免构建错误。

使用“项目”->“添加引用”添加对 NUnit 组件的引用。另外,将这些命名空间添加到 NUnitClient.cs

Sample screenshot

using NUnit.Tests.Assertions;
using NUnit.Framework;
using NUnit.Core;
using NUnit.Extensions;

现在,尝试构建客户端应用程序。构建将失败,因为此应用程序中没有对 COMPlusAdmin 类的引用。

Sample screenshot

要解决我们客户端应用程序中的这些构建错误,我们需要引用一个包含 COMPlusAdmin 类的组件。

让我们创建一个 COMPlusAdministration 组件,其中包含 COMPlusAdmin 类和 CreateApplication 方法。

COMPlusAdministration 应用程序(步骤 2)

首先创建一个库项目,并将其命名为 COMPlusAdministration。

Sample screenshot

Class1.cs 重命名为 COMPlusAdmin.cs,并向其中添加一个带有最少代码的 CreateApplication 方法。

////////////////////////////////////////////////////////////////////
//Function Name: CreateApplication
// Description : This method will create new COM+Application
////////////////////////////////////////////////////////////////////
public string CreateApplication(string strAppName, 
              string strAppDescription)
{
     string strMessage="";
     return strMessage;
}

构建库应用程序。

构建客户端应用程序(步骤 3)

将库引用添加到客户端应用程序。还将 COMPlusAdministration 命名空间添加到 NUintClient.cs

using COMPlusAdministration;

现在,构建客户端应用程序。这次,它将成功构建,因为我们将 COMPlusAdministration 库引用添加到了应用程序中。现在,我们准备使用 NUnit 运行客户端应用程序。

运行 NUnit(步骤 4)

使用 NUnit2.0 运行此应用程序。NUnit 将对“CreateApplication”方法抛出错误消息,称

expected : < “CreateApplicaiton Success” >
but was : < “ ” >

Sample screenshot

COMPlusAdministration 库中的 CreateApplication 方法返回空字符串,因为此方法没有实现。但是,在客户端应用程序中,我们期望此方法返回“CreateApplication Success”。

Assert.AreEqual("CreateApplication Success", strReturn);

现在,我们的目标是让客户端的 CreateApplication 方法通过。只有当 COMPlusAdministration 库的 CreateApplication 方法返回“CreateApplication Success”时,NUnit 才会通过此方法。

在 COMPlusAdministration 中提供功能(步骤 5)

现在是时候实现 CreateApplication 方法的完整功能了。

CreateApplication 方法将返回“CreateApplication Success”或“CreateApplication Failure”,具体取决于 CreateApplication 方法的成功或失败。请查看下面提到的 CreateApplication 方法的代码。

/////////////////////////////////////////////////////////////
// Function Name: OpenCatalog
// Description : This method will open the COM+ Catalog
//               and Get the "Applications" Collection
/////////////////////////////////////////////////////////////
public void OpenCatalog()
{
      //Open the COM+ Catalog
      objCatalog = new COMAdminCatalog(); 
       //Get the "Application" Collection
   objCatalogColl = (COMAdmin.COMAdminCatalogCollection) 
                     objCatalog.GetCollection("Applications");
}

/////////////////////////////////////////////////////////////
// Function Name: CreateApplication
// Description : This method will create new COM+ Application
/////////////////////////////////////////////////////////////
public string CreateApplication(string strAppName, string strAppDescription)
{
      string strMessage="";
     try
     {
        //Open the COM+ Catalog and get the "Application" Collection
        OpenCatalog();
        //Add new COM+ Application
        COMAdmin.COMAdminCatalogObject obj=(COMAdmin.COMAdminCatalogObject) 
                                            objCatalogColl.Add();
        //Set the new Application Name
        obj.set_Value("Name",strAppName);
        //Set the Description for Application
        obj.set_Value("Description",strAppDescription);
        //Save the changes
        objCatalogColl.SaveChanges();
        strMessage= "CreateApplication Success";
    }
     catch(Exception ex)
     {
       strMessage= "CreateApplication Failure";
     }

     return strMessage;
}

在构建 COMPlusAdministration 库之前,添加对 COM +1.0 Admin Type Library 的引用。

Sample screenshot

我们已经实现了“CreateApplication”方法;现在,是时候检查该方法是否正常工作了。

运行 NUnit(步骤 6)

再次使用 NUnit 运行客户端应用程序,并检查任何错误。这次,如果 CreateApplication 方法成功创建了 COM+ 应用程序,NUnit 应该不会显示任何错误。

如果 CreateApplication 方法未能创建 COM+ 应用程序,它将返回“CreateApplication Failure”消息。在这种情况下,NUnit 将不会通过 CreateApplication 方法,并会显示一个错误,称

expected : < “CreateApplicaiton Success” >
but was : < “"CreateApplication Failure" ” >

尝试修改 CreateApplicaiton 方法代码,直到 NUnit 通过该方法。

如果 CreateApplicaiton 方法成功创建了 COM+ 应用程序,您将在组件服务COM+ 应用程序根目录下列出新创建的 COM+ 应用程序。在这种情况下,它是 EventOverlay

Sample screenshot

测试其他功能(步骤 7)

通过在客户端应用程序中创建测试方法来测试其他 COM+ 管理任务(删除应用程序、启动应用程序、关闭应用程序)。

以下是客户端应用程序中 DeleteApplicationStartApplicaitonShutDownApplication 测试方法的代码。

[Test]
public void DeleteApplication()
{
       COMPlusAdmin objCOMPlusAdmin = new COMPlusAdmin();
       string strReturn = objCOMPlusAdmin.DeleteApplication("EventOverlay");
       Assert.AreEqual("DeleteApplication Success",strReturn);
}
[Test]
public void StartApplication()
{
       COMPlusAdmin objCOMPlusAdmin = new COMPlusAdmin();
       string strReturn = objCOMPlusAdmin.StartApplication("EventOverlay");
       Assert.AreEqual("StartApplication Success",strReturn);
}
[Test]
public void ShutDownApplication()
{
       COMPlusAdmin objCOMPlusAdmin = new COMPlusAdmin();
        string strReturn = objCOMPlusAdmin.ShutDownApplication("EventOverlay");
        Assert.AreEqual("ShutDownApplication Success",strReturn);
}

以下是 COMPlusAdministration 库项目中 DeleteApplicationStartApplicationShutDownApplication 的功能。

///////////////////////////////////////////////////////////////////////
// Function Name: DeleteApplication
// Description : This method will delete the existing COM+ Application
///////////////////////////////////////////////////////////////////////
public string DeleteApplication(string strAppName)
{
    string strMessage="";
    try
    {
        //Open the COM+ Catalog and get the "Application" Collection
        OpenCatalog();
        objCatalogColl.Populate();
        //Get the COM+ Application Count 
        int nCount = objCatalogColl.Count;
        for(int i=0; i < nCount ; i++)
        {
            //Get the COM+ Application
            COMAdmin.COMAdminCatalogObject obj = 
                (COMAdmin.COMAdminCatalogObject) objCatalogColl.get_Item(i);
            //Check whether the application to be deleted 
            //is exist in the Application Collection
            if(strAppName == (string)obj.get_Value("Name"))
            {
                //We found the desired application , delete it
                objCatalogColl.Remove(i);
                //Save the changes
                objCatalogColl.SaveChanges(); 
                break;
            }
        }
        strMessage = "DeleteApplication Success";
    }
    catch(Exception ex)
    {
        strMessage= "DeleteApplication Failure";
    } 
    return strMessage;
}
///////////////////////////////////////////////////////////////////////
// Function Name: StartApplication
// Description : This method will start 
//               the the existing COM+ Application
///////////////////////////////////////////////////////////////////////
public string StartApplication(string strAppName)
{
    string strMessage="";
    try
    {
        bool bApplicationFound = false;
        //Open the COM+ Catalog and get the "Application" Collection
        OpenCatalog();
        objCatalogColl.Populate();
        //Get the COM+ Application Count 
        int nCount = objCatalogColl.Count;
        for(int i=0; i < nCount ; i++)
        {
            //Get the COM+ Application
            COMAdmin.COMAdminCatalogObject obj = 
                (COMAdmin.COMAdminCatalogObject) objCatalogColl.get_Item(i);
            //Check whether the application 
            //is exist in the Application Collection
            if(strAppName == (string)obj.get_Value("Name"))
            {
                bApplicationFound = true;
            }
       }
       //Application found in the Collection
       if(true == bApplicationFound )
       {
           objCatalog.StartApplication(strAppName);
       } 
       strMessage= "StartApplication Success";
   }
   catch(Exception ex)
   {
       strMessage = "StartApplication Failure";
   }
   return strMessage;
}
///////////////////////////////////////////////////////////////////////
// Function Name: ShutDownApplication
// Description : This method will shutdown 
//               the existing COM+ Application
///////////////////////////////////////////////////////////////////////
public string ShutDownApplication(string strAppName)
{
       string strMessage="";
        try
       {
            bool bApplicationFound = false;
            //Open the COM+ Catalog and get the "Application" Collection
            OpenCatalog();
            objCatalogColl.Populate();
            //Get the COM+ Application Count 
            int nCount = objCatalogColl.Count;
            for(int i=0; i < nCount ; i++)
           {
               //Get the COM+ Application
               COMAdmin.COMAdminCatalogObject obj = 
                  (COMAdmin.COMAdminCatalogObject) objCatalogColl.get_Item(i);
               //Check whether the application is exist 
               //in the Application Collection
               if(strAppName == (string)obj.get_Value("Name"))
               {
                  bApplicationFound = true;
               }
          }
          //Application found in the Collection
           if(true == bApplicationFound )
          {
                objCatalog.ShutdownApplication(strAppName);
           }
          strMessage= "ShutDownApplication Success";
   }
   catch(Exception ex)
   {
        strMessage= "ShutDownApplication Failure";
   }
     return strMessage;
}

如果客户端应用程序中的所有测试方法都通过,那么该库就已经进行了单元测试,可以使用了。如前所述,本文不涵盖库的用户界面。

结论

测试驱动开发是一种强大的技术,可确保所有代码都经过测试。另一个优点是,正确使用测试驱动开发可以确保所有编写的代码都由测试覆盖。这可以使程序员对代码有更高的信任度。

© . All rights reserved.