<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Se hace camino al andar... &#187; web</title>
	<atom:link href="http://blog.jmbeas.es/tag/web/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.jmbeas.es</link>
	<description>Experiencias de un informático vocacional buscando la calidad y sus efectos colaterales.</description>
	<lastBuildDate>Mon, 16 Jan 2012 07:25:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>

   <image>
    <title>Se hace camino al andar...</title>
    <url>http://0.gravatar.com/avatar/8c024022cec721aaa11dc3b092e2c29c.png?s=48</url>
    <link>http://blog.jmbeas.es</link>
   </image>
		<item>
		<title>Pruebas funcionales automatizadas de una aplicación web</title>
		<link>http://blog.jmbeas.es/2009/01/26/pruebas-funcionales-automatizadas-de-una-aplicacion-web/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pruebas-funcionales-automatizadas-de-una-aplicacion-web</link>
		<comments>http://blog.jmbeas.es/2009/01/26/pruebas-funcionales-automatizadas-de-una-aplicacion-web/#comments</comments>
		<pubDate>Mon, 26 Jan 2009 00:12:00 +0000</pubDate>
		<dc:creator>jmbeas</dc:creator>
				<category><![CDATA[Del viejo blog]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[cargo]]></category>
		<category><![CDATA[jetty]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[selenium]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[webdriver]]></category>
		<category><![CDATA[wicket]]></category>

		<guid isPermaLink="false">http://jmbeas.iexpertos.com/pruebas-funcionales-automatizadas-de-una-aplicacion-web/</guid>
		<description><![CDATA[Hoy voy a resumir cómo automatizar las pruebas funcionales de una aplicación web utilizando: Maven. Con Maven gestionamos el ciclo de vida de la construcción y las pruebas, así como las dependencias entre artefactos. Cargo. Con este plugin Maven realizamos el despliegue de la aplicación web en el contenedor de nuestra elección. Selenium Webdriver. Con [...]]]></description>
			<content:encoded><![CDATA[<div xmlns='http://www.w3.org/1999/xhtml'>Hoy voy a resumir cómo automatizar las pruebas funcionales de una aplicación web utilizando:
<ul>
<li><a target='_blank' href='http://maven.apache.org'>Maven</a>. Con Maven gestionamos el ciclo de vida de la construcción y las pruebas, así como las dependencias entre artefactos.</li>
<li><a href='http://cargo.codehaus.org/' target='_blank'>Cargo</a>. Con este plugin Maven realizamos el despliegue de la aplicación web en el contenedor de nuestra elección.</li>
<li><a href='http://code.google.com/p/webdriver/' target='_blank'>Selenium Webdriver</a>. Con este framework y el correspondiente plugin Maven ejecutamos las pruebas funcionales.</li>
<li><a href='http://jetty.morbay.org' target='_blank'>Jetty</a>. Éste es el contenedor web de mi elección. (Podría haber sido Tomcat, Glassfish o cualquier otro).</li>
<li><a href='http://www.junit.org' target='_blank'>JUnit</a>. Como framework de pruebas.</li>
<li><a href='http://wicket.apache.org/' target='_blank'>Wicket</a>. Éste es el framework web de mi elección.</li>
</ul>
<p>Todo el código fuente lo tenéis disponible en <a href='http://code.google.com/p/shopaas/source/browse/' target='_blank'>GoogleCode</a>.</p>
<p><big>Pruebas unitarias</big></p>
<p>En <a href='http://www.eclipse.org' target='_blank'>Eclipse</a> y con <a href='http://jmbeas.wikidot.com/m2eclipse' target='_blank'>m2eclipse</a> he creado el proyecto raíz con dos módulos: web (de tipo war) y web-integration-test (de tipo pom). El proyecto web lo he creado con el arquetipo &#8220;org.apache.wicket:wicket-archetype-quickstart:1.4-rc1&#8243; y luego lo he tocado un poco.</p>
<pre class='xml' name='code'>< ?xml version="1.0" encoding="UTF-8"?>
<project> 
<parent>  <artifactid>shopaas</artifactid>  <groupid>shopaas</groupid>  <version>0.0.1-SNAPSHOT</version> </parent> <modelversion>4.0.0</modelversion> <groupid>shopaas</groupid> <artifactid>web</artifactid> 
<packaging>war</packaging> <name>Web Application</name> <version>0.0.1-SNAPSHOT</version> <description>UI wicket para Shop As A Service</description> <build>  <finalname>shopaas-web</finalname>  <resources>   <resource>    <directory>src/main/resources</directory>   </resource>   <resource>    <directory>src/main/java</directory>    <includes>     <include>**</include>    </includes>    <excludes>     <exclude>**/*.java</exclude>    </excludes>   </resource>  </resources>  <testresources>   <testresource>    <directory>src/test/java</directory>    <includes>     <include>**</include>    </includes>    <excludes>     <exclude>**/*.java</exclude>    </excludes>   </testresource>  </testresources> 
<plugins> 
<plugin>    <artifactid>maven-compiler-plugin</artifactid>    <inherited>true</inherited>    <configuration>     <source>1.5</source>     <target>1.5</target>     <optimise>true</optimise>     <debug>true</debug>    </configuration>   </plugin> 
<plugin>    <groupid>org.mortbay.jetty</groupid>    <artifactid>maven-jetty-plugin</artifactid>    <configuration>     <scanintervalseconds>10</scanintervalseconds>     <connectors>      <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector"> 
<port>8080</port>       <maxidletime>60000</maxidletime>      </connector>     </connectors>    </configuration>   </plugin> 
<plugin>    <artifactid>maven-eclipse-plugin</artifactid>    <configuration>     <downloadsources>true</downloadsources>    </configuration>   </plugin>  </plugins> </build> <dependencies>  <dependency>   <groupid>org.apache.wicket</groupid>   <artifactid>wicket</artifactid>   <version>${wicket.version}</version>  </dependency>  <dependency>   <groupid>org.slf4j</groupid>   <artifactid>slf4j-log4j12</artifactid>   <version>1.4.2</version>  </dependency>  <dependency>   <groupid>log4j</groupid>   <artifactid>log4j</artifactid>   <version>1.2.14</version>  </dependency>  <dependency>   <groupid>junit</groupid>   <artifactid>junit</artifactid>   <version>4.5</version>   <scope>test</scope>  </dependency>  <dependency>   <groupid>org.mortbay.jetty</groupid>   <artifactid>jetty</artifactid>   <version>${jetty.version}</version>   <scope>provided</scope>  </dependency>  <dependency>   <groupid>org.mortbay.jetty</groupid>   <artifactid>jetty-util</artifactid>   <version>${jetty.version}</version>   <scope>provided</scope>  </dependency>  <dependency>   <groupid>org.mortbay.jetty</groupid>   <artifactid>jetty-management</artifactid>   <version>${jetty.version}</version>   <scope>provided</scope>  </dependency> </dependencies> 
<properties>  <jetty .version>6.1.14</jetty>  <wicket .version>1.4-rc1</wicket> </properties></project></pre>
<p>No quiero entrar en detalles sobre <a target="_blank" href="http://www.ibm.com/developerworks/web/library/wa-aj-wicket/index.html?ca=dgr-jw22wa-aj-wicket&#038;S_TACT=105AGX59&#038;S_CMP=GRsitejw22">cómo es una aplicación Wicket</a>, pero sí explicaré los dos detalles más importantes:</p>
<p>Si quiero desplegar la aplicación en Jetty no tengo más que ejecutar Maven con el &#8220;goal&#8221; jetty:run, pero esto sólo nos sirve para probar manualmente nuestra aplicación. (Por cierto, el puerto 8080 es el puerto por defecto, pero me gusta explicitar esta configuración).</p>
<p>Wicket proporciona la clase <a target="_blank" href="http://cwiki.apache.org/WICKET/testing-pages.html">WicketTester</a>, que permite probar la aplicación fuera del contenedor, mediante una simulación del mismo. De esta manera podemos hacer pruebas unitarias de todos los componentes de nuestra GUI sin necesidad de empaquetarla y desplegarla. Más adelante, en futuros artículos, tengo previsto entrar en detalle en cómo desarrollar la GUI con Wicket haciendo <a target="_blank" href="http://es.wikipedia.org/wiki/Tdd">TDD</a>.</p>
<pre name='code' class='java'>package shopaas;

import junit.framework.TestCase;import org.apache.wicket.util.tester.WicketTester;

/** * Simple test using the WicketTester */public class TestHomePage extends TestCase{ private WicketTester tester;

 <a href="http://twitter.com/Override" class="twitter-user-link" title="Override profile on Twitter" target="_blank">@Override</a> public void setUp() {  tester = new WicketTester(new WicketApplication()); }

 public void testRenderMyPage() {  //start and render the test page  tester.startPage(HomePage.class);

  //assert rendered page class  tester.assertRenderedPage(HomePage.class);

  //assert rendered label component  tester.assertLabel("message", "If you see this message wicket is properly configured and running"); }}
</pre>
<p>Esta prueba es muy simple, pero lo suficiente como para ver &#8220;por dónde van los tiros&#8221;. Como podéis comprobar, llegados a este punto podemos tener las pruebas unitarias de nuestra aplicación web completamente automatizadas y, por tanto, incluidas en nuestro sistema de integración continua sin mayor problema.</p>
<p><big>Pruebas funcionales</big></p>
<p>Pruebas funcionales o de integración son términos muy usados pero no tengo claro que todo el mundo entienda lo mismo cuando los usa. Lo que yo estoy llamando aquí pruebas funcionales o de integración son aquellas en las que pruebo el sistema desplegado (hasta donde se puede razonablemente). Pues bien, lo que voy a enseñar ahora es cómo desplegar de manera automática el war de nuestra aplicación y lanzar (automáticamente también) las pruebas.</p>
<p>Para esto he usado Cargo y he modificado el ciclo de vida de varios plugins (compiler, surefire y el propio cargo) para que se ejecuten en el orden adecuado. Además, he usado <a href="http://code.google.com/p/webdriver/wiki/UsingWebDriver" target="_blank">Selenium Webdriver</a> para escribir y ejecutar las pruebas.</p>
<p>Al ejecutar (desde el proyecto raiz) Maven con el goal &#8220;integration-test&#8221;, el propio Maven estudia las dependencias entre artefactos y empaqueta el war (y ejecuta sus pruebas) antes de pasar a desplegar ese war en un Jetty 6 que se arranca y detiene solamente para ejecutar las pruebas de integración.</p>
<pre name='code' class='xml'>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

 <modelversion>4.0.0</modelversion> 
<parent>  <groupid>shopaas</groupid>  <artifactid>shopaas</artifactid>  <version>0.0.1-SNAPSHOT</version> </parent> <artifactid>web-integration-test</artifactid> 
<packaging>pom</packaging> <name>Functional Tests</name> <dependencies>  <dependency>   <groupid>shopaas</groupid>   <artifactid>web</artifactid>   <version>0.0.1-SNAPSHOT</version>   <type>war</type>  </dependency>  <dependency>   <groupid>junit</groupid>   <artifactid>junit</artifactid>   <version>4.5</version>   <scope>test</scope>  </dependency>  <!-- SELENIUM WEBDRIVER -->  <dependency>   <groupid>org.openqa.selenium.webdriver</groupid>   <artifactid>webdriver-htmlunit</artifactid>   <version>0.6.685</version>  </dependency>  <dependency>   <groupid>org.openqa.selenium.webdriver</groupid>   <artifactid>webdriver-support</artifactid>   <version>0.6.685</version>  </dependency>  <!--  JETTY DEPENDENCIES FOR TESTING  -->  <dependency>   <groupid>org.mortbay.jetty</groupid>   <artifactid>jetty</artifactid>   <version>${jetty.version}</version>   <scope>provided</scope>  </dependency>  <dependency>   <groupid>org.mortbay.jetty</groupid>   <artifactid>jetty-util</artifactid>   <version>${jetty.version}</version>   <scope>provided</scope>  </dependency>  <dependency>   <groupid>org.mortbay.jetty</groupid>   <artifactid>jetty-management</artifactid>   <version>${jetty.version}</version>   <scope>provided</scope>  </dependency> </dependencies> <build>  <!--   We need to force the compiler plugin to compile tests and the   surefire plugin to execute them because we're using a pom packaging   that doesn't have those mapped in its lifecycle.  --> 
<plugins> 
<plugin>    <groupid>org.apache.maven.plugins</groupid>    <artifactid>maven-compiler-plugin</artifactid>    <configuration>     <source>1.5</source>     <target>1.5</target>     <optimise>true</optimise>     <debug>true</debug>    </configuration>    <executions>     <execution>      <goals>       <goal>testCompile</goal>      </goals>     </execution>    </executions>   </plugin> 
<plugin>    <groupid>org.apache.maven.plugins</groupid>    <artifactid>maven-surefire-plugin</artifactid>    <executions>     <execution> 
<phase>integration-test</phase>      <goals>       <goal>test</goal>      </goals>     </execution>    </executions>   </plugin> 
<plugin>    <groupid>org.codehaus.cargo</groupid>    <artifactid>cargo-maven2-plugin</artifactid>    <configuration>     <wait>false</wait>     </configuration><configuration>      <deployables>       <deployable>        <groupid>shopaas</groupid>        <artifactid>web</artifactid>        <type>war</type> 
<properties>         <context>/</context>        </properties>       </deployable>      </deployables>     </configuration>

    <executions>     <execution>      <id>start</id> 
<phase>pre-integration-test</phase>      <goals>       <goal>start</goal>      </goals>     </execution>     <execution>      <id>stop</id> 
<phase>post-integration-test</phase>      <goals>       <goal>stop</goal>      </goals>     </execution>    </executions>   </plugin>  </plugins> </build> 
<profiles> 
<profile>   <id>jetty6x</id>   <activation>    <activebydefault>true</activebydefault>   </activation> 
<properties>    <jetty .version>6.1.14</jetty>   </properties>   <build> 
<plugins> 
<plugin>      <groupid>org.codehaus.cargo</groupid>      <artifactid>cargo-maven2-plugin</artifactid>      <configuration>       <container>        <containerid>jetty6x</containerid>        <type>embedded</type>       </container>       </configuration><configuration> 
<properties>         <cargo .servlet.port>8080</cargo>         <cargo .logging>medium</cargo>        </properties>       </configuration>
</plugin>    </plugins>   </build>  </profile> </profiles>
</pre>
<p>El único test que he incluido como prueba de concepto contiene dos tipos de prueba (una con <a href="http://code.google.com/p/webdriver/wiki/GettingStarted" target="_blank">Webdriver</a> y otra sin él, la anotada con @Ignore).</p>
<pre name='code' class='java'>package shopaas.web.integration.test;

import static org.junit.Assert.assertEquals;

import java.net.HttpURLConnection;import java.net.URL;

import org.junit.Before;import org.junit.Ignore;import org.junit.Test;import org.openqa.selenium.WebDriver;import org.openqa.selenium.htmlunit.HtmlUnitDriver;

public class WebappTest {

 <a href="http://twitter.com/Ignore" class="twitter-user-link" title="Ignore profile on Twitter" target="_blank">@Ignore</a> <a href="http://twitter.com/Test" class="twitter-user-link" title="Test profile on Twitter" target="_blank">@Test</a> public void testCallIndexPage() throws Exception {  URL url = new URL("http://localhost:8080/");  HttpURLConnection connection = (HttpURLConnection) url.openConnection();  connection.connect();  assertEquals(200, connection.getResponseCode()); }

 private WebDriver driver;

 <a href="http://twitter.com/Before" class="twitter-user-link" title="Before profile on Twitter" target="_blank">@Before</a> public void setUp() {  driver = new HtmlUnitDriver(); }

 <a href="http://twitter.com/Test" class="twitter-user-link" title="Test profile on Twitter" target="_blank">@Test</a> public void testHomepage() {  driver.get("http://localhost:8080/");  assertEquals("Wicket Quickstart Archetype Homepage", driver.getTitle()); }

}
</pre>
<p>He utilizado el <a href="http://code.google.com/p/webdriver/wiki/HtmlUnitDriver" target="_blank">HtmlUnitDriver</a> que, aunque también es una emulación de una navegador, para mi es suficiente, no me complica mi entorno y además es más rápido. Pero si quisiera utilizar Firefox, Safari o Internet Explorer, no tendría más que cambiar el driver correspondiente. Lógicamente, podemos tener la misma prueba con un driver diferente y estaremos asegurando que nuestra aplicación funciona para varios navegadores. Mmmmm, veo que he captado vuestra atención&#8230; <img src='http://blog.jmbeas.es/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><big>Problemas encontrados</big></p>
<p>Al poner todo esto en pie he estado bastante tiempo atascado porque cada vez que ejecutaba las pruebas de integración obtenía un mensaje de error en Jetty diciendo que no era capaz de arrancar la aplicación porque &#8220;No suitable Log constructor&#8221;. No entiendo de dónde sale el dichoso commons-logging, pero el caso es que <a href="http://www.nabble.com/cargo-maven2-plugin-causing-exceptions-during-build-because-of-commons-logging-td19197018.html#a19197018" target="_blank">poniendo el fichero commons-logging.properties en el classpath</a> de la aplicación web (para que se empaquete en el war), todo pasó a funcionar perfectamente.</p>
<pre name='code' class='js'>org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog
</pre>
<p>El otro inconveniente que tuve es más un detalle al que prestar atención que otra cosa. Se trata del valor del contexto que hay que poner en la configuración de Cargo, que debe coincidir con el valor usado en el URL de la aplicación en nuestras pruebas y en el fichero web.xml de la aplicación web.</p>
<pre name='code' class='xml'> 
<plugin>    <groupid>org.codehaus.cargo</groupid>    <artifactid>cargo-maven2-plugin</artifactid>    <configuration>     <wait>false</wait>     </configuration><configuration>      <deployables>       <deployable>        <groupid>shopaas</groupid>        <artifactid>web</artifactid>        <type>war</type> 
<properties>         <context>/</context>        </properties>       </deployable>      </deployables>     </configuration>

    <executions>                                ...    </executions>   </plugin></pre>
<p>Bien, creo que esto es todo. Si tenéis interés y el código de ejemplo no es suficiente, no dudéis en preguntarme y trataré de ayudaros.</p></div>
<div class="blogger-post-footer">http://jmbeas.blogspot.com</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.jmbeas.es/2009/01/26/pruebas-funcionales-automatizadas-de-una-aplicacion-web/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SOFEA: ¿Cómo hacer una capa de presentación orientada a servicios?</title>
		<link>http://blog.jmbeas.es/2008/03/02/sofea-%c2%bfcomo-hacer-una-capa-de-presentacion-orientada-a-servicios/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sofea-%25c2%25bfcomo-hacer-una-capa-de-presentacion-orientada-a-servicios</link>
		<comments>http://blog.jmbeas.es/2008/03/02/sofea-%c2%bfcomo-hacer-una-capa-de-presentacion-orientada-a-servicios/#comments</comments>
		<pubDate>Sat, 01 Mar 2008 23:52:00 +0000</pubDate>
		<dc:creator>jmbeas</dc:creator>
				<category><![CDATA[Del viejo blog]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[soa]]></category>
		<category><![CDATA[sofea]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://jmbeas.iexpertos.com/sofea-%c2%bfcomo-hacer-una-capa-de-presentacion-orientada-a-servicios/</guid>
		<description><![CDATA[Hace ya bastante tiempo que he oido hablar a mi compañero Xavi Gost acerca de SOFEA. He estado leyendo un artículo de Matt Raible y me ha parecido bastante interesante. Pero lo que más me ha llamado la atención es la visita que a continuación he hecho a la demo de AppCelerator. Es realmente espectacular. [...]]]></description>
			<content:encoded><![CDATA[<div xmlns='http://www.w3.org/1999/xhtml'>Hace ya bastante tiempo que he oido hablar a mi compañero Xavi Gost acerca de <a href='http://wisdomofganesh.blogspot.com/2007/10/life-above-service-tier.html'>SOFEA</a>. He estado leyendo un <a href='http://raibledesigns.com/rd/entry/sofea_also_known_as_soui'>artículo de Matt Raible</a> y me ha parecido bastante interesante. Pero lo que más me ha llamado la atención es la visita que a continuación he hecho a la <a href='http://unittest.appcelerator.org/index.html'>demo de AppCelerator</a>. Es realmente espectacular. Visitad el ejemplo de los gráficos (Widgets > Chart > Line Chart).<br/><br/></div>
<div class="blogger-post-footer">http://jmbeas.blogspot.com</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.jmbeas.es/2008/03/02/sofea-%c2%bfcomo-hacer-una-capa-de-presentacion-orientada-a-servicios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

