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





3.00/5 (7投票s)
一种用于自动化 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。
当 NUnit 打开客户端应用程序时,它会查找带有 TestFixture
属性的类。TestFixture
属性指示 NUnit 查找带有 Test
属性的方法并运行这些方法。(有关 TestFixture
和 Test
属性的更多详细信息,请参阅 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);
}
}
由于 TestFixture
和 Test
属性是 NUnit 的一部分,我们需要添加对 NUnit Components 的引用以避免构建错误。
使用“项目”->“添加引用”添加对 NUnit 组件的引用。另外,将这些命名空间添加到 NUnitClient.cs。
using NUnit.Tests.Assertions;
using NUnit.Framework;
using NUnit.Core;
using NUnit.Extensions;
现在,尝试构建客户端应用程序。构建将失败,因为此应用程序中没有对 COMPlusAdmin
类的引用。
要解决我们客户端应用程序中的这些构建错误,我们需要引用一个包含 COMPlusAdmin
类的组件。
让我们创建一个 COMPlusAdministration
组件,其中包含 COMPlusAdmin
类和 CreateApplication
方法。
COMPlusAdministration 应用程序(步骤 2)
首先创建一个库项目,并将其命名为 COMPlusAdministration。
将 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 : < “ ” >
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 的引用。
我们已经实现了“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。
测试其他功能(步骤 7)
通过在客户端应用程序中创建测试方法来测试其他 COM+ 管理任务(删除应用程序、启动应用程序、关闭应用程序)。
以下是客户端应用程序中 DeleteApplication
、StartApplicaiton
和 ShutDownApplication
测试方法的代码。
[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 库项目中 DeleteApplication
、StartApplication
和 ShutDownApplication
的功能。
///////////////////////////////////////////////////////////////////////
// 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;
}
如果客户端应用程序中的所有测试方法都通过,那么该库就已经进行了单元测试,可以使用了。如前所述,本文不涵盖库的用户界面。
结论
测试驱动开发是一种强大的技术,可确保所有代码都经过测试。另一个优点是,正确使用测试驱动开发可以确保所有编写的代码都由测试覆盖。这可以使程序员对代码有更高的信任度。