6.3 MRUnit写Mapper和Reduce的单元测试
1.1 MRUnit写单元测试
作用:一旦MapReduce项目提交到集群之后,若是出现问题是很难定位和修改的,只能通过打印日志的方式进行筛选。又如果数据和项目较大时,修改起来则更加麻烦。所以,在将MapReduce项目提交到集群上之前,我们需要先对其进行单元测试。单元测试需要用到mrunit库,这个库中包含MapDriver、ReduceDriver、MapReduceDriver,可以通过三个类,输入简单的数据进行测试map和reduce的逻辑是否正确。
1.1.1 Mapper单元测试
(1)包含测试驱动库mrunit
在pom.xml文件中加入mrunit的依赖,保存会自动下载mrunit库。
<dependency>
<groupId>org.apache.mrunit</groupId>
<artifactId>mrunit</artifactId>
<version>1.1.0</version>
<!--<scope>test</scope>-->
<!--不加导包可能失败-->
<classifier>hadoop2</classifier>
</dependency>
(2)TemperatureMapper类
package Temperature; import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
//import org.apache.hadoop.mapred.MapReduceBase;
//import org.apache.hadoop.mapred.Mapper;
//import org.apache.hadoop.mapred.OutputCollector;
//import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.MapReduceBase;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reporter;
//import org.apache.hadoop.mapreduce.Mapper; import java.io.IOException; //public class TemperatureMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
public class TemperatureMapper extends MapReduceBase implements Mapper<LongWritable, Text, Text, IntWritable> { private static final int MISSING=9999;
public void map(LongWritable longWritable, Text text, OutputCollector<Text, IntWritable> outputCollector, Reporter reporter) throws IOException {
String line=text.toString();
String year=line.substring(15,19);
int airTemperture=MISSING;
if(line.charAt(87)=='+'){
airTemperture=Integer.parseInt(line.substring(88,92));
}else{
airTemperture=Integer.parseInt(line.substring(87,92));
}
String quality=line.substring(92,93);
if(airTemperture!=MISSING&&quality.matches("[01459]")){
outputCollector.collect(new Text(year),new IntWritable(airTemperture));
}
}
}
(3)maper测试类
package Temperature; import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mrunit.MapDriver;
import org.junit.Test; import java.io.IOException; public class TemperatureMapperTest { @Test//注解表示为测试类
public void TestMapper() throws IOException,InterruptedException{
Text value=new Text("0057332130999991950010103004+51317+028783FM-12+017199999V0203201N00721004501CN0100001N9-01281-01391102681");//一行测试数据
new MapDriver<LongWritable, Text, Text, IntWritable>()
.withMapper(new TemperatureMapper())//传入要测试mapper
.withInput(new LongWritable(0), value)//输入值
.withOutput(new Text("1950"), new IntWritable(-128))//验证输出值是否这个,不是则测试出错
.runTest();//开始测试
}
}
(4)执行测试
右键TemperatureMapperTest.java,单击选项run TemperatureMapperTest。如果没有run选项,需要单击文件夹,点击Create run configuration按钮,创建run测试。再次右击TemperatureMapperTest.java就会出现run按钮。

单击run按钮就会运行测试程序,成功会显示tests passed

如果将-128改为-118,在运行测试,就会出现test failed

