对Mapreduce代码进行单元测试

hadoop自带一个wordcount的示例代码,用于计算单词个数。我将其单独移出来,测试成功。源码如下:


package org.apache.hadoop.examples;

import java.io.IOException;

import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.Path;

import org.apache.hadoop.io.IntWritable;

import org.apache.hadoop.io.Text;

import org.apache.hadoop.mapreduce.Job;

import org.apache.hadoop.mapreduce.Mapper;

import org.apache.hadoop.mapreduce.Reducer;

import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;

import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import org.apache.hadoop.util.GenericOptionsParser;

public class WordCount {

public static class TokenizerMapper

extends Mapper{

private final static IntWritable one = new IntWritable(1);

private Text word = new Text();

public void map(Object key, Text value, Context context

) throws IOException, InterruptedException {

StringTokenizer itr = new StringTokenizer(value.toString());

while (itr.hasMoreTokens()) {

word  = new Text(itr.nextToken()); //to unitest,should be new Text word.set(itr.nextToken())

context.write(word, new IntWritable(1));

}

}

}

public static class IntSumReducer

extends Reducer {

private IntWritable result = new IntWritable();

public void reduce(Text key, Iterable values,

Context context

) throws IOException, InterruptedException {

int sum = 0;

for (IntWritable val : values) {

sum += val.get();

}

result.set(sum);

context.write(key, result);

}

}

public static void main(String[] args) throws Exception {

Configuration conf = new Configuration();

String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();

if (otherArgs.length != 2) {

System.err.println("Usage: wordcount  ");

System.exit(2);

}

Job job = new Job(conf, "word count");

job.setJarByClass(WordCount.class);

job.setMapperClass(TokenizerMapper.class);

job.setCombinerClass(IntSumReducer.class);

job.setReducerClass(IntSumReducer.class);

job.setOutputKeyClass(Text.class);

job.setOutputValueClass(IntWritable.class);

FileInputFormat.addInputPath(job, new Path(otherArgs[0]));

FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));

System.exit(job.waitForCompletion(true) ? 0 : 1);

}

}

 现在我想对其进行单元测试。一种方式,是job执行完了后,读取输出目录中的文件,确认计数是否正确。但这样的情况如果失败,也不知道是哪里失败。我们需要对map和reduce单独进行测试。

  tomwhite的书《hadoop权威指南》有提到如何用Mockito进行单元测试,我们依照原书对温度的单元测试来对wordcount进行单元测试。(原书第二版的示例已经过时,可以参考英文版第三版或我的程序)。


package org.apache.hadoop.examples;

/* author zhouhh

* date:2012.8.7

*/

import static org.mockito.Mockito.*;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

import org.apache.hadoop.io.*;

import org.junit.*;

public class WordCountTest {

@Test

public  void testWordCountMap() throws IOException, InterruptedException

{

WordCount w = new WordCount();

WordCount.TokenizerMapper mapper = new WordCount.TokenizerMapper();

Text value = new Text("a b c b a a");

@SuppressWarnings("unchecked")

WordCount.TokenizerMapper.Context context = mock(WordCount.TokenizerMapper.Context.class);

mapper.map(null, value, context);

verify(context,times(3)).write(new Text("a"), new IntWritable(1));

verify(context).write(new Text("c"), new IntWritable(1));

//verify(context).write(new Text("cc"), new IntWritable(1));

}

@Test

public void testWordCountReduce() throws IOException, InterruptedException

{

WordCount.IntSumReducer reducer = new WordCount.IntSumReducer();

WordCount.IntSumReducer.Context context = mock(WordCount.IntSumReducer.Context.class);

Text key = new Text("a");

List values = new ArrayList();

values.add(new IntWritable(1));

values.add(new IntWritable(1));

reducer.reduce(key, values, context);

verify(context).write(new Text("a"), new IntWritable(2));

}

public static void main(String[] args) {

// try {

// WordCountTest t = new WordCountTest();

//

// //t.testWordCountMap();

// t.testWordCountReduce();

// } catch (IOException e) {

// // TODO Auto-generated catch block

// e.printStackTrace();

// } catch (InterruptedException e) {

// // TODO Auto-generated catch block

// e.printStackTrace();

// }

}

}

  verify(context)只检查一次的写,如果多次写,需用verify(contex,times(n))检查,否则会失败。

  执行时在测试文件上点run as JUnit Test,会得到测试结果是否通过。

  本示例程序在hadoop1.0.3环境中测试通过。Mockito也在hadoop的lib中自带,打包在mockito-all-1.8.5.jar

最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2024-09-02 12:43:01

对Mapreduce代码进行单元测试的相关文章

使用MRUnit,Mockito和PowerMock进行Hadoop MapReduce作业的单元测试

