对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/
相关文章
|
2月前
|
测试技术 开发者 Python
Python单元测试入门:3个核心断言方法,帮你快速定位代码bug
本文介绍Python单元测试基础,详解`unittest`框架中的三大核心断言方法:`assertEqual`验证值相等,`assertTrue`和`assertFalse`判断条件真假。通过实例演示其用法,帮助开发者自动化检测代码逻辑,提升测试效率与可靠性。
308 1
|
3月前
|
算法 IDE Java
Java 项目实战之实际代码实现与测试调试全过程详解
本文详细讲解了Java项目的实战开发流程,涵盖项目创建、代码实现(如计算器与汉诺塔问题)、单元测试(使用JUnit)及调试技巧(如断点调试与异常排查),帮助开发者掌握从编码到测试调试的完整技能,提升Java开发实战能力。
415 0
|
1月前
|
安全 Java 测试技术
《深入理解Spring》单元测试——高质量代码的守护神
Spring测试框架提供全面的单元与集成测试支持,通过`@SpringBootTest`、`@WebMvcTest`等注解实现分层测试,结合Mockito、Testcontainers和Jacoco,保障代码质量,提升开发效率与系统稳定性。
|
2月前
|
人工智能 边缘计算 搜索推荐
AI产品测试学习路径全解析:从业务场景到代码实践
本文深入解析AI测试的核心技能与学习路径,涵盖业务理解、模型指标计算与性能测试三大阶段,助力掌握分类、推荐系统、计算机视觉等多场景测试方法,提升AI产品质量保障能力。
|
4月前
|
安全 Java 测试技术
Java 项目实战中现代技术栈下代码实现与测试调试的完整流程
本文介绍基于Java 17和Spring技术栈的现代化项目开发实践。项目采用Gradle构建工具,实现模块化DDD分层架构,结合Spring WebFlux开发响应式API,并应用Record、Sealed Class等新特性。测试策略涵盖JUnit单元测试和Testcontainers集成测试,通过JFR和OpenTelemetry实现性能监控。部署阶段采用Docker容器化和Kubernetes编排,同时展示异步处理和反应式编程的性能优化。整套方案体现了现代Java开发的最佳实践,包括代码实现、测试调试
207 0
|
5月前
|
测试技术 Go 开发者
如何为 gRPC Server 编写本地测试代码
本文介绍了如何使用 Go 语言中的 gRPC 测试工具 **bufconn**,通过内存连接实现 gRPC Server 的本地测试,避免端口冲突和外部依赖。结合示例代码,讲解了初始化内存监听、自定义拨号器及编写测试用例的完整流程,并借助断言库提升测试可读性与准确性。适用于单元及集成测试,助力高效开发。
105 1
|
7月前
|
存储 jenkins 测试技术
Apipost自动化测试:零代码!3步搞定!
传统手动测试耗时低效且易遗漏,全球Top 10科技公司中90%已转向自动化测试。Apipost无需代码,三步实现全流程自动化测试,支持小白快速上手。功能涵盖接口测试、性能压测与数据驱动,并提供动态数据提取、CICD集成等优势,助力高效测试全场景覆盖。通过拖拽编排、一键CLI生成,无缝对接Jenkins、GitHub Actions,提升测试效率与准确性。
581 11
|
7月前
|
人工智能 自然语言处理 测试技术
自然语言生成代码一键搞定!Codex CLI:OpenAI开源终端AI编程助手,代码重构+测试全自动
Codex CLI是OpenAI推出的轻量级AI编程智能体,基于自然语言指令帮助开发者高效生成代码、执行文件操作和进行版本控制,支持代码生成、重构、测试及数据库迁移等功能。
1436 0
自然语言生成代码一键搞定!Codex CLI:OpenAI开源终端AI编程助手,代码重构+测试全自动
|
9月前
|
人工智能 自然语言处理 测试技术
Potpie.ai:比Copilot更狠!这个AI直接接管项目代码,自动Debug+测试+开发全搞定
Potpie.ai 是一个基于 AI 技术的开源平台,能够为代码库创建定制化的工程代理,自动化代码分析、测试和开发任务。
778 19
Potpie.ai:比Copilot更狠!这个AI直接接管项目代码,自动Debug+测试+开发全搞定

热门文章

最新文章