2012-07-31 21 views
10

Estoy tratando de desarrollar algunas pruebas de integración efectivas para mi aplicación GAE/j. Estoy familiarizado con https://developers.google.com/appengine/docs/java/tools/localunittesting - estas herramientas son excelentes para pruebas de unidades pequeñas. Ahora estoy interesado en desarrollar pruebas de integración que prueben las solicitudes web reales. Por ejemplo, me gustaría probar que web.xml está mapeando servlets y filtros a las URL esperadas y prueba que mis JSP generen lo que espero.Pruebas de integración para Google App Engine (java)

Mi objetivo era abrir un servidor de desarrollo local dentro de la JVM, contra el cual podía disparar las solicitudes. Sin embargo, estoy abierto a otras estrategias de integración; como dije antes, solo quiero probar efectivamente la generación de JSP y otras características de nivel de solicitud.

He logrado utilizar DevAppServerFactory para iniciar un servidor de desarrollo en la misma JVM. Sin embargo, parece que el DevAppServer que esto genera usa un cargador de clases separado de la JVM principal. Esto hace que las pruebas sean mucho más desafiantes. No puedo usar ninguna de las pruebas locales locales * TestConfig para controlar el comportamiento de este servidor. Del mismo modo, no puedo "rodar mis propios ganchos" para modificar el comportamiento a través, p. Ej. estática, ya que las estáticas que puedo mutar en el arnés de prueba no son las mismas estáticas que el DevAppServer está mirando. Esto hace que sea difícil omitir características que no son centrales para la prueba actual (por ejemplo, que requiera inicio de sesión), inyectar fallas, inyectar simulacros, etc. Esto realmente limita la manera en que puedo probar mi código de manera completa y eficiente.

He encontrado una gran escasez de documentación en la web para realizar pruebas de integración con App Engine. Estoy seguro de que alguien ha hecho esto antes ... ¿hay algún consejo o recurso que puedas compartir?

Respuesta

2

Básicamente, lo que necesita hacer dos cosas:

  1. añadir dos servlets (o lo que sea), que debe ser sólo permitió durante las pruebas, que le permite invocar montaje y desmontaje en el ayudante de forma remota.
  2. Realice las solicitudes de servicio del motor de servlet en un completamente de una sola rosca. Esto es necesario porque, por alguna razón, la clase Helper que proporciona Google solo tiene efecto en el hilo actual.
0

Acepto que este problema está poco documentado.
Logré escribir una prueba de extremo a extremo que inicia un servidor como una caja negra y lo envía solicitudes HTTP.

funciona así:

package com.project.org; 

import static org.junit.Assert.assertEquals; 
import java.io.File; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.ArrayList; 
import java.util.List; 
import org.junit.After; 
import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import com.google.appengine.api.urlfetch.HTTPResponse; 
import com.google.appengine.api.urlfetch.URLFetchServiceFactory; 
import com.google.appengine.tools.development.testing.BaseDevAppServerTestConfig; 
import com.google.appengine.tools.development.testing.DevAppServerTest; 
import com.google.appengine.tools.development.testing.DevAppServerTestRunner; 
import com.google.appengine.tools.development.testing.LocalServiceTestHelper; 

@RunWith(DevAppServerTestRunner.class) 
@DevAppServerTest(HelloWorldTest.TestConfig.class) 
public class HelloWorldTest { 

    public class TestConfig extends BaseDevAppServerTestConfig { 

    @Override public File getSdkRoot() { 
     // You may need to tweak this. 
     return new File("../../appengine-java-sdk-1.9.15"); 
    } 

    @Override public File getAppDir() { 
     return new File("war"); 
    } 

    @Override 
    public List<URL> getClasspath() { 
     // There may be an easier way to do this. 
     List<URL> classPath = new ArrayList<>(); 
     try { 
     String separator = System.getProperty("path.separator"); 
     String[] pathElements = System.getProperty("java.class.path").split(separator); 
     for (String pathElement : pathElements) { 
      classPath.add(new File(pathElement).toURI().toURL()); 
     } 
     } 
     catch (MalformedURLException e) { 
     throw new RuntimeException(e); 
     } 
     return classPath; 
    } 
    } 

    private final LocalServiceTestHelper testHelper; 
    private final String port; 

    public HelloWorldTest() { 
    testHelper = new LocalServiceTestHelper(); 
    port = System.getProperty("appengine.devappserver.test.port"); 
    } 

    @Before public void setUpServer() { 
    testHelper.setUp(); 
    } 

    @After public void tearDown() { 
    testHelper.tearDown(); 
    } 

    @Test public void testHelloWorld() throws Exception { 
    URL url = new URL("http://localhost:" + port + "/hello"); 
    HTTPResponse response = URLFetchServiceFactory.getURLFetchService().fetch(url); 
    assertEquals(200, response.getResponseCode()); 
    assertEquals("Hello world!", new String(response.getContent(), "UTF-8")); 
    } 
} 

Ahora el problema que tengo es que si usted tiene dos de esas pruebas, con cada paso individual, no se puede ejecutarlos en el mismo binario. La excepción en la línea 37 de this file son lanzados:

IllegalStateException ("Dev Appserver ya se está ejecutando.")

No estoy seguro de cómo solucionar este problema.