Solución:
La mayoría de las veces pruebo Servlets y JSP a través de ‘Pruebas de integración’ en lugar de pruebas unitarias puras. Hay una gran cantidad de complementos disponibles para JUnit / TestNG, que incluyen:
- HttpUnit (el más antiguo y más conocido, de muy bajo nivel que puede ser bueno o malo según tus necesidades)
- HtmlUnit (nivel más alto que HttpUnit, que es mejor para muchos proyectos)
- JWebUnit (se coloca encima de otras herramientas de prueba e intenta simplificarlas, la que yo prefiero)
- WatiJ y Selenium (use su navegador para hacer las pruebas, que es más pesado pero realista)
Esta es una prueba de JWebUnit para un Servlet de procesamiento de pedidos simple que procesa la entrada del formulario ‘orderEntry.html’. Espera una identificación de cliente, un nombre de cliente y uno o más artículos de pedido:
public class OrdersPageTest {
private static final String WEBSITE_URL = "http://localhost:8080/demo1";
@Before
public void start() {
webTester = new WebTester();
webTester.setTestingEngineKey(TestingEngineRegistry.TESTING_ENGINE_HTMLUNIT);
webTester.getTestContext().setBaseUrl(WEBSITE_URL);
}
@Test
public void sanity() throws Exception {
webTester.beginAt("/orderEntry.html");
webTester.assertTitleEquals("Order Entry Form");
}
@Test
public void idIsRequired() throws Exception {
webTester.beginAt("/orderEntry.html");
webTester.submit();
webTester.assertTextPresent("ID Missing!");
}
@Test
public void nameIsRequired() throws Exception {
webTester.beginAt("/orderEntry.html");
webTester.setTextField("id","AB12");
webTester.submit();
webTester.assertTextPresent("Name Missing!");
}
@Test
public void validOrderSucceeds() throws Exception {
webTester.beginAt("/orderEntry.html");
webTester.setTextField("id","AB12");
webTester.setTextField("name","Joe Bloggs");
//fill in order line one
webTester.setTextField("lineOneItemNumber", "AA");
webTester.setTextField("lineOneQuantity", "12");
webTester.setTextField("lineOneUnitPrice", "3.4");
//fill in order line two
webTester.setTextField("lineTwoItemNumber", "BB");
webTester.setTextField("lineTwoQuantity", "14");
webTester.setTextField("lineTwoUnitPrice", "5.6");
webTester.submit();
webTester.assertTextPresent("Total: 119.20");
}
private WebTester webTester;
}
Pruebe HttpUnit, aunque es probable que termine escribiendo pruebas automatizadas que son más ‘pruebas de integración’ (de un módulo) que ‘pruebas unitarias’ (de una sola clase).
Miré las respuestas publicadas y pensé que publicaría una solución más completa que realmente demuestre cómo realizar las pruebas utilizando GlassFish incrustado y su complemento Apache Maven.
Escribí el proceso completo en mi blog Usando GlassFish 3.1.1 Embedded con JUnit 4.xy HtmlUnit 2.xy coloqué el proyecto completo para descargar en Bitbucket aquí: image-servlet
Estaba viendo otra publicación en un servlet de imagen para etiquetas JSP / JSF justo antes de ver esta pregunta. Así que combiné la solución que usé de la otra publicación con una versión completa probada por unidad para esta publicación.
Cómo probar
Apache Maven tiene un ciclo de vida bien definido que incluye test
. Usaré esto junto con otro ciclo de vida llamado integration-test
para implementar mi solución.
- Deshabilite las pruebas unitarias de ciclo de vida estándar en el complemento seguro.
- Agregar
integration-test
como parte de las ejecuciones del complemento seguro - Agregue el complemento GlassFish Maven al POM.
- Configure GlassFish para que se ejecute durante la
integration-test
ciclo vital. - Ejecutar pruebas unitarias (pruebas de integración).
Complemento GlassFish
Agregue este complemento como parte del <build>
.
<plugin>
<groupId>org.glassfish</groupId>
<artifactId>maven-embedded-glassfish-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<!-- This sets the path to use the war file we have built in the target directory -->
<app>target/${project.build.finalName}</app>
<port>8080</port>
<!-- This sets the context root, e.g. http://localhost:8080/test/ -->
<contextRoot>test</contextRoot>
<!-- This deletes the temporary files during GlassFish shutdown. -->
<autoDelete>true</autoDelete>
</configuration>
<executions>
<execution>
<id>start</id>
<!-- We implement the integration testing by setting up our GlassFish instance to start and deploy our application. -->
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
<goal>deploy</goal>
</goals>
</execution>
<execution>
<id>stop</id>
<!-- After integration testing we undeploy the application and shutdown GlassFish gracefully. -->
<phase>post-integration-test</phase>
<goals>
<goal>undeploy</goal>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
Complemento Surefire
Agregue / modifique el complemento como parte del <build>
.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<!-- We are skipping the default test lifecycle and will test later during integration-test -->
<configuration>
<skip>true</skip>
</configuration>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<!-- During the integration test we will execute surefire:test -->
<goal>test</goal>
</goals>
<configuration>
<!-- This enables the tests which were disabled previously. -->
<skip>false</skip>
</configuration>
</execution>
</executions>
</plugin>
HTMLUnit
Agregue pruebas de integración como el ejemplo siguiente.
@Test
public void badRequest() throws IOException {
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
webClient.getOptions().setPrintContentOnFailingStatusCode(false);
final HtmlPage page = webClient.getPage("http://localhost:8080/test/images/");
final WebResponse response = page.getWebResponse();
assertEquals(400, response.getStatusCode());
assertEquals("An image name is required.", response.getStatusMessage());
webClient.getOptions().setThrowExceptionOnFailingStatusCode(true);
webClient.getOptions().setPrintContentOnFailingStatusCode(true);
webClient.closeAllWindows();
}
Escribí el proceso completo en mi blog Usando GlassFish 3.1.1 Embedded con JUnit 4.xy HtmlUnit 2.xy coloqué el proyecto completo para descargar en Bitbucket aquí: image-servlet
Si tiene alguna pregunta, deje un comentario. Creo que este es un ejemplo completo para que lo use como base de cualquier prueba que esté planeando para los servlets.