使用MRUnit对MapReduce进行单元测试

1. 为什么需要单元测试

  一旦MapReduce项目提交到集群之后,若是出现问题是很难定位和修改的,只能通过打印日志的方式进行筛选。又如果数据和项目较大时,修改起来则更加麻烦。所以,在将MapReduce项目提交到集群上之前,我们需要先对其进行单元测试。

2. 使用什么框架进行单元测试

  MRUnit是Cloudera公司专为Hadoop MapReduce写的单元测试框架,其API非常简洁实用。该框架对不同的测试对象使用不同的Driver,因此分为了:MapDriver、ReduceDriver和MapReduceDriver。

3. 测试过程

  准备工作:将mrunit-hadoop.jar包导入Built Path。

  项目目录如下:

 

 3.1 MapDriver测试

  MapReduce的代码使用MapReduce项目之气温统计中的代码,但注意有一点变化如下

   测试函数代码如下:

package com.hadoop.test;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mrunit.mapreduce.MapDriver;
import org.junit.Before;
import org.junit.Test;

public class TemperarureMapperTest {
    
    private Mapper mapper;
    private MapDriver driver;
    
    @Before
    public void init() {   //初始化
        mapper = new Temperature.TemperatureMapper(); //通过Temperature下的Mapper方法对mapper进行初始化
        driver = new MapDriver(mapper); 
    }
    
    @Test  //使用注解添加测试方法,获得入口函数
    public void test() throws IOException {
        String line = "2005 01 01 00    22    -6 10117   210    77     6     0     0";
        driver.withInput(new LongWritable(), new Text(line))
            .withOutput(new Text("03103"), new IntWritable(22)) //"03103"代表测试文件编号;22代表输入测试数据中第五位数,代表气温值
            .runTest();
    }
}

   如上述代码所示,插入注解后即可获取到测试函数入口,右键 -> Run As -> JUnit Test运行可得到如下结果。

  3.2 ReduceDriver测试

  测试函数代码如下:

package com.hadoop.test;


import java.io.IOException;
import java.util.List;
import java.util.ArrayList;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mrunit.mapreduce.ReduceDriver;
import org.junit.Before;
import org.junit.Test;


public class TeperatureReducerTest {

    private Reducer reducer;
    private ReduceDriver driver;
    
    @Before
    public void init() {
        reducer = new Temperature.TemperatureReducer(); //通过Temperature下的Reducer方法对Reducer进行初始化
        driver = new ReduceDriver(reducer);
    }
    
    @Test  //使用注解添加测试方法,获得入口函数
    public void test() throws IOException {
        
        //因为Reduce的输入几位Map的输出,所以需要先获取Map的输出
        String key = "03103";
        List values = new ArrayList();
        values.add(new IntWritable(22));
        values.add(new IntWritable(10));
        
        driver.withInput(new Text(key), values)
              .withOutput(new Text(key), new IntWritable(16)) //输出平均气温(22+10)/2
              .runTest();
    }
    
}

  测试结果如下:

  3.3 MapReduceDriver测试

  测试函数代码如下:

package com.hadoop.test;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mrunit.mapreduce.MapReduceDriver;
import org.junit.Before;
import org.junit.Test;

public class TemperatureMapReduceTest {

    private Mapper mapper;
    private Reducer reducer;
    private MapReduceDriver driver;
    
    @Before
    public void init() {
        mapper = new Temperature.TemperatureMapper();
        reducer = new Temperature.TemperatureReducer();
        driver = new MapReduceDriver(mapper, reducer);
    }
    

    @Test  //使用注解添加测试方法,获得入口函数
    public void test() throws IOException {
        
        String line1 = "2005 01 01 00    22    -6 10117   210    77     6     0     0";
        String line2 = "2005 01 01 06     6   -17 10131   240    41     8    -1   999";
        
        driver.withInput(new LongWritable(), new Text(line1))
              .withInput(new LongWritable(), new Text(line2))
              .withOutput(new Text("03103"), new IntWritable(14)) 
              .runTest();
    }
}

  测试结果如下:

  根据以上结果可以看出,测试结果和预期结果是一致的,也就是说我们的代码是完全正确的,并且可以放心的放到集群上运行。

 

以上就是博主为大家介绍的这一板块的主要内容,这都是博主自己的学习过程,希望能给大家带来一定的指导作用,有用的还望大家点个支持,如果对你没用也望包涵,有错误烦请指出。如有期待可关注博主以第一时间获取更新哦,谢谢!

 

 版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2018-03-26 15:26  子墨言良  阅读(1760)  评论(0编辑  收藏  举报