本部分将告诉你如何使用TDD生成与开发一个测试优先的简单RESTful Web服务。SoapUI的主要学习是如何测试一个由WADL定义的简单RESTful Web服务,该WADL产生JSON响应。在这里也能学到使用Apache CXF开发一个基础的JAX-RS web服务技巧。
3.1 准备阶段
该例子服务是第一章中提到的SOAPinvoice服务的REST版本,该服务通过WADL定义,定义的内容如下:
u WADL:invoice_v1.wadl
u Service endpoint:http://localhost:9000/invoiceservice/v1
u Resource:GET /invoice/{id}
u Produces: application/json
Apache CXF被用于生成、构建、运行Stubweb服务。对于Eclipse用户,可以设置Apache CXF作为一个运行库,设置位置是在:Project----Add Library-------CXF Runtime,以java应用程序运行服务类。
3.2 操作步骤
首先,使用服务的WADL创建一个REST项目,添加一个带有断言的TestStep用来检测响应的invoice的值是否与预期的结果一致。这时,使用Apache CXF生成一个空的可运行的REST web服务,然后添加一个简单的实现通过测试。执行步骤如下:
1. 使用invoice_v1.wadl创建一个SoapUI项目。进入“文件目录|新建REST项目|导入WADL”,找到文件“invoice_v1.wadl”,然后点击确认按钮。在新生成的项目下带有一个简单请求,该请求的invoice源带一个id参数:
2. 创建一个简单的测试集、测试用例、带有断言的TestStep操作,目的是为了指定期望成功返回invoice源的请求。使用“Generate TestSuite”操作:
点击OK,弹出如下弹窗,点击“确定”:
点开生成的测试集,截图如下:
3. 给TestStep添加一些断言。例如我们期望Invocie文档的json文档格式如下样式:
{"Invoice": {
"id": 12345,
"companyName": "Test Company",
"amount": 100
}}
4. 如果是使用SoapUI Pro,可以使用3个JsonPath匹配断言:
Name: IdShouldBe12345 JsonPath: $.Invoice.id expectedValue: 12345 Name: AmountShouldBe100 JsonPath: $.Invoice.amount Expected Value: 100 Name: CompanyNameShouldBeTestCompany JsonPath: $.Invoice.companyName Expected Value: Test Company |
5. 如果是开源的SoapUI,可以使用3个contains断言:
Name: ShouldContainText12345 Contains Content: 12345 Name: ShouldContainTextTestCompany Contains Content: Test Company Name: ShouldContainText100 Contains Content: 100 |
6. 在SoapUI的两个版本都可以检查HTTP的状态是否为200,通过添加一个有效的HTTP Status Codes断言:
Name: ShouldReturnHTTPStatus200 HTTP Status Code = 200 |
7. 现在测试已经准备好,需要生成一个可操作服务。可以使用Apache CXF的wadljava脚本使用WADL生成一个空的可执行的Java服务。不幸的是,在SoapUI 5.0版本,WADL2Java功能已经使用传统的wadl2java写。这个版本的wadl2java只能使用WADL生成客户端代码,而不能生成我们需要的服务端代码。
8. 当然,直接使用Apache CXF生成web服务代码不是SoapUI的一部分。我提供这些完整步骤以防万一他们对你有用。如果你想跳过这个步骤,在<chapter 1 samples>/rest/invoicev1_gen下有生成的代码。否则,通过运行wadl2java生成web服务代码,例如:
MacOSX/Linux的Classpath问题:当使用Apache CXF 运行wadl2java,如果看到问题:“Could not find or load main classorg.apache.cxf.tools.wadlto.WADLToJava”,这是需要手动设置Classpath变量:exportCLASSPATH=apache-cxf-3.0.1/lib/* 解决这个问题。
Windows也要设置好Apache CXF的classpath:
生成的文件截图:
9. 需要编译生成的服务。Apache CXF的库需要classpath(-cp参数):
cd <chapter1 samples>/rest/invoicev1/src/main/java/rest/invoice/v1/ javac -d <chapter1 samples>/rest/invoicev1/target/classes/ *.java |
10. 执行如下命令运行服务:
11. 在浏览器端输入:http://localhost:9000/invoiceservice/v1?_wadl,将看到一个WADL文件表明服务器在运行:
12. 运行之前创建的测试用例:
q n 打开并编辑创建的测试用例
n 给TestStep的请求中添加一个invoiceID,例如:12345
n 运行之前添加的断言测试用例会失败,而且响应的状态码为204,在Raw Tab下没有内容。这是因为没有实施的操作
运行实例源码在服务端会出现下图所示问题,解决办法在invoice.java中修改已经指出:
修改后进行编译,然后启动服务,运行测试用例,响应结果如下:
13. 如果使用本书操作实例,不需要此步操作,在对应目录下存在操作实例源码,如果没有需要创建InvoiceserviceV1ResourceImpl.java:
/**
* Created by Apache CXF WadlToJava code generator
**/
package rest.invoice.v1;
public class InvoiceserviceV1ResourceImpl implements InvoiceserviceV1Resource {
public Invoice getInvoiceid(String id) {
ObjectFactory objectFactory = new ObjectFactory();
Invoice invoice = objectFactory.createInvoice();
invoice.setId("12345");
invoice.setCompanyName("Test Company");
invoice.setAmount(100.0d);
return invoice;
}
}