`

REST在Automation Testing中的应用

 
阅读更多

 背景:

      在进行web自动化测试过程中(eg. Selenium),测试代码和Application代码是分开的。也就是说,自动化测试的代码中是不能调用Application的代码。只是在test case运行时,利用application的web容器。

      这样就会遇到一个问题,Application中的某些功能,需要后台service执行后才能获得数据,这些service一般是定时执行的。在自动化测试中,比如click页面上的某些按钮,要想在页面上看到数据,需要等待service执行以后,才能看到数据。有些service的执行周期可能是24小时。显然不能让test case等待24小时后再检查数据。

 

解决方案:

      针对上述问题,很容易想到的解决办法,就是在test case执行过程中,显式地调用application的后台service。前面提到过,test代码是不能调用application的代码。那该怎么办呢?

      一个通用的解决办法是,把application的service功能封装成标准的接口,比如 web service,REST等,对外开放。然后在test中调用这些标准的web service或REST接口。这样就解决了依赖的问题。

 

具体实现:

        这里以REST为例,介绍把application后台service封装成RESTFul接口的方法。在实际的开发过程中,会有很多后台service。随着系统的升级,可能还会增加新的service。如果每增加一个service,都开放一个RESTful接口,就会是系统变得越来越笨重。而且有些开发是plugin的形式,也不允许新增Restful接口。

        这就需要在系统设计的时候,考虑到这一点。怎么办呢?在Application core中定义一个RESTful接口对外开放。在这个开放的接口中进行内部处理。方法是,定义一个可扩展的REST Service接口,通过JDK的java.util.ServiceLoader来加载实现该REST Service接口的具体类。根据URL中指定的serviceName来触发相应的REST Service。

   以Apache Wink Framework为例,介绍部署RESTful API的方法

--------------------------Application core中的RESTful接口------------------------------------------------------

package com.mycompany.rest;

@Path("/automation/AutomationServiceTest")
public class TestingRestfulResource {

    private static Map<String, AutomationServiceTest> serviceTestMap =
            new HashMap<String, AutomationServiceTest>();

 

    static {
        ServiceLoader<AutomationServiceTest> driverProvider =
                ServiceLoader.load(AutomationServiceTest.class);
        for (AutomationServiceTestserviceTest : driverProvider) {
            serviceTestMap.put(serviceTest.getServiceName(), serviceTest);
        }

    }

    @GET
    @Produces({MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
    public Object runService(@Context final HttpServletRequest request)
            throws WSException
    {
        // The service name like "AgileSyncService"
        String serviceName = request.getParameter("serviceName");
        AutomationServiceTest serviceTest = serviceTestMap.get(serviceName);
        if (null == serviceTest) {
            log.error("Service " + serviceName + "not found");
            throw new WSException(Response.Status.INTERNAL_SERVER_ERROR, request,
                    WSErrorHelper
                            .createWSError("INT_SERVICE_NOT_FOUND", new String[] {serviceName}));
        }
        return serviceTest.runService(request);
    }

}

 在wink_ws.app文件中增加一行

com.mycompany.rest.TestingRestfulResource

 

-------------------------AutomationServiceTest 接口-------------------------------------

package com.mycompany.test.plugin.rest.service;

 

import javax.servlet.ServletRequest;

public interface AutomationServiceTest {
    public Object runService(ServletRequest request);

    public String getServiceName();
}

 
----------------------RESTful service实现类--------------------------------------------
package com.mycompany.test.plugin.rest.service.impl

 

public class MyServiceTestImpl implements AutomationServiceTest {

    @Override
    public Object runService(ServletRequest request) {
        MyService service = new MyService ();
        service.runService("jobID", 2L, 2L);
        return "<result>run my service successfully</result>";
    }

    @Override
    public String getServiceName() {
        return "MyService";
    }

}
 

在/META-INF/services/com.mycompany.test.plugin.rest.service.AutomationServiceTest 文件中增加一行

com.mycompany.test.plugin.rest.service.impl.MyServiceTestImpl

-------------------------------------------------------------------------------------------------------------------

 

这样,通过URL:

http://localhost:8080/<my app>/rest/automation/AutomationServiceTest?serviceName=MyService

就可以在Automation Testing的代码中调用RESTful接口,进而触发后台servie。

比如,利用Cactus framework,可以按照如下方式编写testing code。

 

package com.mycompany.webdriver.page.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpParams;
import org.junit.Before;
import org.junit.Test;

 

 

public class TestMyServic {

      private static final String SERVICE_URL = "http://localhost:8080/app/rest/automation/AutomationServiceTest?serviceName=MyService";

 

    private DefaultHttpClient client;
    private HttpGet get;  
  
   
    @Before
    public void setup() {
        //For REST API Call
        client = new DefaultHttpClient();
        //set time out
        HttpParams params = new BasicHttpParams();
        params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 6000);
        client.setParams(params);

        get = new HttpGet();

    }

 

    @Test
    public void testCallService() {
       
        System.out.println("begin............");
       
        get.setURI(URI.create(SERVICE_URL));
        
        HttpResponse response;
        try {
            response = client.execute(get);
            String responseText = getHttpResponseBodyContent(response);
           
            System.out.println("******response: " + responseText);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
       
       
        System.out.println("end............");
       
    }
   

   
    private static String getHttpResponseBodyContent(HttpResponse response) throws IllegalStateException, IOException{
        String result = null;
       
        BufferedReader bufferedReader = null;
        try{
            bufferedReader = new BufferedReader(
                    new InputStreamReader((response.getEntity().getContent())));
           
            StringBuilder sb = new StringBuilder();
            String outputLine;
           
            while ((outputLine = bufferedReader.readLine()) != null) {
                sb.append(outputLine);
            }
           
            result = sb.toString();
        }finally{
            bufferedReader.close();
        }
       
        return result;
    }

 

}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics