因为本文提供的程序为示例程序,所以测试过程使用 TestRunner 类来模拟测试运行的过程。当 RunTestServlet 接收到客户端运行测试请求的时候,会创建一个 TestRunner 对象,并调用 TestRunner.start() 来启动测试线程。TestRunner 的方法包括:
清单 12. TestRunner 的模拟测试实现public class TestRunner extends Thread{ private List testResults; private int caseNum = 0; private String[] suiteNames = null; public void init(int caseNum, String[] suiteNames) { testResults= new ArrayList(); this.suiteNames = suiteNames; this.caseNum = caseNum; } /** * invoke the server-side test tool */ public void run() { // simulate the running test tool for (int j = 0; j < suiteNames.length; j++) { for (int i = 0; i < caseNum; i++) { TestResult tr = new TestResult(); tr.setName(suiteNames[j] + "-case-" + i); tr.setStart(new Date().toString()); try { //simulate the test Thread.sleep(1200); } catch (InterruptedException e) { e.printStackTrace(); } tr.setEnd(new Date().toString()); tr.setResult(genRandomResult()); testResults.add(tr); } } } /** * simulate test results * @return */ private String genRandomResult(){ int result = new Random().nextInt(3); return result==1?"FAIL":"PASS"; } /** * read the dynamic test results (such as result log file) */ public List getTestResults(){ return this.testResults; } }
服务器端 JSON 数据的解析和转换已经有文章介绍了 JSON 数据到 JSON Java 类的解析转换。在通常开发中,在系统中通常使用各种 JavaBean 来代表系统中的业务对象,如本示例程序中的 JavaBean TestResult 和 RequestForm。如果直接采用以前使用的方法,则需要多做 JSON Java 类和 JavaBean 相互转换的一步。SOJO 则可以解决这个问题,实现 JSON 数据和 JavaBean 的直接转换。
服务器端的业务类如清单13,14。
清单 13. RequestForm 类public class RequestForm { private int caseNum =0; private String[] testSuites = null; //getter and setter … }
清单 14. TestResult 类public class TestResult { private String name; private String start; private String end; private String result; //getter and setter … }
SOJO 作为一个轻量级的数据转换工具,支持 JavaBean 和各种编码的数据格式,如 JSON,进行相互转换。使用 SOJO 的 net.sf.sojo.interchange.json.JsonSerializer 可以轻松的序列/反序列化 JSON 数据和 JavaBean。
从 JSON 数据到 JavaBean。如 ,指定请求信息所映射的 JavaBean,反序列化请求信息字符串。SOJO 将会自动把 JSON 格式数据转换为指定类的 JavaBean。
清单 15. 反序列化 JSON 格式字符串RequestForm requestForm = (RequestForm) serializer.deserialize( payLoad, RequestForm.class);
从 JavaBean 到 JSON 数据:
清单 16. 序列化 JavaBean,生成 JSON 格式字符串List results = testRunner.getTestResults(); String result = (String)serializer.serialize(results.toArray());
其它 JavaBean 和 JSON 数据转换工具:json-lib。同样支持 JavaBean 和 JSON数据之间的解析转换。在这里就不详细介绍了。相对 SOJO 来说,它还支持从 Map 到 JSON 格式的转换,这种方式也非常的方便。
GWT RemoteServiceServlet介绍
GWT 提供的为实现服务器端远程调用服务而提供的 servlet 基类。RemoteServiceServlet 能够自动的反序列化客户端发送的请求信息,也可以序列化返回信息。示例程序中,我们使用 RunTestServlet 来继承 RemoteServiceServlet。
Servlet 配置在 GWT 项目中的配置。
在 GWT 项目中,如果需要配置 servlet 映射,在 Module 的配置文件中添加该 servlet 的声明。以示例程序为例,在 src/unitTest/MainApplication.gwt.xml 中添加 <servlet path='/runTest'/>。
重载 String processCall(String payLoad)实现业务逻辑
用 RunTestServlet 继承 RemoteServiceServlet,并重载 processCall 方法。在 processCall 方法里可以得到当前客户端的请求信息。读取参数 payLoad 里可以得到请求信息文本。当一系列业务处理以后,服务器端返回一个字符串作为此次请求的返回信息。以示例程序为例,服务器端接收到的 payLoad 是:{"caseNum":"3", "testSuites":["TestSuite2","TestSuite3","TestSuite5"]} 。返回的信息为: [{"start":"Fri Jul 13 11:09:55 CST 2007","name":"TestSuite2-case-0","~unique-id~":"0","result":"FAIL","end":"Fri Jul 13 11:09:56 CST 2007","class":"unitTest.entity.TestResult"}] 。清单 11 给出了服务器端 processCall 方法实现代码。
清单 11. RunTestServlet 的 processCall 方法public String processCall(String payLoad) { System.out.println("Received payLoad:" + payLoad); Object result = ""; if (!payLoad.startsWith("getRuntimeResults")) { //parse the request JSON string into javabean requestForm RequestForm requestForm = (RequestForm) serializer.deserialize( payLoad, RequestForm.class); //start a test runner to simulate the unit test testRunner = new TestRunner(); testRunner.init(requestForm.getCaseNum(), requestForm .getTestSuites()); testRunner.start(); } //get runtime results if (testRunner != null) { List results = testRunner.getTestResults(); //transform list of javabeans into JSON string result = serializer.serialize(results.toArray()); } System.out.println("Return Result:" + result.toString()); return result.toString(); }