今回は、リファクタリングの予定を変更して予定の確認と振り返りをしたいと思います。
今後のロードマップです。
- Mapper作成(リファクタリング)
- Mapper作成(テスト追加)
- Mapper作成(レッド→グリーン→リファクタリング)
- Driverのテスト(スタンドアローンモードについて)
- Driverのテスト(テスト実行)
- まとめ
少しコーヒーブレーク。今までを振り返りたいと思います。
INFOというログをログファイルから抽出するプログラムをMap(/Reduce)で作成しようとしています。
まず、実装より先にテストを作りました。
テストの内容は、「context.write();メソッドがある引数で1度だけ呼ばれればOK」というものでした。
次に実際のMapperクラスにコーディングしました。(リテラル値のハードコーディングですが)
そうしてようやくテストがOKになりました。
では、そもそも何でこのテストになったのでしょうか?
Map/Reduceを作成する上でネックとなるのは、「デバッグがしにくい」という点が挙げられます。
- データが大量であるため、デバッグログを吐いてもどれがどのログかわかりづらい
- 分散環境で実行するので、デバッグログを吐いてもどれがどのログかわかりづらい
- HadoopをWindows環境で動かしにくい
ちょっと反省として、
「"INFO"というログを抽出する」という仕様と、今回のテスト仕様がどう繋がるのかわかりづらいかな、というのがあります。
まず、テストデータとして
String[] lines = {を用意しています。これには"INFO"が含まれているので、これをMapperのmap処理に渡せば抽出対象としてcontext.writeを呼び出してくれるはずです。
"2009-12-14 00:00:26,340 INFO hogehoge @ abcdefg hijklmn opqrstu"
};
ということで、
verify(context, new Times(1)).write(new Text(lines[0]), new LongWritable(1));をテストコードとして記述しました。
Mapperの入力はKEY=LongWritable, VALUE=Text、出力は
この辺りの仕様をどうするかは、設計者に委ねられています。UnitTestはあくまで「プログラム仕様を満たしているかどうかをテストする」もので、業務仕様を満たしているかのテストではないのです。そこは、結合テストを実施して出力結果を検討し、業務仕様を満たしている結果になっているか確認する必要があります。(その前にUnitTestのレビューを行い、業務仕様に沿ったプログラム仕様でUnitTestが作られているかを確認するのがよいでしょう)
閑話休題。
次のリファクタリングでは、グリーンのままでどのようにリファクタリングをやっていくか、を説明したいと思います。明日時間があれば・・・。
あかん、今日書くのは無理だわ・・・
返信削除明日以降に時間が取れれば・・・
お詫び:
返信削除keyに行番号では、複数datanodeでの実行時に重複が発生してしまう事に気がつきました。お詫びして訂正いたします。