xmlunit
在你开始前
关于本系列
Web服务越来越成为业务应用程序中的关键组件,并且随着诸如面向服务的体系结构(SOA)之类的范例的出现,对Web服务的关注也在不断增长。 在这些面向服务和关键服务的应用程序中,Web服务测试具有同等重要的意义。 快速创建和部署复杂的Web服务给质量检查团队带来了挑战。 自动化的Web服务测试可以帮助团队有效地管理工作。
Web服务测试通常包括以下任务:
- 生成Web服务的客户端或框架代码。
- 定义测试输入。
- 使用客户端代码或框架代码调用Web服务。
- 验证实际响应与预期响应相似。
在这些活动中,客户端或框架代码的生成以及响应验证的工作量最大。
有多种工具可用于根据其WSDL文件为Web服务生成客户端代码或框架代码。 但是,生成的代码可能是专有的,并且每次WSDL更改时都可能需要重新生成。 解决此问题的方法是消除客户端代码或框架代码的生成,并直接通过通用HTTP客户端调用Web服务。 在本系列的后面部分,您将看到Apache Commons HttpClient(以下称为HttpClient)API提供的一个这样的工具箱。
同样,根据响应内容的复杂性,响应验证通常涉及某种手动干预。 如果响应包含简单元素,则验证可能很简单,因为它要求您仅检查简单元素中的值。 对于包含复杂元素和大量此类复杂元素的响应,手动验证可能需要更多的精力。
本系列向您介绍一种使用一系列技术(例如JUnit,HttpClient和Apache XMLUnit(以下称为XMLUnit))自动测试典型Web服务的技术。 在IBM Rational Software Architect提供的开发平台上演示了该技术。
关于本教程
在本系列的第二篇教程中,您将创建一个简单的Web服务,使用HttpClient调用Web服务,并使用XMLUnit比较预期的响应和实际的响应-所有这些都在IBM Rational Software Architect开发平台上进行。
先决条件
要继续学习本教程,您应该对Web服务及其在Java中的开发有基本的了解,并且对单元测试工具(例如JUnit)有所了解。
系统要求
您需要以下软件才能完成本教程:
- Microsoft®Windows®98、2000或2003操作系统
- IBM Rational Software Architect V6或更高版本 (此链接将您带到试用版下载)
- Apache JUnit 3.8.1
- Apache Commons HttpClient 3.0.1 (下载二进制存档以找到commons-httpclient-3.0.1.jar)
- Apache Commons Codec 1.3 (下载二进制归档文件以找到commons-codec-1.3.jar)
- Apache XMLUnit 1.0 (下载二进制归档文件以找到xmlunit1.0.jar)
定义输入和输出
在本系列的第1部分中,您创建了一个示例Web服务,该服务返回了用户列表。 现在,您将指定对Web服务的请求和预期响应。
请求
通常,对Web服务的请求为SOAP格式。 例如,对于示例Web服务,请求将类似于清单1。
在清单1中,在Web服务上调用了getUsers()
方法。 方法上方的文本构成SOAP头。 您可能还希望在请求中附加自定义标头。
清单1.对Web服务的请求
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:q0="http://sample.ws.ibm.com"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<q0:getUsers/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
现在,将此请求保存在XML文件中,例如C:\ wssample \ request.xml。
预期回应
样本Web服务的预期响应是清单2中的用户列表。
清单2.用户列表
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:q0="http://sample.ws.ibm.com"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<getUsersReturn>
<User>
<name>John</name>
<address>
<street>Park Street</street>
<city>Washington</city>
<zip>012345</zip>
</address>
</User>
<User>
<name>Mohan</name>
<address>
<street>Avenue Street</street>
<city>Bangalore</city>
<zip>456789</zip>
</address>
</User>
<User>
<name>Mansoor</name>
<address>
<street>Martin Street</street>
<city>Bangalore</city>
<zip>135791</zip>
</address>
</User>
</getUsersReturn>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
在清单2中, getUsersReturn
是响应的根元素。 它忽略SOAP标头。 将此预期响应保存在XML文件中,例如C:\ wssample \ expected_response.xml。
编写Web服务的调用客户端
现在,您已经定义了Web服务的输入和输出测试数据并将其存储在磁盘中。 接下来,您将编写客户端代码以使用HttpClient API调用Web服务:
- 打开Rational Software Architect,然后单击菜单>窗口>打开透视图> Java 。
- 转到File> New> Project ...> Java Project ,如图1所示。
图1.新项目
- 如图2所示,输入一个项目名称,例如
SampleTestProject
,然后单击Next 。图2.创建一个Java项目
- 在“ Java设置”页面中,单击SampleTestProject ,然后单击“ 添加文件夹”按钮。
- 输入
src
作为源文件夹名称,然后单击OK ,如图3所示。图3. Java Settings页面
- 向导询问
Do you want to remove the project as source folder and update build output folder to 'SampleTestProject/bin'?
(请参见图4)。 选择是 。图4.新的源文件夹
- 点击完成 。 项目视图应如图5所示。
图5. Java项目的视图
- 现在,在src文件夹中创建一个包,例如com.ibm.ws.sample.test。 该软件包将包含您的测试代码。
- 右键单击SampleTestProject并选择New> Folder ,在SampleTestProject下创建一个名为lib的文件夹 。
- 将.jar文件commons-codec-1.3.jar , commons-logging.jar和commons-httpclient-3.0.1.jar添加到lib文件夹中。
- 通过右键单击项目并选择Properties,将.jar文件添加到项目构建路径。
- 在左窗格中选择Java Build Path ,然后在右边选择Libraries选项卡,如图6所示。
图6. SampleTestProject的属性
- 单击添加JAR ...按钮。 然后在lib文件夹中选择.jar文件,然后单击OK ,如图7所示。
图7. JAR选择
- 在“属性”页面中单击“ 确定 ”。
- 现在,在com.ibm.ws.sample.test包中创建一个名为SampleHttpClient.java的Java类,如清单3所示。
清单3.创建一个Java类
package com.ibm.ws.sample.test; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.RequestEntity; import org.apache.commons.httpclient.methods.StringRequestEntity; public class SampleHttpClient { public static String invokeWebService(String webServiceURL, String requestXMLPath) throws FileNotFoundException, Exception { PostMethod post = null; HttpClient client = new HttpClient(); try { // Read the SOAP request from the file StringBuffer requestFileContents = new StringBuffer(); BufferedReader bufferedReader = new BufferedReader (new FileReader(requestXMLPath)); String line = null; while((line = bufferedReader.readLine()) != null) { requestFileContents.append(line); } post = new PostMethod(webServiceURL); post.setRequestHeader("Accept","application/soap+xml,application/ dime,multipart/related,text/*"); post.setRequestHeader("SOAPAction", ""); // Request content will be retrieved directly from the input stream RequestEntity entity = new StringRequestEntity(requestFileContents .toString(), "text/xml", "utf-8"); post.setRequestEntity(entity); // Returns a number indicating the status of response int result = client.executeMethod(post); String response = post.getResponseBodyAsString(); return response; } finally { // Release current connection to the connection pool once you are done post.releaseConnection(); } } }
- 保存并生成项目。
从JUnit测试调用Web服务
在上一节中,您创建了一个简单的HttpClient,它将使用给定的请求调用Web服务。 在本部分中,您将创建一个使用此客户端的JUnit测试。
- 右键单击包com.ibm.ws.sample.test ,然后通过选择New> Other ...> Java> JUnit> JUnit Test Case添加一个新的JUnit测试,例如SampleTest。
- 创建清单4所示的测试方法。
- 保存并生成项目。
- 右键单击SampleTest.java ,然后以JUnit身份运行。 您将看到Web服务的响应打印到控制台。
清单4.测试方法
package com.ibm.ws.sample.test;
import java.io.FileNotFoundException;
import junit.framework.TestCase;
public class SampleTest extends TestCase
{
public void test() throws FileNotFoundException, Exception
{
// Web service URL
final String wsURL = "http://localhost:9080/SampleProject/services/Users";
// Request XML path
final String requestXMLPath = "C:/wssample/request.xml";
// Invoke the Web service
String webServiceResponse = SampleHttpClient.invokeWebService(wsURL,requestXMLPath);
System.out.println("Response: " + webServiceResponse);
}
}
使用XMLUnit验证测试
在上一节中,您创建了一个JUnit测试来调用Web服务并获取响应。 现在,您将修改JUnit测试,以将来自Web服务的实际响应存储到文件中,然后使用XMLUnit API将其与预期响应进行比较。
- 将xmlunit1.0.jar添加到项目构建路径。
- 通过将蓝色代码添加到清单5中所示的代码中,来修改JUnit测试方法。
清单5.比较响应
package com.ibm.ws.sample.test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; import junit.framework.TestCase; import org.custommonkey.xmlunit.Diff; import org.custommonkey.xmlunit.XMLAssert; import org.custommonkey.xmlunit.XMLUnit; public class SampleTest extends TestCase { public void test() throws FileNotFoundException, Exception { // Web service URL final String wsURL = "http://localhost:9080/ SampleProject/services/Users"; // Request XML path final String requestXMLPath = "C:/wssample/request.xml"; // Expected response path final String expectedXMLPath = "C:/wssample/expected_response.xml"; // Actual response path final String actualXMLPath = "C:/wssample/actual_response.xml"; // Encoding final String encoding = "UTF-8"; // Invoke the web service String webServiceResponse = SampleHttpClient.invokeWebService (wsURL,requestXMLPath); // Store the response in the disk File responseFile = new File(actualXMLPath); responseFile.createNewFile(); OutputStreamWriter oSW = new OutputStreamWriter (new FileOutputStream(responseFile),encoding); oSW.write(webServiceResponse); oSW.flush(); oSW.close(); // Compare the responses Reader expectedXMLReader = new InputStreamReader (new FileInputStream(expectedXMLPath), encoding); Reader actualXMLReader = new InputStreamReader (new FileInputStream(actualXMLPath), encoding); // Ignore the white space while comparing XMLUnit.setIgnoreWhitespace(true); // Diff object, which contains the differences, if any Diff xmlDiff = new Diff(expectedXMLReader, actualXMLReader); // "false" ignores the order of the users in the XMLs XMLAssert.assertXMLEqual(xmlDiff,false); } }
- 保存并生成项目。
- 右键单击SampleTest.java ,然后以JUnit身份运行。
- JUnit控制台显示为绿色,表明测试已通过,如图8所示。
图8. JUnit控制台
- 现在,更改预期响应中的用户顺序,然后重新运行测试。 在C:\ wssample \ expected_response.xml中打开期望的响应XML。
- 更改用户顺序,如清单6所示。
清单6.新的用户订单
<?xml version="1.0" encoding="UTF-8" ?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://sample.ws.ibm.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Body> <getUsersReturn> <User> <name>Mohan</name> <address> <street>Avenue Street</street> <city>Bangalore</city> <zip>456789</zip> </address> </User> <User> <name>Mansoor</name> <address> <street>Martin Street</street> <city>Bangalore</city> <zip>135791</zip> </address> </User> <User> <name>John</name> <address> <street>Park Street</street> <city>Washington</city> <zip>012345</zip> </address> </User> </getUsersReturn> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
- 保存文件,然后重新运行测试。 它应该再次通过。
结论
在本教程中,您学习了一种使用HttpClient和XMLUnit API自动测试Web服务输出的技术。 具体来说,您学习了如何:
- 创建一个简单的Web服务。
- 使用HttpClient调用Web服务。
- 使用XMLUnit比较预期响应和实际响应。
翻译自: https://www.ibm.com/developerworks/webservices/tutorials/ws-soa-autotest2/ws-soa-autotest2.html
xmlunit