引言 Hadoop MapReduce作业有着独一无二的代码架构,这种代码架构拥有特定的模板和结构.这样 的架构会给测试驱动开发和单元测试带来一些麻烦.这篇文章是运用MRUnit,Mockito和PowerMock的真实范例 .我会介绍 使用MRUnit来编写Hadoop MapReduce应用程序的JUnit测试 使用PowerMock和Mockito模拟静态方法 模拟其他类型中的业务逻辑(译注:也就是编写测试驱动模块) 查看模拟的业务逻辑是否被调用(译注:测试驱动模块是否运行正常) 计数器

代码-java单元测试时jar读取项目中properties

问题描述 java单元测试时jar读取项目中properties 我的项目中引用同事的jar,这个jar中读取了我项目中的properties,我的properties里的value是从pom中获取的,这时问题出现了 jar只能读取properties中pom还没有注入时的value,也就是${value}形式.但我项目中自身的获取properties的代码可以成功获取pom注入后的value.这是什么问题?两个现象的区别就是一个是从jar中获取,一个是本地程序获取. 解决方案 肯定是jar中读

无接口.NET代码的单元测试

最近工作上的活就是研究一下如何为一个历史代码工程添加单元测试,已经做完了,就想抛砖引玉和大家分享一下结果,听听大家的反馈. 该工程目前还是VS2010下的C#代码,虽然大量使用了继承,封装和多态,但对接口的应用非常少,所以基本上没办法用常见的Mock框架(如Moq, Rhino Mock,等)来写单元测试. 考虑下来,解决方案无非两种:一是重构现有代码,通过接口(interface)来实现依赖注入(Dependency Injection, DI);二是寻找无需通过接口直接支持虚拟实体类的Moc

使用 JUnit 进行 Java 代码的单元测试

下载安装 JUnit 的相关文件 首先我们需要先下载相应的 JUnit 相关的 JAR 包,下载的过程可以去 JUnit 的官方网站,也可以直接通过 Maven 资源仓库来完成,我这里直接通过开源中国社区在国内的Maven 镜像下载了 JUnit-4.8.2.jar 的版本,如下图所示: 直接搜索关键字"junit"即可,我们可以从搜索结果中找到红色方框1中的对应项,选中之后就会在左下方列出目前可以获得的 junit  的所有版本,这里我选择了 4.8.2 的版本(红色方框2),然后点

求大神指导一段代码的单元测试如何写

问题描述 Pathdst_path=newPath(photoPath);try{FileSystemhdfs=dst_path.getFileSystem(conf);if(hdfs.exists(dst_path)){hdfs.delete(dst_path,true);}}catch(IOExceptione){LOG.error(e.getMessage(),e);}对HDFS上的文件进行删除,向这段代码进行mockito,不知道怎么下手,求哪位大神可以指导下

使用Qunit对js代码进行单元测试

1.创建qunit.html 文件添加由官方提供的cdn 加载测试框架 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>QUnit Example</title> <link rel="stylesheet" href="//code.jquery.com/qunit/qunit-1.15.0.css&quo

利用单元测试在每个层上对PHP代码进行检查

测试驱动的开发和单元测试是确保代码在经过修改和重大调整之后依然能如我们期望的一样工作的最新方法.在本文中,您将学习到如何在模块.数据库和用户界面(UI)层对自己的 PHP 代码进行单元测试. 现在是凌晨 3 点.我们怎样才能知道自己的代码依然在工作呢? Web 应用程序是 24x7 不间断运行的,因此我的程序是否还在运行这个问题会在晚上一直困扰我.单元测试已经帮我对自己的代码建立了足够的信心 -- 这样我就可以安稳地睡个好觉了. 单元测试 是一个为代码编写测试用例并自动运行这些测试的框架.测试驱

《Python高性能编程》——2.13 在优化期间进行单元测试保持代码的正确性

2.13 在优化期间进行单元测试保持代码的正确性 如果你不对你的代码进行单元测试,那么从长远来看你可能正在损害你的生产力.Ian(脸红)十分尴尬地提到有一次他花了一整天的时间优化他的代码,因为嫌麻烦所以他禁用了单元测试,最后却发现那个显著的速度提升只是因为他破坏了需要优化的那段算法.这样的错误你一次都不要犯. 除了单元测试,你还应该坚定地考虑使用coverage.py.它会检查有哪些代码行被你的测试所覆盖并找出那些没有被覆盖的代码.这可以让你迅速知道你是否测试了你想要优化的代码,那么在优化过程中

Hadoop专业解决方案-第5章 开发可靠的MapReduce应用

本章主要内容: 1.利用MRUnit创建MapReduce的单元测试. 2.MapReduce应用的本地实例. 3.理解MapReduce的调试. 4.利用MapReduce防御式程序设计. 在WOX.COM下载本章源代码 本章在wox.com网站的源码可以在www.wiley.com/go/prohadoopsolutions的源码下载标签找到.第五章的源码根据本章的内容各自分别命名放在了第五章下载目录中. 到目前为止,你应该对MapReduce体系结构,应用程序设计,和定制MapReduce