分类:hadoop| 发布时间:2018-04-23 20:28:00
在上一篇文章 MRUnit 入门 中我们介绍了如何使用 MRUnit 编写以及运行 MapReduce 的测试用例。
通过使用 maven 进行项目的构建以及管理显得很方便,我们只需要写好代码然后使用 mvn test 命令即可运行测试。 由于很好奇 mvn test 究竟做了什么以及是否能不使用 mvn 而直接通过 java 命令运行 mrunit 的测试用例, 我做了一些测试以及探索并将相应的过程和结果记录为本文。
本文的目标主要是如何只通过 java 运行 mrunit 用例。
由于 mrunit 需要依赖大量的外部库,在搞懂如何运行 mrunit 之前,先从如何直接运行 junit 单元测试是一个很好的着手点。
假设我们有如下代码需要测试:
// Calculator.javaa
public class Calculator {
public int evaluate(String expression) {
int sum = 0;
for (String summand: expression.split("\\+"))
sum += Integer.valueOf(summand);
return sum;
}
}
测试代码如下:
// Calculator.javaa
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class CalculatorTest {
@Test
public void evaluatesExpression() {
Calculator calculator = new Calculator();
int sum = calculator.evaluate("1+2+3");
assertEquals(6, sum);
}
}
要运行 junit 需要下载相关的 jar,在 https://github.com/junit-team/junit4/wiki/Download-and-Install 这里下载 junit 和 hamcrest-core.jar。 本文假设你将其下载到了当前用户的 home 目录,你可以需要根据实际更改下面的命令:
首先先编译相关的代码和测试代码(注意需要使用全路径):
% javac javac CalculatorTest.java
% javac -cp .:/home/ubuntu/junit.jar:/home/ubuntu/hamcrest-core-1.3.jar CalculatorTest.java
使用如下命令即可运行单元测试:
% java -cp .:/home/ubuntu/junit.jar:/home/ubuntu/hamcrest-core-1.3.jar org.junit.runner.JUnitCore CalculatorTest
JUnit version 4.12
.
Time: 0.004
OK (1 test)
可以看到单元测试成功运行了。
理论上来说直接运行 mrunit 和 junit 是一样的。不同的是要编译以及运行 mrunit 需要依赖的库要比上面简单的 junit 测试用例要复杂得多。
我最终放弃了一个一个地分析其中的依赖树并手动将其下载到本地,转而分析 mvn test 命令的输出得到其完整的以来列表。
以上一篇文章的代码为例,在上一篇文章的代码目录执行以下命令:
% mvn test -X >debug.log 2>&1
通过查看 debug.log 发现其完整依赖列表为:
classpathElements = [
/home/ubuntu/src/wordcount-mrunit/target/test-classes,
/home/ubuntu/src/wordcount-mrunit/target/classes,
/home/ubuntu/.m2/repository/org/apache/hadoop/hadoop-core/1.0.3/hadoop-core-1.0.3.jar,
/home/ubuntu/.m2/repository/commons-cli/commons-cli/1.2/commons-cli-1.2.jar,
/home/ubuntu/.m2/repository/xmlenc/xmlenc/0.52/xmlenc-0.52.jar,
/home/ubuntu/.m2/repository/commons-httpclient/commons-httpclient/3.0.1/commons-httpclient-3.0.1.jar,
/home/ubuntu/.m2/repository/commons-codec/commons-codec/1.4/commons-codec-1.4.jar,
/home/ubuntu/.m2/repository/org/apache/commons/commons-math/2.1/commons-math-2.1.jar,
/home/ubuntu/.m2/repository/commons-configuration/commons-configuration/1.6/commons-configuration-1.6.jar,
/home/ubuntu/.m2/repository/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1.jar,
/home/ubuntu/.m2/repository/commons-lang/commons-lang/2.4/commons-lang-2.4.jar,
/home/ubuntu/.m2/repository/commons-digester/commons-digester/1.8/commons-digester-1.8.jar,
/home/ubuntu/.m2/repository/commons-beanutils/commons-beanutils/1.7.0/commons-beanutils-1.7.0.jar,
/home/ubuntu/.m2/repository/commons-beanutils/commons-beanutils-core/1.8.0/commons-beanutils-core-1.8.0.jar,
/home/ubuntu/.m2/repository/commons-net/commons-net/1.4.1/commons-net-1.4.1.jar,
/home/ubuntu/.m2/repository/org/mortbay/jetty/jetty/6.1.26/jetty-6.1.26.jar,
/home/ubuntu/.m2/repository/org/mortbay/jetty/servlet-api/2.5-20081211/servlet-api-2.5-20081211.jar,
/home/ubuntu/.m2/repository/org/mortbay/jetty/jetty-util/6.1.26/jetty-util-6.1.26.jar,
/home/ubuntu/.m2/repository/tomcat/jasper-runtime/5.5.12/jasper-runtime-5.5.12.jar,
/home/ubuntu/.m2/repository/tomcat/jasper-compiler/5.5.12/jasper-compiler-5.5.12.jar,
/home/ubuntu/.m2/repository/org/mortbay/jetty/jsp-api-2.1/6.1.14/jsp-api-2.1-6.1.14.jar,
/home/ubuntu/.m2/repository/org/mortbay/jetty/servlet-api-2.5/6.1.14/servlet-api-2.5-6.1.14.jar,
/home/ubuntu/.m2/repository/org/mortbay/jetty/jsp-2.1/6.1.14/jsp-2.1-6.1.14.jar,
/home/ubuntu/.m2/repository/ant/ant/1.6.5/ant-1.6.5.jar, /home/ubuntu/.m2/repository/commons-el/commons-el/1.0/commons-el-1.0.jar,
/home/ubuntu/.m2/repository/net/java/dev/jets3t/jets3t/0.7.1/jets3t-0.7.1.jar,
/home/ubuntu/.m2/repository/net/sf/kosmosfs/kfs/0.3/kfs-0.3.jar, /home/ubuntu/.m2/repository/hsqldb/hsqldb/1.8.0.10/hsqldb-1.8.0.10.jar,
/home/ubuntu/.m2/repository/oro/oro/2.0.8/oro-2.0.8.jar,
/home/ubuntu/.m2/repository/org/eclipse/jdt/core/3.1.1/core-3.1.1.jar,
/home/ubuntu/.m2/repository/org/codehaus/jackson/jackson-mapper-asl/1.0.1/jackson-mapper-asl-1.0.1.jar,
/home/ubuntu/.m2/repository/org/codehaus/jackson/jackson-core-asl/1.0.1/jackson-core-asl-1.0.1.jar,
/home/ubuntu/.m2/repository/org/apache/mrunit/mrunit/1.1.0/mrunit-1.1.0-hadoop1.jar,
/home/ubuntu/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar,
/home/ubuntu/.m2/repository/org/mockito/mockito-core/1.9.5/mockito-core-1.9.5.jar,
/home/ubuntu/.m2/repository/org/objenesis/objenesis/1.0/objenesis-1.0.jar,
/home/ubuntu/.m2/repository/com/google/guava/guava/11.0.2/guava-11.0.2.jar,
/home/ubuntu/.m2/repository/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar,
/home/ubuntu/.m2/repository/org/powermock/powermock-core/1.5.1/powermock-core-1.5.1.jar,
/home/ubuntu/.m2/repository/org/powermock/powermock-reflect/1.5.1/powermock-reflect-1.5.1.jar,
/home/ubuntu/.m2/repository/org/javassist/javassist/3.18.0-GA/javassist-3.18.0-GA.jar,
/home/ubuntu/.m2/repository/org/powermock/powermock-api-mockito/1.5.1/powermock-api-mockito-1.5.1.jar,
/home/ubuntu/.m2/repository/org/powermock/powermock-api-support/1.5.1/powermock-api-support-1.5.1.jar,
/home/ubuntu/.m2/repository/org/powermock/powermock-module-junit4/1.5.1/powermock-module-junit4-1.5.1.jar,
/home/ubuntu/.m2/repository/org/powermock/powermock-module-junit4-common/1.5.1/powermock-module-junit4-common-1.5.1.jar,
/home/ubuntu/.m2/repository/junit/junit/4.10/junit-4.10.jar,
/home/ubuntu/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar,
/home/ubuntu/.m2/repository/org/hamcrest/hamcrest-all/1.3/hamcrest-all-1.3.jar]
有了上述信息我们就可以手动编译以及执行 wordcount-mrunit 了。
在这里我只演示如何运行 WordCountMapperTest.java,其他的测试用例类似。
% cd src/main/java
% javac -cp /home/ubuntu/.m2/repository/org/apache/hadoop/hadoop-core/1.0.3/hadoop-core-1.0.3.jar WordCountMapper.java
% javac -cp /home/ubuntu/src/wordcount-mrunit/src/main/java/:\
/home/ubuntu/.m2/repository/org/apache/hadoop/hadoop-core/1.0.3/hadoop-core-1.0.3.jar:\
/home/ubuntu/.m2/repository/org/apache/mrunit/mrunit/1.1.0/mrunit-1.1.0-hadoop1.jar:\
/home/ubuntu/.m2/repository/junit/junit/4.10/junit-4.10.jar WordCountMapperTest.java
% java -cp /home/ubuntu/src/wordcount-mrunit/src/main/java/:\
/home/ubuntu/src/wordcount-mrunit/src/test/java/:\
/home/ubuntu/.m2/repository/org/apache/hadoop/hadoop-core/1.0.3/hadoop-core-1.0.3.jar:\
/home/ubuntu/.m2/repository/commons-cli/commons-cli/1.2/commons-cli-1.2.jar:\
/home/ubuntu/.m2/repository/xmlenc/xmlenc/0.52/xmlenc-0.52.jar:\
/home/ubuntu/.m2/repository/commons-httpclient/commons-httpclient/3.0.1/commons-httpclient-3.0.1.jar:\
/home/ubuntu/.m2/repository/commons-codec/commons-codec/1.4/commons-codec-1.4.jar:\
/home/ubuntu/.m2/repository/org/apache/commons/commons-math/2.1/commons-math-2.1.jar:\
/home/ubuntu/.m2/repository/commons-configuration/commons-configuration/1.6/commons-configuration-1.6.jar:\
/home/ubuntu/.m2/repository/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1.jar:\
/home/ubuntu/.m2/repository/commons-lang/commons-lang/2.4/commons-lang-2.4.jar:\
/home/ubuntu/.m2/repository/commons-digester/commons-digester/1.8/commons-digester-1.8.jar:\
/home/ubuntu/.m2/repository/commons-beanutils/commons-beanutils/1.7.0/commons-beanutils-1.7.0.jar:\
/home/ubuntu/.m2/repository/commons-beanutils/commons-beanutils-core/1.8.0/commons-beanutils-core-1.8.0.jar:\
/home/ubuntu/.m2/repository/commons-net/commons-net/1.4.1/commons-net-1.4.1.jar:\
/home/ubuntu/.m2/repository/org/mortbay/jetty/jetty/6.1.26/jetty-6.1.26.jar:\
/home/ubuntu/.m2/repository/org/mortbay/jetty/servlet-api/2.5-20081211/servlet-api-2.5-20081211.jar:\
/home/ubuntu/.m2/repository/org/mortbay/jetty/jetty-util/6.1.26/jetty-util-6.1.26.jar:\
/home/ubuntu/.m2/repository/tomcat/jasper-runtime/5.5.12/jasper-runtime-5.5.12.jar:\
/home/ubuntu/.m2/repository/tomcat/jasper-compiler/5.5.12/jasper-compiler-5.5.12.jar:\
/home/ubuntu/.m2/repository/org/mortbay/jetty/jsp-api-2.1/6.1.14/jsp-api-2.1-6.1.14.jar:\
/home/ubuntu/.m2/repository/org/mortbay/jetty/servlet-api-2.5/6.1.14/servlet-api-2.5-6.1.14.jar:\
/home/ubuntu/.m2/repository/org/mortbay/jetty/jsp-2.1/6.1.14/jsp-2.1-6.1.14.jar:\
/home/ubuntu/.m2/repository/ant/ant/1.6.5/ant-1.6.5.jar:\
/home/ubuntu/.m2/repository/commons-el/commons-el/1.0/commons-el-1.0.jar:\
/home/ubuntu/.m2/repository/net/java/dev/jets3t/jets3t/0.7.1/jets3t-0.7.1.jar:\
/home/ubuntu/.m2/repository/net/sf/kosmosfs/kfs/0.3/kfs-0.3.jar:\
/home/ubuntu/.m2/repository/hsqldb/hsqldb/1.8.0.10/hsqldb-1.8.0.10.jar:\
/home/ubuntu/.m2/repository/oro/oro/2.0.8/oro-2.0.8.jar:\
/home/ubuntu/.m2/repository/org/eclipse/jdt/core/3.1.1/core-3.1.1.jar:\
/home/ubuntu/.m2/repository/org/codehaus/jackson/jackson-mapper-asl/1.0.1/jackson-mapper-asl-1.0.1.jar:\
/home/ubuntu/.m2/repository/org/codehaus/jackson/jackson-core-asl/1.0.1/jackson-core-asl-1.0.1.jar:\
/home/ubuntu/.m2/repository/org/apache/mrunit/mrunit/1.1.0/mrunit-1.1.0-hadoop1.jar:\
/home/ubuntu/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar:\
/home/ubuntu/.m2/repository/org/mockito/mockito-core/1.9.5/mockito-core-1.9.5.jar:\
/home/ubuntu/.m2/repository/org/objenesis/objenesis/1.0/objenesis-1.0.jar:\
/home/ubuntu/.m2/repository/com/google/guava/guava/11.0.2/guava-11.0.2.jar:\
/home/ubuntu/.m2/repository/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar:\
/home/ubuntu/.m2/repository/org/powermock/powermock-core/1.5.1/powermock-core-1.5.1.jar:\
/home/ubuntu/.m2/repository/org/powermock/powermock-reflect/1.5.1/powermock-reflect-1.5.1.jar:\
/home/ubuntu/.m2/repository/org/javassist/javassist/3.18.0-GA/javassist-3.18.0-GA.jar:\
/home/ubuntu/.m2/repository/org/powermock/powermock-api-mockito/1.5.1/powermock-api-mockito-1.5.1.jar:\
/home/ubuntu/.m2/repository/org/powermock/powermock-api-support/1.5.1/powermock-api-support-1.5.1.jar:\
/home/ubuntu/.m2/repository/org/powermock/powermock-module-junit4/1.5.1/powermock-module-junit4-1.5.1.jar:\
/home/ubuntu/.m2/repository/org/powermock/powermock-module-junit4-common/1.5.1/powermock-module-junit4-common-1.5.1.jar:\
/home/ubuntu/.m2/repository/junit/junit/4.10/junit-4.10.jar:\
/home/ubuntu/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar:\
/home/ubuntu/.m2/repository/org/hamcrest/hamcrest-all/1.3/hamcrest-all-1.3.jar org.junit.runner.JUnitCore WordCountMapperTest
JUnit version 4.10
..
Time: 0.273
OK (2 tests)
可以看出如此简单的一个 mrunit 用例都要依赖如此多的库,如果真要手动处理好所有的库版本以及其依赖将是无法想象的。 这不仅会使得构建变得低效而且容易出错。