Foro Formación Hadoop
Capítulo 5 - Test unitarios
Hola,
tengo una duda con la parte del ejercicio donde hay que desarrollar unos test unitarios en MRunit
Se explica poco más, desconozco si hay que instalar algún programa? ya que se dice que al acabar hay que cerrar la pestaña JUnit...
se comenta que se puede consultar el código de las soluciones, pero sólo veo un .java en la carpeta de workspace, con un código genérico
¿Podríais explicar un poco más en detalle?
Aprovecho para mandar un saludo, es mi primer post aquí, llevo poco tiempo en el curso y aunque tengo muy escaso conocimiento de java me estoy enterando a la perfección
Muchas gracias
Hola Alfonso,
Estás en lo cierto, faltaban las soluciones de este ejercicio. Acabamos de actualizar el fichero workspace-soluciones.zip en los materiales del master con las soluciones.
En las soluciones tienes 3 clases java:
1. Clase Mapper.
2. Clase Reducer.
3. Tests unitarios para las 2 anteriores clases.
Para poder ejecutar los tests unitarios de una manera sencilla recomendamos utilizar Eclipse (para realizarlo de una manera visual), por eso lo de que comentas de "cerrar pestaña".
Si buscas sobre "tests unitarios JUnit en eclipse" es más o menos lo que se realiza con MRUnit, lo único que habría que hacer es añadir al classpath del eclipse la librería correspondiente.
Tal y como se dice en el temario, MRUnit "nace" debido a que únicamente con JUnit no éramos capaces de realizar tests unitarios para mapreduce. Es como una "extensión" de JUnit.
Como habrás podido observar estamos completando cada uno de los temas del master con vídeos explicativos. En breve esperamos poder subir el de ese capítulo y esperamos que con el vídeo te quede más claro.
Cualquier cosa no dudes en preguntarla.
Un saludo,
Hola Fabiola,
gracias por la aclaración, ya he conseguido crear el proyecto para los test e incluido los jar necesarios (hadoop, mrunit (descargado de internet), junit,...) no me da warnings ni errores de imports.
Al ejecutar el proyecto como Junit test y me da errores del tipo:
testMapper:
java.lang.NoClassDefFoundError: Could not initialize class org.apache.hadoop.mrunit.mapreduce.MapDriver
at formacionhadoop.solution.TestWordCount.setUp(TestWordCount.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
testReducer:
java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at org.apache.hadoop.mrunit.TestDriver.<clinit>(TestDriver.java:38)
at formacionhadoop.solution.TestWordCount.setUp(TestWordCount.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 25 more
testMapReducer:
java.lang.NoClassDefFoundError: Could not initialize class org.apache.hadoop.mrunit.mapreduce.MapDriver
at formacionhadoop.solution.TestWordCount.setUp(TestWordCount.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
no encuentro solución
Gracias
Hola Alfonso,
Te siguen faltando librerías. ¿Sabes utilizar Maven? Lo mejor es que te generes un proyecto desde el eclipse con Maven y añadas en el pom:
<dependency>
<groupId>org.apache.mrunit</groupId>
<artifactId>mrunit</artifactId>
<version>1.1.0</version>
</dependency>
Maven es un "gestor" de librerías. Se descargará todas las librerías que dependa de MRunit para poder ejecutar los tests.
En este enlace del foro hay un ejemplo para crear un proyecto maven desde la consola:
http://formacionhadoop.com/aulavirtual/mod/forum/discuss.php?d=67
Si el eclipse viene configurado con el plugin de maven, es más sencillo crear el proyecto a partir del eclipse, en este enlace se explica un poco cómo realizarlo:
http://jarroba.com/maven-en-eclipse/
Si no te aclaras bien, tal y como te comentó Fabiola, esperamos poder colgar en lo que queda de semana el vídeo explicativo de ese capítulo donde pondremos en ejemplo de como crear el proyecto para ejecutar los tests.
Un saludo,
Buenos días,
A continuación os indico un ejemplo del fichero pom.xml que tendría el proyecto para poder ejecutar MRUnit:
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.formacionhadoop.training</groupId>
<artifactId>mrunit</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mrunit</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.6.0-cdh5.10.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.6.0-cdh5.10.0</version>
</dependency>
<dependency>
<groupId>org.apache.mrunit</groupId>
<artifactId>mrunit</artifactId>
<version>1.1.0</version>
<classifier>hadoop2</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Hola,
Tengo el mismo problema que Alfonso en cuanto a las soluciones. En mi caso no estoy haciendo el master sino el curso de desarrollador Hadoop y en el fichero de soluciones solo tengo una AppTest.java por lo que ando bastante desorientado.
Saludos,
Antonio
Buenas tardes Antonio,
Ya hemos actualizado las soluciones con las clases de MRUnit.
Perdona las molestias.
Un saludo,
Buenos dias,
Al intentar probar un Mapper de los ejercicios me ha surgido esta excepción:
He revisado los import y no consigo ver el por qué, mi Mapper extiende de la clase org.apache.hadoop.mapreduce.Mapper y aún así tengo este problema, ¿a qué puede ser debido?.
Saludos,
Antonio Baena
Hola Antonio,
¿Puedes indicarnos la definición de la clase abiMapper?
Gracias.
Un saludo
Buenos días Fernando,
Esta es mi clase que extiende de org.apache.hadoop.mapreduce.Mapper:
package hadoop.abi;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.IntWritable;
import java.io.IOException;
public class abiMaper extends Mapper<LongWritable, Text, Text, IntWritable> {
@Override
protected void map(LongWritable pKey, Text linea, Context contexto) throws IOException, InterruptedException {
String palabras = linea.toString();
for (String palabra: palabras.split("\\W+")) {
contexto.write(new Text(palabra.substring(0, 1)), new IntWritable(palabra.length()));
}
}
}
Lo he probado tanto en entorno eclipse en Windows como en la maquina virtual cloudera teniendo en ambos casos el mismo problema. No se si estoy importando algo mal o tengo alguna referencia errónea.
Saludos,
Antonio Baena
Redes sociales