java.lang.AssertionError: 1 Error(s): (Missing expected output (1950, -118) at position 0, got (1950, -128).)
(5)新旧mapper
新旧Mapper和测试类型import要匹配,否则会出现错误。
旧的mapper
import org.apache.hadoop.mapred.Mapper;
public class TemperatureMapper extends MapReduceBase implements Mapper<LongWritable, Text, Text, IntWritable> {
旧的测试Driver
import org.apache.hadoop.mrunit.MapDriver;
新的mapper
import org.apache.hadoop.mapreduce.Mapper;
public class TemperatureMapperNew extends Mapper<LongWritable, Text, Text, IntWritable> {
新的测试Driver
import org.apache.hadoop.mrunit.mapreduce.MapDriver;
(6)@Test的作用
@Test的使用是该方法可以不用main方法调用就可以测试出运行结果,是一种测试方法,一般函数都需要有main方法调用才能执行,注意被测试的方法必须是public修饰的。
1.1.2 Reduce单元测试
Reduce测试也需要依赖mrunit的库,
(1)reduce类
package Temperature; import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.MapReduceBase;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reducer;
import org.apache.hadoop.mapred.Reporter; import java.io.IOException;
import java.util.Iterator; public class MaxTempertureReduce extends MapReduceBase implements Reducer<Text, IntWritable,Text,IntWritable> {
public void reduce(Text text, Iterator<IntWritable> iterator, OutputCollector<Text, IntWritable> outputCollector, Reporter reporter) throws IOException {
int MaxValue = Integer.MIN_VALUE;
while (iterator.hasNext()) {
MaxValue = Math.max(MaxValue, iterator.next().get());
}
outputCollector.collect(text, new IntWritable(MaxValue));
}
}
(1)Reduce测试类
package Temperature;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mrunit.ReduceDriver;
import org.junit.Test;
import java.io.IOException;
import java.util.Arrays;
public class MaxtemperatureReduceTest {
@Test
public void ReduceTest() throws IOException{
new ReduceDriver<Text, IntWritable, Text, IntWritable>()
.withReducer(new MaxTempertureReduce())
.withInput(new Text("1950"), Arrays.asList(new IntWritable(10),new IntWritable(5)))
.withOutput(new Text("1950"),new IntWritable(10) )
.runTest();
}
}
自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取:
https://www.cnblogs.com/bclshuai/p/11380657.html
6.3 MRUnit写Mapper和Reduce的单元测试的更多相关文章
- Hadoop 2:Mapper和Reduce
		Hadoop 2:Mapper和Reduce Understanding and Practicing Hadoop Mapper and Reduce 1 Mapper过程 Hadoop将输入数据划 ... 
- SpringBoot图文教程11—从此不写mapper文件「SpringBoot集成MybatisPlus」
		有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ... 
- java 写一个 map reduce 矩阵相乘的案例
		1.写一个工具类用来生成 map reduce 实验 所需 input 文件 下面两个是原始文件 matrix1.txt 1 2 -2 0 3 3 4 -3 -2 0 2 3 5 3 -1 2 -4 ... 
- mybatis写mapper文件注意事项(转)
		原文链接:http://wksandy.iteye.com/blog/1443133 xml中某些特殊符号作为内容信息时需要做转义,否则会对文件的合法性和使用造成影响 < < > & ... 
- mybatis_mybatis写mapper文件注意事项
		xml中某些特殊符号作为内容信息时需要做转义,否则会对文件的合法性和使用造成影响 < < > > & & ' ' " " ... 
- 如何写好、管好单元测试?基于Roslyn+CI分析单元测试,严控产品提测质量
		上一篇文章中,我们谈到了通过Roslyn进行代码分析,通过自定义代码扫描规则,将有问题的代码.不符合编码规则的代码扫描出来,禁止签入,提升团队的代码质量. .NET Core技术研究-通过Roslyn ... 
- 如何写好测试用例以及go单元测试工具testify简单介绍
		背景  最近在工作和业余开源贡献中,和单元测试接触的比较频繁.但是在这两个场景之下写出来的单元测试貌似不太一样,即便是同一个代码场景,今天写出来的单元测试和昨天写的也不是很一样,我感受到了对于单元测 ... 
- Hadoop 2.x从零基础到挑战百万年薪第一季
		鉴于目前大数据Hadoop 2.x被企业广泛使用,在实际的企业项目中需要更加深入的灵活运用,并且Hadoop 2.x是大数据平台处理 的框架的基石,尤其在海量数据的存储HDFS.分布式资源管理和任务调 ... 
- java写hadoop全局排序
		前言: 一直不会用java,都是streaming的方式用C或者python写mapper或者reducer的可执行程序.但是有些情况,如全排序等等用streaming的方式往往不好处理,于是乎用原生 ... 
随机推荐
- 十二、react-reudx之@connect 摆脱redux的繁琐操作
			如果对redux的概念和用法掌握的已经不错了 那么现在react-redux会让你的操作更加的得心印手 忘记subscribe,记住reducer,action和dispatch即可 Reac ... 
- [转载]Java中继承、装饰者模式和代理模式的区别
			[转载]Java中继承.装饰者模式和代理模式的区别 这是我在学Java Web时穿插学习Java设计模式的笔记 我就不转载原文了,直接指路好了: 装饰者模式和继承的区别: https://blog.c ... 
- HotSpot JVM目录
			一.知识结构整理 jvm体系大体分四大块: 类的加载机制 jvm内存结构 GC算法 垃圾回收 GC分析 命令调优 二.运行时JVM结构组成及作用 http://www.cnblogs.com/imxi ... 
- JS基础 sessionStorage
			html5中的Web Storage包括了两种存储方式:sessionStorage和localStorage. sessionStorage用于本地存储一个会话(session)中的数据,这些数据只 ... 
- golang包管理工具
			软件开发中,不可避免的会使用到第三方库,因此包管理工具可以极大的方便开发者管理第三方依赖,避免掉入"依赖地狱". 作为google强大背书的golang语言,golang官方包管理 ... 
- Python处理异常
			异常操作: 1.错误的定义和特征 什么是错误:错误是由于逻辑和语法等导致一个程序无法正常执行的问题 错误的特征:有些错误无法预知 2.异常的定义 异常是程序错误时表示的一种状态 异常发生时,程序不会再 ... 
- PHP 二维数组排序函数的应用 array_multisort()
			<?php $arrayData = array( array("name"=>"泰山", "age"=>"23 ... 
- Task.Run 和 Task.Factory.StartNew 区别
			Task.Run 是在 dotnet framework 4.5 之后才可以使用, Task.Factory.StartNew 可以使用比 Task.Run 更多的参数,可以做到更多的定制. 可以认为 ... 
- js重写页面之后后台如何获取重写后的控件值
			需求描述:专业分流系统中,学生在选择志愿时,我想实现在页面按照点击相应专业的顺序来设置选专业的志愿,如首先点击“工商”,则工商专业为第一志愿,接着点击“营销”,则营销专业为第二志愿,以此类推.从而达到 ... 
- 7月新的开始 - Axure学习01 - 元件库、元件交互样式设置
			解释: Axure 属于原型制作里的霸道总裁 1.原型:原型模拟真实产品的功能与设计.用于在初期阶段测试产品的可行性与效果.来节省开发成本与周期. 2.线框图:在初期实现对产品的了解.实现产品的基本结 ... 
