首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

8.4  使用TCP测试Web方法

问题

如何使用TCP通过调用Web service中的某个Web方法对其进行测试。

设计

第一步,实例化一个TcpClient对象并连接到Web service所在的远程服务器。第二步,构造一个用于发送给Web方法的SOAP消息。第三步,构造一个包含HTTP信息的报头。第四步,实例化一个与TcpClient对象相关联的NetworkStream对象,并通过NetworkStream.Write()方法发送报头和SOAP消息。第五步,通过在while循环里使用NetworkStream.Read()方法接收SOAP响应。第六步,根据期望值对SOAP响应进行分析。

方案

这个例子通过TCP把字符串“testing”发送给Web方法GetTitles()。

Console.WriteLine("Calling Web Method GetTitles() using TCP");

string input = "testing";

//TcpClient client = new TcpClient("127.0.0.1", 80);

TcpClient client = new TcpClient(AddressFamily.InterNetwork);

client.Connect("127.0.0.1", 80);

string soapMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";

soapMessage += "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-

instance\"";

soapMessage += " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"";

soapMessage += " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">";

soapMessage += "<soap:Body>";

soapMessage += "<GetTitles xmlns=\"http://tempuri.org/\">";

soapMessage += "<filter>" + input + "</filter>";

soapMessage += "</GetTitles>";

soapMessage += "</soap:Body>";

soapMessage += "</soap:Envelope>";

string webService = "/TestAuto/Ch8/TheWebService/BookSearch.asmx";

string host = "localhost";

string webMethod = "GetTitles";

string header = "POST " + webService + " HTTP/1.1\r\n";

header += "Host: " + host + "\r\n";

header += "Content-Type: text/xml; charset=utf-8\r\n";

header += "Content-Length: " + soapMessage.Length.ToString() + "\r\n";

header += "Connection: close\r\n";

header += "SOAPAction: \"http://tempuri.org/" + webMethod + "\"\r\n\r\n";

Console.Write("Header is: \n" + header);

string requestAsString = header + soapMessage;

byte[] requestAsBytes = Encoding.ASCII.GetBytes(requestAsString);

NetworkStream stream = client.GetStream();

stream.Write(requestAsBytes, 0, requestAsBytes.Length);

byte[] responseBufferAsBytes = new byte[512];

string responseAsString = "";

string entireResponse = "";

int numBytesReceived = 0;

while ((numBytesReceived = stream.Read(responseBufferAsBytes, 0, 512)) > 0)

{

  responseAsString = Encoding.ASCII.GetString(responseBufferAsBytes, 0,

                                                       numBytesReceived);

  entireResponse += responseAsString;

}

Console.WriteLine(entireResponse);

if ( entireResponse.IndexOf("002") >= 0 &&

      entireResponse.IndexOf("004") >= 0 &&

      entireResponse.IndexOf("005") >= 0 )

  Console.WriteLine("\nPass");

else

  Console.WriteLine("\nFail");

通过TCP调用Web方法与通过套接字调用Web方法非常类似。这并不是一种巧合,因为TcpClient原本就是被设计用来作为Socket类的一个更为友好的外覆类(wrapper)。这两种技术非常相似,以至于很难选择该用哪一个。有两种方法可以帮助我们判断应该使用哪一种技术。一方面,因为TcpClient相比于Socket类较为简洁,所以当通过TCP调用Web service的时候,应该使用TcpClient,而当调用那些由非TCP协议实现的Web service时,应该使用Socket。从实践上来看,因为ASP.NET Web service使用HTTP协议,而HTTP协议又使用TCP协议,所以我们可以简单地说:“当对Web方法进行底层调用的时候,总是使用TcpClient类”。另一方面,因为使用TcpClient与使用Socket非常相似,而且Socket更为灵活,因此你可能也要用到Socket类。从而这一条也可以简化成“当对Web方法进行底层调用的时候,总是使用Socket类”。最终的结论是:用两种方法进行测试比只选用其中一种要好。但是,因为使用TcpClient与使用Socket类非常相似,所以当我们试图通过两种方式调用Web方法来对其进行测试,从而验证自动化测试程序时,应该只使用TcpClient类或Socket类中的一种,而不是两种都用上。

注解

