設定
要開始使用,請從此處下載MRUnit。 解壓縮tar文件后,將cd插入mrunit-0.9.0-incubating / lib目錄。 在其中,您應該看到以下內容:
- mrunit-0.9.0-incubating-hadoop1.jar
- mrunit-0.9.0-incubating-hadoop2.jar
我敢肯定,mrunit-0.9.0-incubating-hadoop1.jar用于Hadoop的MapReduce版本1,而mrunit-0.9.0-incubating-hadoop2.jar用于處理Hadoop的新版本的MapReduce。 對于本文以及其他所有后續文章,我們將使用Cloudera CDH4.1.1發行版中的hadoop-2.0版本,因此我們需要mrunit-0.9.0-incubating-hadoop2.jar文件。 我在Intellij中將MRUnit,JUnit和Mockito添加為庫(JUnit和Mockito與MRUnit jar文件位于同一目錄中)。 現在我們已經建立了依賴關系,讓我們開始測試。
測試映射器
設置測試映射器非常簡單,最好先查看一些代碼來說明。 我們將使用上一篇文章中的映射器內合并示例:
@Test
public void testCombiningMapper() throws Exception {new MapDriver<LongWritable,Text,Text,TemperatureAveragingPair>().withMapper(new AverageTemperatureCombiningMapper()).withInput(new LongWritable(4),new Text(temps[3])).withOutput(new Text('190101'),new TemperatureAveragingPair(-61,1)).runTest();}
注意流利的api樣式,這增加了創建測試的便利性。 要編寫測試,您將:
- 實例化完全與被測映射器參數化的MapDriver類的實例。
- 在withMapper調用中添加要測試的Mapper實例。
- 在withInput調用中,輸入您的鍵和輸入值,在這種情況下,一個LongWritable具有任意值和一個Text對象,該對象包含來自NCDC天氣數據集的行,該數據集包含在名為“ temps”的字符串數組中,該數組早些時候在其中建立。測試(此處不會顯示,因為它會從演示文稿中刪除)。
- 在withOutput調用中指定期望的輸出,這里我們期望一個Text對象的值為“ 190101”,一個TemperatureAveragingPair對象的值為-61(溫度)和1(計數)。
- 最后一個調用runTest將指定的輸入值輸入到映射器中,并將實際輸出與“ withOutput”方法中設置的預期輸出進行比較。
要注意的一件事是MapDriver每次測試僅允許一個輸入和輸出。 您可以根據需要多次調用withInput和withOutput,但是MapDriver會用新值覆蓋現有值,因此您將只能在任何時候使用一個輸入/輸出進行測試。 為了指定多個輸入,我們將使用MapReduceDriver,稍后將介紹幾節,但接下來將測試reducer。
測試減速器
測試減速器遵循與映射器測試相同的模式。 再次,讓我們看一個代碼示例:
@Test
public void testReducerCold(){List<TemperatureAveragingPair> pairList = new ArrayList<TemperatureAveragingPair>();pairList.add(new TemperatureAveragingPair(-78,1));pairList.add(new TemperatureAveragingPair(-84,1));pairList.add(new TemperatureAveragingPair(-28,1));pairList.add(new TemperatureAveragingPair(-56,1));new ReduceDriver<Text,TemperatureAveragingPair,Text,IntWritable>().withReducer(new AverageTemperatureReducer()).withInput(new Text('190101'), pairList).withOutput(new Text('190101'),new IntWritable(-61)).runTest();}
- 該測試首先創建一個TemperatureAveragingPair對象列表,用作減速器的輸入。
- 實例化了ReducerDriver,并且與MapperDriver一樣,對它的參數設置也與被測試的reducer完全相同。
- 接下來,我們要在withReducer調用中傳入要測試的reducer實例。
- 在withInput調用中,我們傳入鍵“ 190101”和在測試開始時創建的pairList對象。
- 接下來,我們指定我們期望減速器發出的輸出,相同的鍵“ 190101”和一個IntWritable,它表示列表中的溫度平均值。
- 最后調用runTest,它將給我們的減速器提供指定的輸入,并將減速器的輸出與期望輸出進行比較。
ReducerDriver具有與MapperDriver相同的限制,即不接受多個輸入/輸出對。 到目前為止,我們已經單獨測試了Mapper和Reducer,但我們也想在集成測試中一起測試它們。 可以通過使用MapReduceDriver類完成集成測試。 MapReduceDriver還是用于測試組合器,自定義計數器或自定義分區程序使用情況的類。
整合測試
為了測試您的mapper和reducer一起工作,MRUnit提供了MapReduceDriver類。 正如您現在所期望的,MapReduceDriver類有兩個主要區別。 首先,參數化映射器的輸入和輸出類型以及化簡器的輸入和輸出類型。 由于映射器輸出類型需要與化簡器輸入類型匹配,因此最終需要3對參數化類型。 其次,您可以提供多個輸入并指定多個預期輸出。 這是我們的示例代碼:
@Test
public void testMapReduce(){new MapReduceDriver<LongWritable,Text,Text,TemperatureAveragingPair,Text,IntWritable>().withMapper(new AverageTemperatureMapper()).withInput(new LongWritable(1),new Text(temps[0])).withInput(new LongWritable(2),new Text(temps[1])).withInput(new LongWritable(3),new Text(temps[2])).withInput(new LongWritable(4),new Text(temps[3])).withInput(new LongWritable(5),new Text(temps[6])).withInput(new LongWritable(6),new Text(temps[7])).withInput(new LongWritable(7),new Text(temps[8])).withInput(new LongWritable(8),new Text(temps[9])).withCombiner(new AverageTemperatureCombiner()).withReducer(new AverageTemperatureReducer()).withOutput(new Text('190101'),new IntWritable(-22)).withOutput(new Text('190102'),new IntWritable(-40)).runTest();}
從上面的示例中可以看到,設置與MapDriver和ReduceDriver類相同。 您傳入了映射器,reducer和(可選)組合器的實例進行測試。 MapReduceDriver允許我們傳遞具有不同鍵的多個輸入。 此處的“溫度”數組與Mapper樣本中引用的數組相同,并包含NCDC天氣數據集中的幾行內容,這些樣本行中的關鍵字為1901年1月和2月,分別表示為“ 190101”和“ 190102“。 該測試是成功的,因此我們對映射器和化簡器一起工作的正確性有了更多的信心。
結論
希望我們已經證明了MRUnit對于測試Hadoop程序有多么有用。 我想用我自己的一些觀點來總結這篇文章。 盡管MRUnit使映射器和化簡器代碼的單元測試變得容易,但是這里介紹的映射器和化簡器示例相當簡單。 如果您的映射和/或精簡代碼開始變得更加復雜,則最好將代碼與Hadoop框架解耦,然后單獨測試新類。 另外,與MapReduceDriver類一樣,它用于集成測試也非常有用,很容易達到不再測試代碼,而已經測試Hadoop框架本身的地步。 我提出了自己打算繼續使用的測試策略:
- 單元測試映射/減少代碼。
- 可能使用MapReduceDriver類編寫一個集成測試。
- 作為健全性檢查,請在單節點安裝(在我的筆記本電腦上)上運行MapReduce作業,以確保其在Hadoop框架上運行。
- 然后在我的案例中,使用Apache Whirr在EC2的測試集群上運行我的代碼。
討論如何在筆記本電腦(OSX Lion)上設置單節點安裝以及如何使用Whirr在EC2上建立群集將使這篇文章過長,因此我將在下一篇文章中介紹這些主題。 謝謝你的時間。
資源資源
- Jimmy Lin和Chris Dyer 使用MapReduce進行的數據密集型處理
- Hadoop: Tom White 的權威指南
- 來自博客的源代碼
- Hadoop API
- MRUnit用于單元測試Apache Hadoop映射減少工作
- Gutenberg項目提供了大量純文本格式的書籍,非常適合在本地測試Hadoop作業。
參考:來自我們的JCG合作伙伴 Bill Bejeck的《 Random Thoughts On Coding》博客中的MRUnit測試Hadoop程序 。
翻譯自: https://www.javacodegeeks.com/2012/11/testing-hadoop-programs-with-mrunit.html