在HADOOP中使用MRUNIT進行單元測試
前提
1. 瞭解JUnit4.x的使用。2. 瞭解Mock的概念在單元測試中的應用。
3. 瞭解Hadoop中MapReduce的程式設計模型。
如果您對Hadoop中MapReduce的程式設計模型不瞭解,可以先閱讀Map/Reduce Tutorial。
介紹
MRUnit是一款由Couldera公司開發的專門針對Hadoop中編寫MapReduce單元測試的框架。
它可以用於0.18.x版本中的經典org.apache.hadoop.mapred.*的模型,也能在0.20.x版本org.apache.hadoop.mapreduce.*的新模型中使用。
官方的介紹如下:
MRUnit is a unit test library designed to facilitate easy integration between your MapReduce development process and standard development and testing tools such as JUnit. MRUnit contains mock objects that behave like classes you interact with during MapReduce execution (e.g., InputSplit and OutputCollector) as well as test harness "drivers" that test your program's correctness while maintaining compliance with the MapReduce semantics. Mapper and Reducer implementations can be tested individually, as well as together to form a full MapReduce job.
安裝
在目前Hadoop的發行版中,並沒有預設包含MRUnit。你需要去Couldera公司的官網中去下載一個由他們再次發行的版本。
下載這個檔案後,你將在hadoop-0.20.1+133\contrib\mrunit目錄中找到我們需要的jar包:hadoop-0.20.1+133-mrunit.jar。
為了使用MRUnit,我們需要將hadoop-0.20.1+133-mrunit.jar和Junit4.x使用的jar包:junit.jar都新增到我們開發Hadoop程式專案的classpath中。
示例
程式碼是最好的文件,我們先看一個簡單的map單元測試示例,程式碼如下:
package gpcuster.cnblogs.com;
import junit.framework.TestCase;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.lib.IdentityMapper;
import org.junit.Before;
import org.junit.Test;
import org.apache.hadoop.mrunit.MapDriver;
publicclass TestExample extends TestCase {
private Mapper<Text, Text, Text, Text> mapper;
private MapDriver<Text, Text, Text, Text> driver;
@Before
public void setUp() {
mapper = new IdentityMapper<Text, Text>();
driver = new MapDriver<Text, Text, Text, Text>(mapper);
}
@Test
publicvoid testIdentityMapper() {
driver.withInput(new Text("foo"), new Text("bar"))
.withOutput(new Text("foo"), new Text("bar"))
.runTest();
}
}
在這段示例程式碼中,我們使用的map是org.apache.hadoop.mapred.lib.IdentityMapper。這是一個非常簡單的map函式:輸入什麼,就輸出什麼。
org.apache.hadoop.mrunit.MapDriver是我們從MRUnit框架中匯入的一個專門用於測試map的類。
我們通過withInput指定輸入的引數,通過withOutput指定我們期望的輸出,然後通過runTest執行我們的測試。
功能
1. 測試Map,我們可以使用MapDriver。2. 測試Reduce,我們可以使用ReduceDriver。
3. 測試一個完整的MapReduce,我們可以使用MapReduceDriver。
4. 測試多個MapReduce組合而成的操作,我們可以使用PipelineMapReduceDriver。
實現
MRUnit框架非常精簡,其核心的單元測試依賴於JUnit。
由於我們編寫的MapReduce函式中包含有一個OutputCollector的物件,所以MRUnit自己實現了一套Mock物件來控制OutputCollector的操作。
侷限
通過閱讀MRUnit的原始碼我們會發現:
1. 不支援MapReduce框架中的分割槽和排序操作:從Map輸出的值經過shuffle處理後直接就匯入Reduce中了。2. 不支援Streaming實現的MapReduce操作。
雖然MRUnit有這些侷限,但是足以完成大多數的需求。