用于测试ASP.NET Web service的4种主要方法中,使用TCP这种方式,其操作所在的抽象层次仅比使用套接字稍高。通过TcpClient类对Web方法进行测试的时候,有6个分开的步骤。这6个步骤都可以单独地看作是“问题及其解决方案”,但是因为这些步骤之间的相互依赖性很强,因此放在一起讲述更容易理解。第一步是实例化一个TcpClient对象并连接到待测Web service所在的服务器:

TcpClient client = new TcpClient(AddressFamily.InterNetwork);

client.Connect("127.0.0.1", 80);

关于AddressFamily枚举值的讨论请参见8.2节。创建好TcpClient对象之后,就可以通过指定IP地址和端口号连接到服务器。也可以直接把服务器IP地址和端口号传给TcpClient重载过的一个构造函数,从而省去指定AddressFamily,因为InterNetwork是Connect()方法的默认值。

TcpClient client = new TcpClient("127.0.0.1", 80);

通过TCP调用Web方法,第二步是构造一个用于发送给Web方法的SOAP消息:

string soapMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";

soapMessage += "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-

instance\"";

soapMessage += " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"";

soapMessage += " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">";

soapMessage += "<soap:Body>";

soapMessage += "<GetTitles xmlns=\"http://tempuri.org/\">";

soapMessage += "<filter>" + input + "</filter>";

soapMessage += "</GetTitles>";

soapMessage += "</soap:Body>";

soapMessage += "</soap:Envelope>";

如8.2节所述,我们可以从Visual Studio中得到一个SOAP消息模板。第三步是构造一个包含HTTP信息的报头:

string webService = "/TestAuto/Ch8/TheWebService/BookSearch.asmx";

string host = "localhost";

string webMethod = "GetTitles";

string header = "POST " + webService + " HTTP/1.1\r\n";

header += "Host: " + host + "\r\n";

header += "Content-Type: text/xml; charset=utf-8\r\n";

header += "Content-Length: " + soapMessage.Length.ToString() + "\r\n";

header += "Connection: close\r\n";

header += "SOAPAction: \"http://tempuri.org/" + webMethod + "\"\r\n\r\n";

Console.Write("Header is: \n" + header);

这些信息,仍然可以从Visual Studio中得到。第四步是实例化一个与TcpClient对象相关联的NetworkStream对象,并通过NetworkStream.Write()方法发送报头和SOAP消息:

string requestAsString = header + soapMessage;

byte[] requestAsBytes = Encoding.ASCII.GetBytes(requestAsString);

NetworkStream stream = client.GetStream();

stream.Write(requestAsBytes, 0, requestAsBytes.Length);

与使用Socket类相比,第四步的差别是最大的。通过GetBytes()方法把HTTP报头和SOAP消息转换成字节数组之后,我们通过TcpClient.GetStream()方法创建一个NetworkStream对象,然后使用NetworkStream.Write()把数据通过网络发送出去——这个过程非常简单明了。通过TCP调用Web方法,第五步是在while循环里使用NetworkStream.Read()方法接收SOAP响应:

byte[] responseBufferAsBytes = new byte[512];

string responseAsString = "";

string entireResponse = "";

int numBytesReceived = 0;

while ((numBytesReceived = stream.Read(responseBufferAsBytes, 0, 512)) > 0)

{

  responseAsString = Encoding.ASCII.GetString(responseBufferAsBytes, 0,

                                                       numBytesReceived);

  entireResponse += responseAsString;

}

这一步遵循与8.2节所描述的几乎一样的读取模式。把两段代码对照阅读可能更容易理解。一旦理解了这种通用模式,你会发现无论是在自动化测试还是程序开发中,它都被广泛使用。第六步,也就是最后一步,是根据给定的期望值检查SOAP响应:

Console.WriteLine(entireResponse);

if ( entireResponse.IndexOf("002") >= 0 &&

      entireResponse.IndexOf("004") >= 0 &&

      entireResponse.IndexOf("005") >= 0 )

  Console.WriteLine("\nPass");

else

    Console.WriteLine("\nFail");

正如8.2节和8.3节所讨论的那样,当测试结果的返回值比较复杂的时候(比如这里),要判断测试结果通过与否并不是很容易。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论