José Arrarte | Blog de notas » jarrarte http://josearrarte.com/blog Un bloc de notas online sobre Java, tecnología, Uruguay, etc... Fri, 03 Sep 2010 02:39:05 +0000 en hourly 1 http://wordpress.org/?v=3.0.1 Editar archivos de Office 2007 en versiones anteriores de Office http://josearrarte.com/blog/2010/08/08/editar-archivos-de-office-2007-en-versiones-anteriores-de-office/ http://josearrarte.com/blog/2010/08/08/editar-archivos-de-office-2007-en-versiones-anteriores-de-office/#comments Sun, 08 Aug 2010 22:34:06 +0000 jarrarte http://josearrarte.com/blog/?p=420
  • Pantalla widescreen (16:10) en Powerpoint
  • 64GB de RAM en un sistema operativo de 32 bits
  • ]]>
    Según Microsoft,

    Al instalar el paquete de compatibilidad junto con Office 2000, Office XP u Office 2003, podrá abrir, editar y guardar archivos con los nuevos formatos de Word 2007, Excel 2007 y PowerPoint 2007. El paquete de compatibilidad puede utilizarse junto con Microsoft Office Word Viewer 2003, Excel Viewer 2003 y PowerPoint Viewer 2003 para ver los archivos guardados con estos formatos.

    El paquete de compatibilidad pesa 37.2 MB y se puede descargar en ésta página. Es un instalador llamado FileFormatConverters.exe, y el proceso de instalación es bien simple.

    Luego de instalado tendremos la posibilidad de abrir archivos de Office 2007 (.docx, .pptx, .xlsx, etc.), editarlos y guardarlos como si fueran versiones antiguas. Para crear archivos de Office 2007 tendremos la opción de guardarlos con el formato deseado en la lista de formatos de “Guardar como tipo“:

    Referencias:

    Posts relacionados:

    1. Pantalla widescreen (16:10) en Powerpoint
    2. 64GB de RAM en un sistema operativo de 32 bits

    ]]>
    http://josearrarte.com/blog/2010/08/08/editar-archivos-de-office-2007-en-versiones-anteriores-de-office//feed 0
    Array de bytes y la clase java.nio.ByteBuffer http://josearrarte.com/blog/2010/07/29/array-de-bytes-y-la-clase-java-nio-bytebuffer/ http://josearrarte.com/blog/2010/07/29/array-de-bytes-y-la-clase-java-nio-bytebuffer/#comments Fri, 30 Jul 2010 00:00:58 +0000 jarrarte http://josearrarte.com/blog/?p=439
  • Crear un nuevo proyecto Java con Maven
  • Seleccionar y matar un proceso java determinado
  • ]]>
    Un buffer es una secuencia finita de elementos -en este caso, tipos primitivos-. La clase abstracta java.nio.Buffer y sus respectivas subclases concretas (java.nio.ByteBuffer, java.nio.IntBuffer, java.nio.FloatBuffer, etc.) sirven como contenedores para datos de tipos primitivos. Estos buffers forman parte de la API NIO junto a las classes Channel, Selector, entre otras.

    Estas clases, en particular java.nio.ByteBuffer, son de especial utilidad en aplicaciones en las cuales tenemos que generar array de bytes y que no justifica usar frameworks demasiado refinados para dicha tarea.

    Un java.nio.Buffer tiene algunas propiedades escenciales:

    • Capacidad: la cantidad de elementos máxima del buffer. Siempre tiene un valor positivo, y no cambia durante la vida del objeto. Debe ser conocido al momento de inicializar el buffer.
    • Límite: según la documentación de java.nio.Buffer, el límite es “el índice del primer elemento que no debería ser leído ni escrito”. Es un valor entre la posición y la capacidad del buffer. La idea es utilizarlo como marcador para que, luego de terminada la escritura hacia el buffer, sepamos hasta donde lo podemos leer para obtener el array generado.
    • Posición: la posición actual dentro del bufffer. Es el índice del próximo elemento a leer o escribir.

    Funcionalidades básicas

    Todas estas funcionalidades están muy detalladas en los javadocs de las clases, pero es interesante repasar las más útiles:

    • Operaciones de escritura: la API provee las distintas variantes de operaciones put, permitiendo agregar bytes y tipos más grandes como ser int, long, float, arrays de bytes o incluso el contenido de otro ByteBuffer. Para los tipos de datos que ocupen más de un byte, se considerará la codificación (endianness) seteado utilizando el método order(). Tenemos métodos put para agregar bytes en posiciones relativas (en la posición actual) o absolutas (en una posición determinada)
    • Operaciones de lectura: al igual que con las operaciones put, las operaciones get permiten recuperar datos del buffer. Tenemos operaciones para recuperar diferentes tipos de datos (siempre teniendo en cuenta la codificación -endianness- cuando los tipos de datos son multi-byte), para recuperarlos desde la posición actual o desde una posición determinada. También podemos cargar un array de bytes con una sección del buffer.
    • clear(): prepara el buffer para una nueva secuencia de operaciones de escritura, seteando el límite con igual valor que la capacidad, y la posición actual en cero.
    • flip(): prepara el buffer para una secuencia de lecturas, seteando el límite igual a la posición actual, y la posición a cero. Más allá de la capacidad máxima del buffer, permite hacer operaciones sobre la porción que utilizamos anteriormente.
    • rewind(): prepara el buffer para una relectura de la información que contiene, seteando la posición en cero sin cambiar el valor del límite.
    • mark() / reset(): mark() setea la marca del buffer en la posición actual. al invocar reset(), cambiamos de posición en el buffer a la última invocación de mark().
    • slice(): crea un nuevo ByteBuffer a partir de la posición actual y hasta el fin del array. Los buffers comparten el array subyacente, por lo que un cambio en los datos se verá reflejado en ambos.
    • array(): retorna el buffer en forma de array.
    • Chaining (encadenamiento) de invocaciones: los métodos que no deben retornar valores al invocarlos, retornan una referencia a sí mismo, de manera de poder encadenar invocaciones al buffer. El encadenamiento no aporta nuevas funcionalidades, simplemente mejora la usabilidad.

    Ejemplo de uso

    Imaginemos que necesitamos generar un array de bytes para enviar a un sistema externo, que contiene la siguiente información:

    Campo Tipo de dato Largo Formato
    Largo del mensaje short 2 bytes Little Endian
    Id long 8 bytes Big Endian
    Largo del nombre short 2 bytes Little Endian
    Nombre String Máximo 30 caracteres -
    Edad byte 1 byte -
    Salario int 4 bytes Big Endian

    Debemos codificar el largo total del mensaje y el largo del nombre como little-endian (es decir, el byte menos significativo va en la primer posición, y el byte más significativo va en la última) en lugar de big-endian -a veces también llamado network order, por ser la codificación definida en el protocolo IP-.

    Aprovecharemos las funcionalidades de la clase ByteBuffer para resolver este problema. En particular, ByteBuffer nos permite setear la representación de los enteros de varios bytes en el array, utilizando el método order(ByteOrder bo). Una solución que resuelve la generación del array podría ser la siguiente:

    package com.josearrarte.demo;
    
    import java.nio.ByteBuffer;
    import java.nio.ByteOrder;
    
    public class ByteBufferDemo {
    
    	private static final int SIZEOF_BYTE = 1;
    	private static final int SIZEOF_SHORT = 2;
    	private static final int SIZEOF_INT = 4;
    	private static final int SIZEOF_LONG = 8;
    
    	public static void main(String[] args) {
    
    		byte[] byteArray = buildByteArray(12345678L, "Pedro Picapiedra", (byte)46, 25000);
    
    		String hexString = getHexString(byteArray);
    		System.out.println(hexString);
    	}
    
    	private static byte[] buildByteArray(long id, String name, byte age, int salary) {
    
    		int capacity = 2 * SIZEOF_SHORT +	// largos
    			SIZEOF_LONG + 					// id
    			name.length() + 				// nombre
    			SIZEOF_BYTE + 					// edad
    			SIZEOF_INT;						// salario
    
    		ByteBuffer buffer = ByteBuffer.allocate(capacity);
    
    		// largo de datos
    		buffer.order(ByteOrder.LITTLE_ENDIAN);
    		buffer.putShort((short)capacity);
    
    		// id
    		buffer.order(ByteOrder.BIG_ENDIAN);
    		buffer.putLong(id);
    
    		// largo del campo nombre
    		buffer.order(ByteOrder.LITTLE_ENDIAN).putShort((short)name.length());
    
    		// nombre
    		buffer.order(ByteOrder.BIG_ENDIAN).put(name.getBytes());
    
    		// edad
    		buffer.put(age).putInt(salary);
    
    		return buffer.array();
    
    	}
    
    	private static String getHexString(byte[] array) {
    		final char[] chars = { '0', '1', '2', '3', '4',
    				'5', '6', '7', '8', '9',
    				'A', 'B', 'C', 'D', 'E', 'F' };
    
    		StringBuilder strBuilder = new StringBuilder();
    
    		for (int i = 0; i < array.length; i++) {
    			byte b = array[i];
    
    			byte lowNibble = (byte) (b & 0x0F);
    			byte highNibble = (byte) ((b & 0xF0) >>> 4);
    
    			strBuilder.append(chars[highNibble]);
    			strBuilder.append(chars[lowNibble]);
    			strBuilder.append(' ');
    		}
    
    		return strBuilder.toString();
    	}
    }
    

    La salida del programa es:

    21 00 00 00 00 00 00 BC 61 4E 10 00 50 65 64 72 6F 20 50 69 63 61 70 69 65 64 72 61 2E 00 00 61 A8
    

    Podemos desglosar la salida para cada dato:

    • Largo de datos: 21 00 (33)
    • Id: 00 00 00 00 00 BC 61 4E (12345678)
    • Largo del campo de nombre: 10 00 (16)
    • Nombre: 50 65 64 72 6F 20 50 69 63 61 70 69 65 64 72 61 (“Pedro Picapiedra”)
    • Edad: 2E (46)
    • Salario: 00 00 61 A8 (25000)

    Notemos la facilidad ByteBuffer que nos da a la hora de tener que intercambiar los formatos de enteros y de mezclar distintos tipos primitivos en un mismo array. No tuvimos necesidad de ir calculando las posiciones dentro del array, ni calcular la representación de enteros en formato little-endian o big-endian.

    Referencias

    API de java.nio.ByteBuffer
    API de java.nio.Buffer
    http://en.wikipedia.org/wiki/Endianness
    http://en.wikipedia.org/wiki/New_I/O

    Posts relacionados:

    1. Crear un nuevo proyecto Java con Maven
    2. Seleccionar y matar un proceso java determinado

    ]]>
    http://josearrarte.com/blog/2010/07/29/array-de-bytes-y-la-clase-java-nio-bytebuffer//feed 1
    Descargar archivos de sitios de file-sharing por consola en Linux http://josearrarte.com/blog/2010/07/26/descargar-archivos-de-sitios-de-file-sharing-por-consola-en-linux/ http://josearrarte.com/blog/2010/07/26/descargar-archivos-de-sitios-de-file-sharing-por-consola-en-linux/#comments Tue, 27 Jul 2010 00:00:43 +0000 jarrarte http://josearrarte.com/blog/?p=446
  • Copiar archivos utilizando SCP en Linux
  • Copiar archivo y particiones utilizando dd (Linux/UNIX)
  • Monitoreo en Linux: nmon
  • ]]>
    Quienes hemos utilizado el excepcional JDownloader sabemos la facilidad que nos proporciona a la hora de descargar una lista de archivos que son secciones de un archivo comprimido. Tengo una PC bastante antigüa (Pentium III con 256MB de RAM) que utilizo como servidor de descargas con MLDonkey sobre Gentoo Linux, pero me hacía falta encontrar un sustituto para el JDownloader que no necesitara un ambiente gráfico para correr.

    PlowShare es un conjunto de scripts para el sistema operativo Linux con el fin de permitir administrar las descargas y subidas en sitios de file-sharing, del estilo de RapidShare, MegaUpload, HotFile, etc. Automatiza el reconocimiento de caracteres -CAPTCHA- y los tiempos de espera para comenzar la descarga. Además, es una aplicación de consola con requerimientos de recursos excepcionalmente bajos.

    Los scripts son plowdown.sh, plowup.sh, plowdel.sh y plowlist.sh. Seguramente el más utilizado por el común de la gente sea plowdown, y éstas son sus opciones:

    server ~ # plowdown
    Usage: plowdown [OPTIONS] [MODULE_OPTIONS] URL|FILE [URL|FILE ...]
    
      Download files from file sharing servers.
    
      Available modules: rapidshare megaupload 2shared badongo mediafire 4shared zshare depositfiles storage_to uploaded_to uploading netload_in usershare sendspace x7_to hotfile divshare dl_free_fr humyo filefactory data_hu
    
    Global options:
    
      -h, --help: Show help info
      --version: Return plowdown version
      -v LEVEL, --verbose=LEVEL: Set output verbose level: 0=none, 1=err, 2=notice (default), 3=dbg
      -q, --quiet: Alias for -v0
      -c, --check-link: Check if a link exists and return
      -m, --mark-downloaded: Mark downloaded links in (regular) FILE arguments
      -x, --no-overwrite: Do not overwrite existing files
      --get-module: Get module(s) for URL(s)
      -o DIRECTORY, --output-directory=DIRECTORY: Directory where files will be saved
      --temp-directory=DIRECTORY: Directory where files are temporarily downloaded
      -r SPEED, --limit-rate=SPEED: Limit speed to bytes/sec (suffixes: k=Kb, m=Mb, g=Gb)
      -i IFACE, --interface=IFACE: Force IFACE interface
      -t SECS, --timeout=SECS: Timeout after SECS seconds of waits
      --max-retries=N: Set maximum retries for loops
      --run-download=COMMAND: run down command (interpolations: %filename, %cookies, %url)
    
    Options for module <rapidshare>:
    
      -a USER:PASSWORD, --auth=USER:PASSWORD: Use Premium-Zone account
    
    Options for module <megaupload>:
    
      -a USER:PASSWORD, --auth=USER:PASSWORD: Free-membership or Premium account
      -p PASSWORD, --link-password=PASSWORD: Used in password-protected files
    
    Options for module <x7_to>:
    
      -b USER:PASSWORD, --auth-free=USER:PASSWORD: Use Free account
    

    Al script lo podemos invocar con la URL de un archivo a descargar, una lista de URLs de archivos a descargar o inclusive con la ruta a un archivo de texto que contiene la lista de links (uno por línea). En los últimos dos casos el script descargará los archivos en orden, siendo posible configurar que marque con el símbolo ‘#’ al principio de la línea del archivo cada archivo descargado correctamente (ver –mark-downloaded más abajo).

    Algunas de las opciones importantes son:

    • -o (–output-directory): determina el directorio de salida. Es el lugar en donde se ubicarán el o los archvos descargados.
    • -r (–limit-rate): configura la velocidad de transferencia máxima, por ejemplo, -r=50kb, –limit-rate=1m.
    • -c (–check-link): no descarga el o los archivos, sólo verifica que los links sean válidos.
    • -m (–mark-downloaded): cuando se desea descargar todos los links listados en un archivo de texto, marca los archivos descargados correctamente con un ‘#’ al principio de la línea.

    Veamos un ejemplo de invocación para descargar un archivo desde MegaUpload:

    server ~ # plowdown -v 2 -o /tmp http://www.megaupload.com/?d=977IJRE0
    Install aview or libcaca to display captcha image
    Waiting 47 seconds... 37.. 27.. 17.. 7.. 0
    File URL: http://www937.megaupload.com/files/927a093e5f4d388420ef7ecfcecd73c0/Weeds 5x01 - Seba357.rar
    Filename: Weeds 5x01 - Seba357.rar
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
     51  233M   51  120M    0     0   209k      0  0:18:57  0:09:47  0:09:10  212k
    

    En http://code.google.com/p/plowshare/wiki/Readme tenemos otros ejemplos de uso para descargar, subir, borrar y comprobar links en sitios de file-sharing.

    El proyecto PlowShare está hosteado en Google Code. La página del proyecto es http://code.google.com/p/plowshare/.

    Gentoo Linux tiene el paquete disponible en portage bajo el nombre net-misc/plowshare. Archlinux y (e incluso Mac OSX) también tiene paquete de instalación, para el resto de los sabores de Linux tenemos la posibilidad de instalarlo desde el código fuente.

    Posts relacionados:

    1. Copiar archivos utilizando SCP en Linux
    2. Copiar archivo y particiones utilizando dd (Linux/UNIX)
    3. Monitoreo en Linux: nmon

    ]]>
    http://josearrarte.com/blog/2010/07/26/descargar-archivos-de-sitios-de-file-sharing-por-consola-en-linux//feed 1
    Orgullo Celeste http://josearrarte.com/blog/2010/07/10/orgullo-celeste/ http://josearrarte.com/blog/2010/07/10/orgullo-celeste/#comments Sun, 11 Jul 2010 01:28:46 +0000 jarrarte http://josearrarte.com/blog/?p=426

    Fuente: sitio de FIFA

    Hoy Uruguay cerró su gran actuación en el mundial de fútbol en Sudáfrica, con un cuarto puesto luego de perder contra la selección alemana.

    Sin ánimo de subirme al tren exitista luego de la gran actuación de la Celeste, deseo hacer público este sentimiento de orgullo por la entrega, por la pasión demostrada, por la unión del grupo, por la humildad y la nobleza de las declaraciones ante la prensa, tanto luego de ganar como luego de perder. También tengo un sentimiendo de que este logro no fue por suerte o de regalo; el sentimiento de que luego de ver al plantel luchar hasta el último minuto -literalmente-, un lugar mejor era también bien merecido.

    Sin dudas el temple y las ganas esta selección es un ejemplo a seguir, ese sentimiendo de que ya no es regla que el más chico no puede llegar a cosas grandes, de que por ser uruguayos no podemos estar entre los mejores del mundo y destacarnos en algo. Es responsabilidad de nosotros dejarnos contagiarnos por esta actitud, y tomar este mundial como ejemplo para animarnos a llegar a más.

    Salud Celeste, ojalá que todas estas alegrías sean sólo el comienzo de una nueva etapa de nuestra historia en el fútbol mundial.

    (No existen posts relacionados)

    ]]>
    http://josearrarte.com/blog/2010/07/10/orgullo-celeste//feed 2
    UnxUtils: ejecutar comandos Linux/UNIX en Windows http://josearrarte.com/blog/2010/05/13/unxutils-ejecutar-comandos-linuxunix-en-windows/ http://josearrarte.com/blog/2010/05/13/unxutils-ejecutar-comandos-linuxunix-en-windows/#comments Thu, 13 May 2010 21:50:48 +0000 jarrarte http://josearrarte.com/blog/?p=285
  • Ejecutar aplicaciones gráficas de X11 (Linux y Unix) en Windows
  • Copiar archivo y particiones utilizando dd (Linux/UNIX)
  • Copiar archivos utilizando SCP en Linux
  • 64GB de RAM en un sistema operativo de 32 bits
  • Hotkeys del símbolo de sistema de Windows
  • Matar procesos en Windows (taskkill)
  • Listado de comandos de administración de Informix
  • Descargar archivos de sitios de file-sharing por consola en Linux
  • Monitoreo en Linux: nmon
  • ]]>
    UnxUtils es un port para Windows de varias utilidades GNU. Para la gente que está acostumbrada a utilizar sistemas UNIX o Linux, estas utilidades se extrañan bastante en sistemas Windows, especialmente cuando tenemos que crear scripts. Incluye ls, grep, diff, wget, md5sum, tail, head, less, sed, entre otras. Podemos ver la lista entera de comandos en la siguiente imagen:

    Para instalarlo, debemos bajar la herramienta desde la página del proyecto en SourceForge.net. Descomprimimos el archivo en el directorio que más nos guste (yo lo tengo en C:\UnxUtils) y agregamos el directorio [dir]\usr\local\wbin a la variable de entorno path, donde [dir] es el directorio elegido para descomprimir el archivo (en mi caso, agregué C:\UnxUtils\usr\local\wbin)

    Otra forma, no tan rápida o directa de contar con este tipo de utilidades bajo Windows, pero más completa es instalar Cygwin. Para ello debemos bajar el instalador desde su página, y luego seguir las instrucciones de su guía para el usuario.

    Posts relacionados:

    1. Ejecutar aplicaciones gráficas de X11 (Linux y Unix) en Windows
    2. Copiar archivo y particiones utilizando dd (Linux/UNIX)
    3. Copiar archivos utilizando SCP en Linux
    4. 64GB de RAM en un sistema operativo de 32 bits
    5. Hotkeys del símbolo de sistema de Windows
    6. Matar procesos en Windows (taskkill)
    7. Listado de comandos de administración de Informix
    8. Descargar archivos de sitios de file-sharing por consola en Linux
    9. Monitoreo en Linux: nmon

    ]]>
    http://josearrarte.com/blog/2010/05/13/unxutils-ejecutar-comandos-linuxunix-en-windows//feed 1
    Cambiar la JVM utilizada por Eclipse http://josearrarte.com/blog/2010/05/13/cambiar-la-jvm-utilizada-por-eclipse/ http://josearrarte.com/blog/2010/05/13/cambiar-la-jvm-utilizada-por-eclipse/#comments Thu, 13 May 2010 21:48:52 +0000 jarrarte http://josearrarte.com/blog/?p=397
  • m2eclipse: un plugin de Eclipse para proyectos de Maven
  • Problemas en Eclipse de proyectos Maven con dependencias a AspectJ
  • Evitar la ejecución de tests o ignorar resultados al utilizar Maven
  • Generación del manifest de un JAR utilizando Maven
  • Crear un nuevo proyecto Java con Maven
  • ]]>
    En algunos casos es necesario iniciar el IDE Eclipse utilizando una JDK en lugar de la JRE por defecto. Un caso es, por ejemplo, para poder utilizar todas las funcionalidades del plugin m2eclipse. Veremos cómo cambiar la configuración para usar otra máquina virtual.

    Para ello, debemos editar el archivo eclipse.ini que está en el directorio de instalación de Eclipse (bah, en el directorio en donde lo descomprimimos), y agregar el parámetro -vm indicando el ejecutable de la JDK que usará el IDE. Hay algunas cosas a tener en cuenta:

    1. El parámetro -vm debe ir solo en una línea, con su valor en la línea siguiente.
    2. El valor del parámetro -vm es la ruta hasta el ejecutable (por ejemplo javaw.exe), no es la ruta del directorio que lo contiene.
    3. Es importante la ubicación del parámetro -vm. Debe estar ubicado antes del parámetro -vmargs. Todos los parámetros luego de -vmargs serán pasados directamente a la JVM

    Yo tengo una JDK en Windows instalada en el directorio D:\Java\jdk1.6.0_17, y éste es mi eclipse.ini:

    -startup
    plugins/org.eclipse.equinox.launcher_1.0.201.R35x_v20090715.jar
    --launcher.library
    plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.0.200.v20090519
    -product
    org.eclipse.epp.package.jee.product
    --launcher.XXMaxPermSize
    256M
    -showsplash
    org.eclipse.platform
    --launcher.XXMaxPermSize
    256m
    -vm
    D:/Java/jdk1.6.0_17/bin/javaw.exe
    -vmargs
    -Dosgi.requiredJavaVersion=1.5
    -Xms40m
    -Xmx512m
    

    Como último punto a destacar, quisiera comentar que toda esta configuración se puede verificar en About Eclipse, en el menú de Help.

    http://wiki.eclipse.org/Eclipse.ini
    http://tech.karolzielinski.com/m2eclipse-eclipse-is-running-in-a-jre-but-a-jdk-is-required

    Posts relacionados:

    1. m2eclipse: un plugin de Eclipse para proyectos de Maven
    2. Problemas en Eclipse de proyectos Maven con dependencias a AspectJ
    3. Evitar la ejecución de tests o ignorar resultados al utilizar Maven
    4. Generación del manifest de un JAR utilizando Maven
    5. Crear un nuevo proyecto Java con Maven

    ]]>
    http://josearrarte.com/blog/2010/05/13/cambiar-la-jvm-utilizada-por-eclipse//feed 0
    Generación del manifest de un JAR utilizando Maven http://josearrarte.com/blog/2010/04/30/generacion-del-manifest-de-un-jar-utilizando-maven/ http://josearrarte.com/blog/2010/04/30/generacion-del-manifest-de-un-jar-utilizando-maven/#comments Fri, 30 Apr 2010 20:43:50 +0000 jarrarte http://josearrarte.com/blog/?p=250
  • Crear un nuevo proyecto Java con Maven
  • Evitar la ejecución de tests o ignorar resultados al utilizar Maven
  • “Unmappable character for encoding UTF-8″ al compilar proyectos Java con Maven
  • Problemas en Eclipse de proyectos Maven con dependencias a AspectJ
  • m2eclipse: un plugin de Eclipse para proyectos de Maven
  • Catálogos web de artefactos de Maven
  • Cambiar la JVM utilizada por Eclipse
  • Audio y video en Java utilizando ffmpeg, Jffmpeg, y JMF
  • ]]>
    Al empaquetar un artefacto Java, puede interesarnos agregar información al manifest generado. El manifest es un archivo que se crea dentro de nuestro JAR (en la ruta META-INF/MANIFEST.MF) con información bastante diversa acerca del JAR, en forma de "propiedad: valor". Esta información puede ser acerca de la versión de código empaquetada, del classpath, de la clase que se ejecutará al correr java -jar [archivo.jar] o inclusive propiedades personalizadas que tienen significado para el usuario de ese JAR.

    Utilizando Maven podemos generar automáticamente el archivo MANIFEST.MF. Para ello, debemos editar el archivo pom.xml agregando la configuración del manifest al plugin que se encarga de empaquetar nuestro proyecto (maven-jar-plugin). Veamos un ejemplo:

    <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>
    	<groupId>com.josearrarte</groupId>
    	<artifactId>tests</artifactId>
    	<version>0.0.1-SNAPSHOT</version>
    	<url>http://www.josearrarte.com/blog</url>
    
    	<dependencies>
    		<dependency>
    			<groupId>commons-dbcp</groupId>
    			<artifactId>commons-dbcp</artifactId>
    			<version>1.4</version>
    		</dependency>
    	</dependencies>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<configuration>
    					<source>1.6</source>
    					<target>1.6</target>
    				</configuration>
    			</plugin>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-jar-plugin</artifactId>
    				<executions>
    					<execution>
    						<phase>package</phase>
    						<goals>
    							<goal>jar</goal>
    						</goals>
    					</execution>
    				</executions>
    				<configuration>
    					<archive>
    						<manifest>
    							<classpathPrefix>lib</classpathPrefix>
    							<addClasspath>true</addClasspath>
    							<mainClass>com.josearrarte.demo.MainClass</mainClass>
    						</manifest>
    						<manifestEntries>
    			              <sample_entry>sample_value</sample_entry>
    			              <url>${project.url}</url>
    			            </manifestEntries>
    					</archive>
    				</configuration>
    			</plugin>
    		</plugins>
    	</build>
    </project>
    

    Lo más importante del ejemplo está en la parte de configuración del maven-jar-plugin. Ahí tenemos tres elementos configurados:

    • mainClass: Se utiliza para determinar qué clase contiene el método main del JAR cuando ejecutamos la JVM con el parámetro -jar [archivo.jar]
    • addClasspath: los valores posibles son true o false. Si el valor es true se agregará una entrada Class-Path al manifest, con la lista de JARs de los cuales depende nuestro artefacto (algunos scopes no serán considerados, por ejemplo test)
    • classpathPrefix: este elemento de configuración es útil cuando queremos referenciar los JARs de los que depende nuestro artefacto y están en un directorio diferente. Se pueden utilizar paths relativos

    Los elementos dentro de sirven para agregar propiedades adicionales al manifest. Se pueden utilizar variables del estilo de ${project.build.finalName} que serán sustituidas sus valores reales. No conozco todas las variables existentes, pero aquí hay una lista que parece bastante completa.

    El archivo META-INF/MANIFEST.MF resultante de empaquetar el proyecto será muy similar al siguiente:

    Manifest-Version: 1.0
    Archiver-Version: Plexus Archiver
    Created-By: Apache Maven
    Built-By: jarrarte
    Build-Jdk: 1.6.0_19
    Main-Class: com.josearrarte.demo.MainClass
    sample_entry: sample_value
    url: http://www.josearrarte.com/blog
    Class-Path: lib/commons-dbcp-1.4.jar lib/commons-pool-1.5.4.jar
    

    En el pom.xml del proyecto de ejemplo tenemos una dependencia a commons-dbcp, que a su vez depende de commons-pool. Esto se ve reflejado al construir el valor classpath en el manifest, que contiene las dos dependencias.

    Referencias

    http://tutorialexception.blogspot.com/2009/03/configurar-el-manifest-con-maven-para.html
    http://maven.apache.org/
    http://maven.apache.org/shared/maven-archiver/examples/classpath.html
    http://maven.apache.org/guides/mini/guide-manifest.html
    http://docs.codehaus.org/display/MAVENUSER/MavenPropertiesGuide
    http://java.sun.com/docs/books/tutorial/deployment/jar/modman.html

    Posts relacionados:

    1. Crear un nuevo proyecto Java con Maven
    2. Evitar la ejecución de tests o ignorar resultados al utilizar Maven
    3. “Unmappable character for encoding UTF-8″ al compilar proyectos Java con Maven
    4. Problemas en Eclipse de proyectos Maven con dependencias a AspectJ
    5. m2eclipse: un plugin de Eclipse para proyectos de Maven
    6. Catálogos web de artefactos de Maven
    7. Cambiar la JVM utilizada por Eclipse
    8. Audio y video en Java utilizando ffmpeg, Jffmpeg, y JMF

    ]]>
    http://josearrarte.com/blog/2010/04/30/generacion-del-manifest-de-un-jar-utilizando-maven//feed 3
    Tests de performance y de stress http://josearrarte.com/blog/2010/04/28/tests-de-performance-y-de-stress/ http://josearrarte.com/blog/2010/04/28/tests-de-performance-y-de-stress/#comments Wed, 28 Apr 2010 20:18:10 +0000 jarrarte http://josearrarte.com/blog/?p=353
  • Tests parametrizados con TestNG
  • Tests parametrizados con JUnit 4
  • Evitar la ejecución de tests o ignorar resultados al utilizar Maven
  • ]]>
    Introducción

    Los tests de performance son aquellos que sirven para determinar qué tan rápido o qué tan bien se comporta un sistema sometido a una carga en particular. También pueden ser utilizados para validar y verificar otros requerimientos no funcionales del sistema como ser estabilidad, escalabilidad, disponibilidad o consumo de recursos.

    Los tests de performance pueden buscar diferentes objetivos. Pueden servir para demostrar que un sistema cumple con determinado criterio de aceptación, para comparar dos sistemas y determinar cuál se comporta mejor o bien para detectar qué sistema externo o qué componente interno es el cuello de botella. Para el último caso, los tests de performance se pueden utilizar junto a profilers para medir y determinar cómo se distribuye el uso de recursos (tiempo, CPU, I/O, memoria, etc.) entre los diferentes componentes del sistema.

    Los tests de stress, en cambio, son tests diseñados para verificar el comportamiento de un sistema al introducir caos o incertidumbre, y el objetivo es comprobar la robustez del software cuando es sometido a condiciones diferentes a la de operación normal. Estos tests son particularmente importantes para software considerado crítico, y hacen énfasis en características como robustez, disponibilidad o manejo controlado de errores y situaciones de excepción.

    Al igual que con los tests unitarios o de integración, la noción de “testear temprano y testear seguido” también aplica para los tests de performance y de stress. Es importante considerar al principio de un proyecto si se van a requerir tests de performance y/o stress (por ejemplo para cumplir requerimientos no funcionales) o qué componentes van a participar de estos tests. De forma análoga a la detección de bugs, la detección de problemas de performance se va complicando a medida que vamos avanzando en las etapas del proyecto, y nuestro sistema está más cerca del producto final. Si bien encontrar problemas de performance en una prueba de concepto o prototipo puede llegar a determinar un cambio de arquitectura o de tecnología y consumir varias horas de retrabajo, el detectar este mismo problema luego de puesto en producción puede llegar a ser un problema de varios órdenes de magnitud peor. Sin embargo, no es tan fácil poder contar con un ambiente, con los sistemas externos -o procesos que los simulen- y con los datos necesarios, pero es importante establecer si va a ser posible y en qué momento se realizarán.

    Este post estará mayormente centrado en los tests de performance, pero varios de los puntos destacados aplican también a la hora de planificar los tests de stress.

    Objetivos

    Como comentábamos en la introducción, los tests de performance pueden perseguir diferentes objetivos. Es importante delinear estos objetivos al diseñar los tests, así como también los parámetros fijos y variables con los que se ejecutarán. Por ejemplo, si imaginamos que queremos determinar la capacidad máxima de respuestas por segundo de un web service, no es lo mismo realizar las pruebas con 3 clientes concurrentes que con 3000 clientes concurrentes. Se debe conocer de antemano a la realización de los tests en qué aspectos debemos enfocarnos, y con qué parámetros analizaremos esos aspectos.

    Algunos objetivos posibles a perseguir pueden ser:

    Cumplir con requerimientos no funcionales

    Además de la definición de requerimientos funcionales (por ejemplo en forma de casos de uso), un sistema se pueden definir también con requerimientos que son ortogonales a los funcionales. Ejemplos típicos de estos requerimientos no funcionales pueden ser seguridad, escalabilidad, volumen de datos a manejar o niveles mínimos aceptables de performance.

    El cumplimiento o no de algunos requerimientos no funcionales se puede determinar en función del resultado de tests de performance, si se diseñan para comprobar que el sistema cumple con los criterios establecidos.

    Conocer nuestro sistema

    Un test de performance puede ser utilizado para conocer cuánto podemos esperar de nuestro sistema para un aspecto determinado. Volviendo al caso del web service, si bien puede que no haya requerimientos no funcionales acerca de la cantidad máxima de requests por segundo, puede llegar a interesarnos el conocer su límite, para tenerlo en cuenta luego en un monitoreo en producción. Por supuesto, que este tipo de test de performance debe ser realizado en un ambiente (hardware, software, datos) lo más parecido posible al real.

    También puede ser interesante determinar cuál es el aspecto limitante, y que este conocimiento nos ayude en un futuro dimensionamiento de sistemas similares.

    Profiling

    Si pensamos en hacer tests de performance utilizando además herramientas de profiling, podremos pensar en encontrar cuellos de botella de nuestro sistema. Una sesión de profiling puede ser tan simple como registrar estadísticas en un log y analizarlas a mano o tan complejas como el uso de herramientas especialmente construidas para este fin. Un ejemplo de dichas herramientas para el caso del lenguaje Java puede ser el excelente JProfiler, que permite monitorear el tiempo usado por cada método, clase, paquete e inclusive invocaciones JDBC o JMS. También permite monitorear el uso de memoria en los diferentes heaps, garbage collection o cantidad de instancias por clase.

    Para el uso de herramientas de profiling generalmente es necesario generar en el sistema una carga de trabajo que simule su uso en la vida real. Acá es donde los tests de performance entran en juego, combinándose una herramienta que sepa generar la carga, y otro que sepa analizar el funcionamiento de nuestro sistema.

    Cabe destacar que la performance de nuestro sistema es muy inferior cuando la herramienta de profiling la monitorea, pero los recursos consumidos deberían ser proporcionales a los reales.

    Comparación entre sistemas

    Los tests de performance y de stress pueden servir para conocer y optimizar nuestro sistema, pero también pueden servir para comparar dos o más sistemas similares, y determinar cuál de ellos es superior en algún aspecto que nos interese comparar.

    Un ejemplo de esto puede ser la comparación entre dos implementaciones de una misma funcionalidad. Otro posible podría ser la medición de performance de dos motores de base de datos diferentes. Es más, podemos querer determinar cómo se comporta un mismo sistema en distintos ambientes, haciendo cambios en el hardware o en el software de base (por ejemplo sistema operativo) y descubrir cómo impactan estos cambios en la performance de nuestro sistema.

    Objetos

    La lista de objetos o sistemas a los que podemos realizarles tests de performance y de stress es demasiado amplia para detallarla en su totalidad. A modo de ejemplo, algunos de los sistemas objeto de los tests pueden ser:

    • Bases de datos, stored procedures, consultas SQL
    • Web services
    • Sitios y servidores web
    • Servidores FTP
    • Colas de mensajes (MQs)
    • Sistemas que interactúan directamente utilizando mediante conexiones TCP/IP

    Tipos de tests de stress

    Como comentamos al principio, los tests de stress o de performance pueden apuntar a aspectos bien diferentes de un sistema. Repasemos cuáles de estos aspectos nos pueden interesar.

    Concurrencia

    En sistemas de tipo servidor, siempre es importante comprobar que para un sistema es posible procesar correctamente la carga de invocaciones de sus clientes. En general, esta carga es medida en función de la cantidad de pedidos que es capaz de contestar por unidad de tiempo (medida en TPS – transacciones por segundo) y en función de la cantidad de clientes concurrentes que le realizan esos pedidos. En la gran mayoría de los casos estas dos variables no son independientes.

    Tiempo de respuesta

    De la mano de las TPS para una determinada cantidad de clientes viene el tiempo requerido para procesar cada invocación. Generalmente este tiempo de respuesta crece cuando se crece la cantidad de clientes o la cantidad de TPS generadas por cada cliente. La rapidez con la que crece el tiempo de respuesta determinará -de forma inversamente proporcional- la escalabilidad de nuestro sistema.

    Generalmente es uno de los requerimientos no funcionales de sistemas cliente-servidor o servidor, e impacta directamente en la agilidad percibida por el usuario final. Es necesario definir y verificar los requerimientos mínimos determinando de antemano el ambiente y un perfil de uso.

    De resistencia (endurance testing)

    Los tests de resistencia generalmente se realizan para determinar o comprobar que un sistema puede funcionar cierto tiempo con la carga esperada. En estos tests pueden surgir problemas de degradación de performance o resource leaks (memoria RAM, handles de archivos, conexiones abiertas, etc.). También –especialmente en sistemas con alta concurrencia– pueden ser útiles para detectar deadlocks, situaciones de por si bastante complicadas de diagnosticar y solucionar.

    Límite del sistema (break point)

    El encontrar el límite o break point de un sistema implica exigirlo hasta tal punto que ya no sea capaz de responder como debería. Para simular escenarios de stress extremo podemos optar por exigir al sistema de forma superior para la cual fue diseñado, o también tenemos la opción de destinar menos recursos de los previstos para el sistema: que esté en un servidor con el CPU ya ocupado, configurar el uso de memoria máximo permitido a menos de lo mínimo aconsejable, utilizar dispositivos de almacenamiento lentos, etc.

    Si bien no es esperado que el sistema procese de forma correcta todas las peticiones, con este tipo de tests podemos comprobar que el sistema se comportará de una manera aceptable (sin corromper datos o dejar recursos inutilizables).

    A tener en cuenta

    Existen varias consideraciones que, si no se tienen en cuenta pueden hacer que los tests de performance o de stress no ayuden a diagnosticar problemas, o que nos lleven camino a solucionar problemas que no existen.

    Algunos de estos puntos son:

    • Repetibilidad: generalmente los tests de performance implicarán varios ciclos de correr el test, evaluar los resultados, hace algún cambio, y correr el test nuevamente. Es deseable tener un ambiente en el cual los tests se puedan repetir sin sufrir cambios en los resultados.
    • Se deberá recrear el ambiente de forma lo más similar posible para cada ronda. Se debe tener en cuenta que los arranques en frío (cold startup), caching, estado de los sistemas externos, etc. pueden afectar el resultado de los tests. Por ejemplo, un sistema que utilice una base de datos puede no tener inicializado su pool de conexiones a la base de datos en la primera ejecución del test, y esto hará que el primer ciclo de pruebas difiera en resultados del segundo y posteriores. Deberán ser consideradas técnicas de “calentamiento” del sistema, o correr los tests de cada ciclo partiendo del estado inicial.
    • Como consideración adicional a los puntos anteriores, puede ser deseable construir mocks (simuladores) de los sistemas externos. Esto ayudará a que nuestros tests sean más repetibles, ya que nos liberamos de una dependencia a sistemas que no podemos modificar. Como punto en contra de los mocks, debemos tener claro que pueden no comportarse de manera idéntica a los sistemas originales, distorsionando los tests.
    • Code freeze: es deseable que los diferentes ciclos de tests se ejecuten partiendo del mismo código, y que los cambios realizados sean conocidos. Debemos evitar introducir demasiados cambios entre ciclo y ciclo, para tener claro cómo impactó cada uno de ellos.
    • Si queremos conocer datos de cómo se comportará nuestro sistema en producción, el ambiente en el que corramos los tests debe ser lo más parecido al de producción posible. Esto incluye hardware, sistema operativo, base de datos, otros sistemas, configuración, etc. A veces no es posible acceder a este tipo sistemas, ya sea por su costo o porque directamente porque hay sistemas externos que no podemos utilizar para las pruebas. Si sabemos que podemos tener un cuello de botella distinto al de producción, considerar sistemas mocks para aislarnos del mismo (ver uno de los puntos anteriores).
    • Es deseable que la distribución del juego de datos para los test sea lo más parecida posible a la realidad. Por ejemplo, si sabemos al testear una base de datos que hay un 80% de selects, un 15% de inserts y que el restante 5% son updates, deberíamos distribuir las invocaciones SQL de la misma manera, para que el sistema se comporte de forma semejante a la real.
    • Utilizar un determinado juego de datos puede distorsionar los resultados de los tests. Imaginemos que nuestro sistema expone un web service con un método que recupera empleados de una tabla de una base de datos. Si nuestros tests invocan siempre el método del web service con el mismo identificador de empleado, podría pasar que los datos recuperados queden cacheados y no se esté yendo a la base de datos a recuperarlos. Otro escenario podría ser que se ocasionen bloqueos entre los diferentes pedidos concurrentes. Por ejemplo, si el mismo web service sólo permite una operación concurrente por empleado. En este caso, si todos los clientes del web service envían el mismo id de empleado, la carga no será representativa de la realidad, y los resultados serán mucho peores.

    Herramientas

    JMeter

    JMeter es un projecto open source de Apache Jakarta. Está construido 100% en Java, lo que garantiza su portabilidad entre plataformas. Permite realizar tests de performance a una variedad de tipos de sistemas (desde servlets y páginas web estáticas hasta ejecución de stored procedures de una base de datos). Permite extensiones en la forma de nuevas clases de tests, lo que permite probar prácticamente cualquier tipo de sistema con cualquier juego de datos.

    Brinda además herramientas para hacer análisis gráficos de los resultados, e inclusive posibilidades de controlar una “red de esclavos JMeter” para poder correr tests masivos sin que el cliente sea el cuello de botella.

    JProfiler

    JProfiler es un producto comercial de ej-technologies para hacer profiling de aplicaciones en tiempo real. Puede funcionar stand-alone o integrado a los IDEs más utilizados.

    Su intuitiva interfaz gráfica, la facilidad de uso y su potencial lo hacen una excelente herramienta, digna de probarla por lo menos durante los 10 días de evaluación.

    Scripts manuales

    No es obligatorio contar con herramientas muy complejas para crear tests de stress o de performance. En algunos casos, un buen conjunto de scripts o de programas de test y algunas líneas adicionales de log de nuestra aplicación puede servir para descubrir cuellos de botella o para comprobar el correcto cumplimiento de ciertos requerimientos no funcionales.

    Referencias

    Wikipedia – Software load testing

    MSDN Library patterns and practices – Performance Testing Guidance for Web Applications

    The art of application performance testing (libro)

    Performance vs. load vs. stress testing

    JMeter

    JProfiler

    Posts relacionados:

    1. Tests parametrizados con TestNG
    2. Tests parametrizados con JUnit 4
    3. Evitar la ejecución de tests o ignorar resultados al utilizar Maven

    ]]>
    http://josearrarte.com/blog/2010/04/28/tests-de-performance-y-de-stress//feed 4
    m2eclipse: un plugin de Eclipse para proyectos de Maven http://josearrarte.com/blog/2010/04/17/m2eclipse-un-plugin-de-eclipse-para-proyectos-de-maven/ http://josearrarte.com/blog/2010/04/17/m2eclipse-un-plugin-de-eclipse-para-proyectos-de-maven/#comments Sat, 17 Apr 2010 16:58:12 +0000 jarrarte http://josearrarte.com/blog/?p=361
  • Problemas en Eclipse de proyectos Maven con dependencias a AspectJ
  • Cambiar la JVM utilizada por Eclipse
  • “Unmappable character for encoding UTF-8″ al compilar proyectos Java con Maven
  • Evitar la ejecución de tests o ignorar resultados al utilizar Maven
  • Crear un nuevo proyecto Java con Maven
  • Generación del manifest de un JAR utilizando Maven
  • Catálogos web de artefactos de Maven
  • ]]>
    m2eclipse es un plugin de Eclipse para la integración con Maven. Permite usarlo para manejar, proyectos simples, multi-módulo, ejecutar builds de Maven utilizando la interfaz de Eclipse e interactuar con repositorios de Maven. El plugin ya está bastante maduro, y resulta muy cómodo para trabajar con este tipo de proyectos.

    La instalación es bastante simple. Tenemos que agregar el update site, que es http://m2eclipse.sonatype.org/sites/m2e. Hay una única opción para instalar, llamada “Maven Integration for Eclipse (Required)“. Se instalará el core, el editor de POMs y la integración al repositorio de Maven.

    En el sitio oficial hay links a videos bastante descriptivos acerca del proceso de instalación, creación de proyectos, etc.

    m2eclipse trae un Maven embebido. Si ya tenemos una instalación de Maven configurada y un repositorio local con artefactos descargados podemos aprovecharla, configurando m2eclipse para que haga uso de ella. Para agregar instalaciones de Maven a m2clipse, debemos acceder al menú de preferencias de Eclipse, agregar la instalación seleccionando el directorio en el cual está ubicado y marcarla como la instalación activa:
    Configurar instalaciones de maven

    El plugin cuenta con bastante documentación. Es posible descargar la referencia de m2eclipse en PDF desde éste link (es necesario llenar algunos datos) o leer la documentación on-line aquí. Tiene una FAQ bastante completa, y el blog de m2eclipse es éste.

    La página principal del plug-in es http://m2eclipse.sonatype.org/index.html

    Posts relacionados:

    1. Problemas en Eclipse de proyectos Maven con dependencias a AspectJ
    2. Cambiar la JVM utilizada por Eclipse
    3. “Unmappable character for encoding UTF-8″ al compilar proyectos Java con Maven
    4. Evitar la ejecución de tests o ignorar resultados al utilizar Maven
    5. Crear un nuevo proyecto Java con Maven
    6. Generación del manifest de un JAR utilizando Maven
    7. Catálogos web de artefactos de Maven

    ]]>
    http://josearrarte.com/blog/2010/04/17/m2eclipse-un-plugin-de-eclipse-para-proyectos-de-maven//feed 0
    Tests parametrizados con TestNG http://josearrarte.com/blog/2010/04/15/tests-parametrizados-con-testng/ http://josearrarte.com/blog/2010/04/15/tests-parametrizados-con-testng/#comments Thu, 15 Apr 2010 21:11:16 +0000 jarrarte http://josearrarte.com/blog/?p=371
  • Tests parametrizados con JUnit 4
  • Evitar la ejecución de tests o ignorar resultados al utilizar Maven
  • Tests de performance y de stress
  • Crear un nuevo proyecto Java con Maven
  • ]]>
    En el post anterior vimos cómo podíamos implementar tests parametrizados utilizando JUnit 4. TestNG es un framework similar a JUnit, compartiendo entre ellos casi la totalidad de sus features.

    TestNG propone un enfoque un poco diferente a la implementación de tests parametrizados. Me pareció más flexible y prolija, por lo que creo que vale la pena continuar el post anterior con el ejemplo implementado utilizando este framework.

    En TestNG, los pasos que debemos seguir para implementar un test parametrizado son los siguientes:

    • Escribir un método anotado con @DataProvider(name = “[nombre]“), donde [nombre] es el nombre por el cual se referenciará a este DataProvider en los métodos de test. Si los juegos de datos tienen más de una variable, deberá retornar un array multidimensional. Si es necesario -generalmente lo es-, podría contener además el resultado esperado para cada juego de datos de entrada.
    • Escribir un método anotado con @Test(dataProvider = “[nombre]“), que reciba tantos parámetros como cantidad de datos se tenga en cada item del array que retorna el método anotado con @DataProvider.

    No hay necesidad de aislar los tests parametrizados de los tests que no lo son. Se puede inclusive tener varios DataProviders en una misma clase, asociando métodos de tests diferentes a cada uno.

    Veamos un ejemplo de la case de test utilizando TestNG (el proyecto está disponible para bajar aquí):

    package com.josearrarte;
    
    import static org.junit.Assert.assertEquals;
    
    import org.testng.annotations.DataProvider;
    import org.testng.annotations.Test;
    
    public class ParametrizedTestNGTest {
    
    	@DataProvider(name="test1")
    	public Object[][] createData1() {
    		return new Object[][] {
    				{ DateFormatProvider.OPERATION_TYPE_1, "MMYY" },
    				{ DateFormatProvider.OPERATION_TYPE_2, "YYMM" },
    				{ DateFormatProvider.OPERATION_TYPE_3, "YYYYMM" } };
    	}
    
    	@Test(dataProvider="test1")
    	public void verifyDateFormats(int operationType, String dateFormat)
    		throws Exception {
    		DateFormatProvider provider = new DateFormatProvider();
    
    		String result = provider.getDateFormatFor(operationType);
    		assertEquals(dateFormat, result);
    	}
    
    	@Test(expectedExceptions=IllegalArgumentException.class)
    	public void verifyDateFormats_ShouldThrowIllegalArgumentException()
    		throws Exception {
    		DateFormatProvider provider = new DateFormatProvider();
    
    		provider.getDateFormatFor(-1);
    	}
    }
    

    Como vemos, la idea es exactamente la misma que en JUnit, pero está mejor implementada. Los tests parametrizados se diferencian mejor, y no es necesario tener miembros de la clase y constructores comunes para almacenar los datos.

    Además, el hecho de separar la creación de los tests (instanciación) con la generación de los juegos de datos (data providers) nos permite tener en una misma clase tests con y sin parámetros.

    Posts relacionados:

    1. Tests parametrizados con JUnit 4
    2. Evitar la ejecución de tests o ignorar resultados al utilizar Maven
    3. Tests de performance y de stress
    4. Crear un nuevo proyecto Java con Maven

    ]]>
    http://josearrarte.com/blog/2010/04/15/tests-parametrizados-con-testng//feed 0